require('strict');
local getArgs = require ('Module:Arguments').getArgs;  
local cfg = mw.loadData ('Module:Citation/CS1/Configuration'); -- load the configuration module
local whitelist = mw.loadData ('Module:Citation/CS1/Whitelist'); -- load the whitelist module  
local exclusion_lists = { -- TODO: move these tables into a separate ~/data module and mw.loadData it
['cite book'] = {
['agency'] = true,
['air-date'] = true,
['arxiv'] = true,
['biorxiv'] = true,
['citeseerx'] = true,
['class'] = true,
['conference'] = true,
['conference-format'] = true,
['conference-url'] = true,
['degree'] = true,
['department'] = true,
['display-interviewers'] = true,
['docket'] = true,
['episode'] = true,
['interviewer#'] = true,
['interviewer-first#'] = true,
['interviewer-link#'] = true,
['interviewer-mask#'] = true,
['ismn'] = true,
['issn'] = true,
['issue'] = true,
['jfm'] = true,
['journal'] = true,
['jstor'] = true,
['mailinglist'] = true,
['message-id'] = true,
['minutes'] = true,
['MR'] = true,
['network'] = true,
['number'] = true,
['RFC'] = true,
['script-journal'] = true,
['season'] = true,
['section'] = true,
['sections'] = true,
['series-link'] = true,
['series-number'] = true,
['series-separator'] = true,
['sheet'] = true,
['sheets'] = true,
['SSRN'] = true,
['station'] = true,
['time'] = true,
['time-caption'] = true,
['trans-article'] = true,
['trans-journal'] = true,
['transcript'] = true,
['transcript-format'] = true,
['transcript-url'] = true,
['ZBL'] = true,
},
['cite journal'] = {
['agency'] = true,
['air-date'] = true,
['book-title'] = true,
['chapter'] = true,
['chapter-format'] = true,
['chapter-url'] = true,
['chapter-url-access'] = true,
['class'] = true,
['conference'] = true,
['conference-format'] = true,
['conference-url'] = true,
['contribution'] = true,
['contributor#'] = true,
['contributor-first#'] = true,
['contributor-link#'] = true,
['contributor-mask#'] = true,
['degree'] = true,
['department'] = true,
['display-interviewers'] = true,
['docket'] = true,
['edition'] = true,
['editor#'] = true,
['editor-first#'] = true,
['editor-link#'] = true,
['editor-mask#'] = true,
['editors'] = true,
['encyclopedia'] = true,
['episode'] = true,
['ignore-isbn-error'] = true,
['interviewer#'] = true,
['interviewer-first#'] = true,
['interviewer-link#'] = true,
['interviewer-mask#'] = true,
['isbn'] = true,
['ismn'] = true,
['LCCN'] = true,
['mailinglist'] = true,
['message-id'] = true,
['minutes'] = true,
['network'] = true,
['script-chapter'] = true,
['season'] = true,
['section'] = true,
['sections'] = true,
['series-link'] = true,
['series-number'] = true,
['series-separator'] = true,
['sheet'] = true,
['sheets'] = true,
['station'] = true,
['time'] = true,
['time-caption'] = true,
['trans-article'] = true,
['transcript'] = true,
['transcript-format'] = true,
['transcript-url'] = true,
},
}  
--script-<param>= lang codes always use override names so dagger is omitted  
local function add_to_list (code_list, name_list, override_list, code, name, dagger)
if false == dagger then
dagger = ''; -- no dagger for |script-<param>= codes and names
else
dagger = '<sup>†</sup>'; -- dagger for all other lists using override
end  
if override_list[code] then -- look in the override table for this code
code_list[code] = override_list[code] .. dagger; -- use the name from the override table; mark with dagger
name_list[override_list[code]] = code .. dagger;
else
code_list[code] = name; -- use the MediaWiki name and code
name_list[name] = code;
end
end  
--[[-------------------------< L I S T _ F O R M A T >---------------------------------------------------------  
formats key/value pair into a string for rendering
['k'] = 'v' → k: v  
local function list_format (result, list)
for k, v in pairs (list) do
table.insert (result, k .. ': ' .. v);
end
end  
---------------------------< L A N G _ L I S T E R >---------------------------------------------------------  
Module entry point  
Crude documentation tool that returns one of several lists of language codes and names.  
Used in Template:Citation Style documentation/language/doc  
where <selector> is one of the values:
2char – list of ISO 639-1 codes and names sorted by code
3char – list of ISO 639-2, -3 codes and names sorted by code
ietf – list of IETF language tags and names sorted by tag
ietf2 – list of ISO 639-1 based IETF language tags and names sorted by tag
ietf3 – list of list of ISO 639-2, -3 based IETF language tags and names sorted by tag
name – list of language names and codes sorted by name
all - list all language codes/tags and names sorted by code/tag  
where <code> is a MediaWiki supported 2, 3, or ietf-like language code; because of fall-back, language names may
be the English-language names.  
local function lang_lister
local lang = (.args.lang and '' ~= .args.lang) and .args.lang or mw.getContentLanguage:getCode
local source_list = mw.language.fetchLanguageNames(lang, 'all');
local override = cfg.lang_tag_remap;
local code_1_list={};
local code_2_list={};
local ietf_list={};
local ietf_list2={};
local ietf_list3={};
local name_list={};  
if not ({['2char']=true, ['3char']=true, ['ietf']=true, ['ietf2']=true, ['ietf3']=true, ['name']=true, ['all']=true})[.args.list] then
return '<span>unknown list selector: ' .. .args.list .. '</span>';
end  
for code, name in pairs (source_list) do
if 'all' == .args.list then
add_to_list (code_1_list, name_list, override, code, name); -- use the code_1_list because why not?
elseif 2 == code:len then
add_to_list (code_1_list, name_list, override, code, name);
elseif 3 == code:len then
add_to_list (code_2_list, name_list, override, code, name);
elseif code:match ('^%a%a%-.+') then -- ietf with 2-character language tag
add_to_list (ietf_list, name_list, override, code, name); -- add to main ietf list for |list=ietf
add_to_list (ietf_list2, name_list, override, code, name); -- add to ietf2 list
elseif code:match ('^%a%a%a%-.+') then -- ietf with 3-character language tag
add_to_list (ietf_list, name_list, override, code, name); -- add to main ietf list for |list=ietf
add_to_list (ietf_list3, name_list, override, code, name); -- add to ietf3 list
end
end  
local result = {};
local out = {};  
if '2char' == .args.list or 'all' == .args.list then -- iso 639-1
list_format (result, code_1_list);
elseif '3char' == .args.list then -- iso 639-2, 3
list_format (result, code_2_list);
elseif 'ietf' == .args.list then -- all ietf tags
list_format (result, ietf_list);
elseif 'ietf2' == .args.list then -- 2-character ietf tags
list_format (result, ietf_list2);
elseif 'ietf3' == .args.list then -- 3 character ietf tags
list_format (result, ietf_list3);
else --must be 'name'
list_format (result, name_list);
end  
local templatestyles = :extensionTag{
name = 'templatestyles', args = { src = "Div col/styles.css" }
}  
table.sort (result);
table.insert (result, 1, templatestyles .. '<div>');
table.insert (out, table.concat (result, '\n*'));
table.insert (out, '</div>');  
return table.concat (out, '\n');
end  
--script-<param>= parameters.  
used in Help:CS1 errors  
local function script_lang_lister
local lang_code_src = cfg.script_lang_codes ; -- get list of allowed script language codes
local override = cfg.lang_tag_remap;
local this_wiki_lang = mw.language.getContentLanguage.code; -- get this wiki's language  
local code_list = {}; -- interim list of aliases
local name_list={}; -- not used; defined here so that we can reuse add_to_list
local out = {}; -- final output (for now an unordered list)  
for _, code in ipairs (lang_code_src) do -- loop through the list of codes
local name = mw.language.fetchLanguageName (code, this_wiki_lang); -- get the language name associated with this code
add_to_list (code_list, name_list, override, code, name, false); -- name_list{} not used but provided so that we can reuse add_to_list; don't add superscript dagger
end  
local result = {};
local out = {};  
list_format (result, code_list);  
local templatestyles = :extensionTag{