Module:Cs1 documentation support: Difference between revisions
script_lang_lister: 20em for lang cols wider than necessary; wastes too much space |
Richardpruen (talk | contribs) m 1 revision imported: template update |
||
(7 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
require(' | require('strict'); | ||
local getArgs = require ('Module:Arguments').getArgs; | local getArgs = require ('Module:Arguments').getArgs; | ||
Line 172: | Line 172: | ||
2char – list of ISO 639-1 codes and names sorted by code | 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 | 3char – list of ISO 639-2, -3 codes and names sorted by code | ||
ietf – list of IETF language tags and names sorted by tag -- | ietf – list of IETF language tags and names sorted by tag | ||
name – list of language names and codes sorted by name | 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 | all - list all language codes/tags and names sorted by code/tag | ||
Line 185: | Line 187: | ||
local lang = (frame.args.lang and '' ~= frame.args.lang) and frame.args.lang or mw.getContentLanguage():getCode() | local lang = (frame.args.lang and '' ~= frame.args.lang) and frame.args.lang or mw.getContentLanguage():getCode() | ||
local source_list = mw.language.fetchLanguageNames(lang, 'all'); | local source_list = mw.language.fetchLanguageNames(lang, 'all'); | ||
local override = cfg. | local override = cfg.lang_tag_remap; | ||
local code_1_list={}; | local code_1_list={}; | ||
local code_2_list={}; | local code_2_list={}; | ||
local ietf_list={}; | local ietf_list={}; | ||
local ietf_list2={}; | |||
local ietf_list3={}; | |||
local name_list={}; | local name_list={}; | ||
if not ({['2char']=true, ['3char']=true, ['ietf']=true, ['name']=true, ['all']=true})[frame.args.list] then | if not ({['2char']=true, ['3char']=true, ['ietf']=true, ['ietf2']=true, ['ietf3']=true, ['name']=true, ['all']=true})[frame.args.list] then | ||
return '<span style=" | return '<span style="color:#d33">unknown list selector: ' .. frame.args.list .. '</span>'; | ||
end | end | ||
Line 202: | Line 206: | ||
elseif 3 == code:len() then | elseif 3 == code:len() then | ||
add_to_list (code_2_list, name_list, override, code, name); | 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 ( | 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 | ||
end | end | ||
Line 210: | Line 218: | ||
local out = {}; | local out = {}; | ||
if '2char' == frame.args.list or 'all' == frame.args.list then | if '2char' == frame.args.list or 'all' == frame.args.list then -- iso 639-1 | ||
list_format (result, code_1_list); | list_format (result, code_1_list); | ||
elseif '3char' == frame.args.list then | elseif '3char' == frame.args.list then -- iso 639-2, 3 | ||
list_format (result, code_2_list); | list_format (result, code_2_list); | ||
elseif 'ietf' == frame.args.list then | elseif 'ietf' == frame.args.list then -- all ietf tags | ||
list_format (result, ietf_list); | list_format (result, ietf_list); | ||
elseif 'ietf2' == frame.args.list then -- 2-character ietf tags | |||
list_format (result, ietf_list2); | |||
elseif 'ietf3' == frame.args.list then -- 3 character ietf tags | |||
list_format (result, ietf_list3); | |||
else --must be 'name' | else --must be 'name' | ||
list_format (result, name_list); | list_format (result, name_list); | ||
Line 247: | Line 259: | ||
local function script_lang_lister (frame) | local function script_lang_lister (frame) | ||
local lang_code_src = cfg.script_lang_codes ; -- get list of allowed script language codes | local lang_code_src = cfg.script_lang_codes ; -- get list of allowed script language codes | ||
local override = cfg. | local override = cfg.lang_tag_remap; | ||
local this_wiki_lang = mw.language.getContentLanguage().code; -- get this wiki's language | local this_wiki_lang = mw.language.getContentLanguage().code; -- get this wiki's language | ||
Line 663: | Line 675: | ||
local handlers = cfg.id_handlers; -- get id_handlers {} table from ~/Configuration | local handlers = cfg.id_handlers; -- get id_handlers {} table from ~/Configuration | ||
return args[1] and handlers[args[1]:upper()].id_limit or ('<span style=" | return args[1] and handlers[args[1]:upper()].id_limit or ('<span style="color:#d33">No limit defined for identifier: ' .. (args[1] or '<unknown name>') .. '</span>'); | ||
end | end | ||
Line 683: | Line 695: | ||
local lang_list_t = mw.language.fetchLanguageNames ('en', 'all'); | local lang_list_t = mw.language.fetchLanguageNames ('en', 'all'); | ||
local function script_cat_lister (script_lang_codes_t, | local function script_cat_lister (script_lang_codes_t, lang_tag_remap_t, cats_list_t) | ||
for _, lang_code in ipairs (script_lang_codes_t) do | for _, lang_code in ipairs (script_lang_codes_t) do | ||
local lang_name = | local lang_name = lang_tag_remap_t[lang_code] or lang_list_t[lang_code]; -- use remap table to get Bengali instead of Bangla and the like; else use standard MediaWiki names | ||
local cat = 'CS1 uses ' .. lang_name .. '-language script (' .. lang_code .. ')'; -- build a category name | local cat = 'CS1 uses ' .. lang_name .. '-language script (' .. lang_code .. ')'; -- build a category name | ||
cats_list_t[cat] = 1; -- and save it | cats_list_t[cat] = 1; -- and save it | ||
Line 766: | Line 778: | ||
end | end | ||
script_cat_lister (cfg.script_lang_codes, cfg. | script_cat_lister (cfg.script_lang_codes, cfg.lang_tag_remap, list_live_cats); -- get live module's foriegn language script cats | ||
if sandbox then -- if ~/sandbox module exists and |sandbox= not set to 'no' | if sandbox then -- if ~/sandbox module exists and |sandbox= not set to 'no' | ||
Line 774: | Line 786: | ||
end | end | ||
script_cat_lister (sb_cfg.script_lang_codes, sb_cfg. | script_cat_lister (sb_cfg.script_lang_codes, sb_cfg.lang_tag_remap, list_sbox_cats); -- get sandbox module's foriegn language script cats | ||
end | end | ||
else | else | ||
return '<span style= | return '<span style="color:#d33; font-style:normal;">error: unknown selector: ' .. select .. '</span>' | ||
end | end | ||
Line 877: | Line 889: | ||
with this: | with this: | ||
{{#invoke:Cs1 documentation support|help_text_cats|err_bad_biorxiv}} | {{#invoke:Cs1 documentation support|help_text_cats|err_bad_biorxiv}} | ||
where {{{1}}} is the error_conditions key from Module:Citation/CS1/Configuration | |||
add |pages=yes to append the number of pages in the category | add |pages=yes to append the number of pages in the category | ||
]=] | ]=] | ||
local function help_text_cats (frame) | local function help_text_cats (frame) | ||
local | local args_t = getArgs (frame); | ||
local | local error_conditions_t = cfg.error_conditions; -- get the table of error conditions | ||
local | local replacements_t = {}; -- table to hold replacement parameters for $1 etc placeholders in category names | ||
for k, v in pairs (args_t) do -- look for |$1=<replacement> parameters | |||
if | if 'string' == type (k) and k:match ('^$%d+$') then -- if found | ||
replacements_t[k] = v; -- save key and value | |||
end | |||
end | |||
if args_t[1] and error_conditions_t[args_t[1]] then -- must have error_condition key and it must exist | |||
local error_cat = error_conditions_t[args_t[1]].category; -- get error category from cs1|2 configuration | |||
if error_cat:match ('$%d') then -- look for placeholders in <error_cat> | |||
error_cat = error_cat:gsub ('$%d', replacements_t) -- replace place holders with matching value from replacements_t | |||
end | |||
table. | local title_obj = mw.title.getCurrentTitle(); -- get a title object for the currently displayed page | ||
local name_space = title_obj.nsText; | |||
if ('Category' == name_space) and (error_cat == title_obj.text) then -- if this is the category page for the error message | |||
return table.concat ({'Category:', error_cat}); -- no link; just category name | |||
else -- here when currently displayed page is other than the error message category | |||
local pages = ''; -- default empty strin for concatenation | |||
if 'yes' == args_t.pages then -- if we should display category page count: TODO: do we need to keep this? | |||
pages = mw.site.stats.pagesInCategory (error_cat, 'all'); -- get category page count | |||
pages = table.concat ({' (', mw.language.getContentLanguage():formatNum (pages), ' page', (1 == pages) and ')' or 's)'}); -- make renderable text | |||
end | |||
return table.concat ({'[[:Category:', error_cat, ']]', pages}); -- link to category with or without page count | |||
end | end | ||
else | else | ||
return '<span style=" | return '<span style="color:#d33">unknown error_conditions key: ' .. (args_t[1] or 'key missing') .. '</span>'; | ||
end | end | ||
end | end | ||
Line 915: | Line 937: | ||
{{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_issn|$1=_}} -> Check |issn= value | {{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_issn|$1=_}} -> Check |issn= value | ||
{{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_issn|$1=e}} -> Check |eissn= value | {{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_issn|$1=e}} -> Check |eissn= value | ||
error message is rendered at 120% font size; to specify another font size use |size=; must include unit specifier (%, em, etc) | |||
]] | ]] | ||
local function help_text_error_messages (frame) | local function help_text_error_messages (frame) | ||
local | local args_t = getArgs (frame); | ||
local error_conditions = mw.loadData ('Module:Citation/CS1/Configuration').error_conditions; | local error_conditions = mw.loadData ('Module:Citation/CS1/Configuration').error_conditions; | ||
-- local span_o = '<span class="cs1-visible-error citation-comment">'; | |||
local span_o = '<span class="citation-comment" style="color:#d33; font-size:' .. ((args_t.size and args_t.size) or '120%') .. '">'; | |||
local span_c = '</span>'; | local span_c = '</span>'; | ||
Line 926: | Line 952: | ||
local out = {}; -- output goes here | local out = {}; -- output goes here | ||
if | if args_t[1] and error_conditions[args_t[1]] then -- must have error_condition key and it must exist | ||
message = error_conditions[ | message = error_conditions[args_t[1]].message; | ||
local i=1; | local i=1; | ||
local count; | local count; | ||
Line 933: | Line 959: | ||
repeat | repeat | ||
rep = '$'..i | rep = '$'..i | ||
args_t[rep] = args_t[rep] and args_t[rep]:gsub ('^%s*_%s*$', '') or nil; -- replace empty string marker with actual empty string | |||
message, count = message:gsub (rep, | message, count = message:gsub (rep, args_t[rep] or rep) | ||
i = i + 1; | i = i + 1; | ||
until (0 == count); | until (0 == count); | ||
Line 942: | Line 968: | ||
table.insert (out, span_c); | table.insert (out, span_c); | ||
else | else | ||
return '<span style=" | return '<span style="color:#d33">unknown error_conditions key: ' .. (args_t[1] or 'key missing') .. '</span>'; | ||
end | end | ||
local out_str = table.concat (out); | local out_str = table.concat (out); | ||
return table.concat ({frame:extensionTag ('templatestyles', '', {src='Module:Citation/CS1/styles.css'}), out_str}); | |||
return table.concat ({ | |||
end | end | ||
Line 959: | Line 984: | ||
Each subsequence table holds: | Each subsequence table holds: | ||
[1] documentation page where the TemplateData json is stored ({{cite book}} is the oddball) | [1] documentation page where the TemplateData json is stored ({{cite book}} is the oddball) | ||
[2] key to ' | [2] key to 'preprint_arguments_t' and unique_arguments_t' tables in Module:Citation/CS1/Whitelist; these keys | ||
dictate which of the basic or limited arguments and numbered arguments tables will be used to validate | dictate which of the basic or limited arguments and numbered arguments tables will be used to validate | ||
the content of the TemplateData | the content of the TemplateData | ||
Line 971: | Line 996: | ||
citebiorxiv = {'Template:Cite bioRxiv/doc', 'biorxiv'}, -- preprint arguments | citebiorxiv = {'Template:Cite bioRxiv/doc', 'biorxiv'}, -- preprint arguments | ||
citebook = {'Template:Cite book/TemplateData'}, | citebook = {'Template:Cite book/TemplateData'}, | ||
citeciteseerx = {'Template:Cite | citeciteseerx = {'Template:Cite CiteSeerX/doc', 'citeseerx'}, -- no template data; preprint uses limited arguments | ||
citeconference = {'Template:Cite conference/doc'}, | citeconference = {'Template:Cite conference/doc', 'conference'}, -- unique arguments | ||
citedocument = {'Template:Cite document/doc', 'document'}, -- special case; uses whitelist.document_parameters_t | |||
citeencyclopedia = {'Template:Cite encyclopedia/doc'}, | citeencyclopedia = {'Template:Cite encyclopedia/doc'}, | ||
citeepisode = {'Template:Cite episode/doc', 'episode'}, -- unique arguments | citeepisode = {'Template:Cite episode/doc', 'episode'}, -- unique arguments | ||
Line 979: | Line 1,005: | ||
citemagazine = {'Template:Cite magazine/doc'}, | citemagazine = {'Template:Cite magazine/doc'}, | ||
citemailinglist = {'Template:Cite mailing list/doc', 'mailinglist'}, -- unique arguments -- no template data | citemailinglist = {'Template:Cite mailing list/doc', 'mailinglist'}, -- unique arguments -- no template data | ||
citemap = {'Template:Cite map/ | citemap = {'Template:Cite map/TemplateData', 'map'}, -- unique arguments | ||
citemedrxiv = {'Template:Cite medRxiv/doc', 'medrxiv'}, -- preprint arguments | |||
citenews = {'Template:Cite news/doc'}, | citenews = {'Template:Cite news/doc'}, | ||
citenewsgroup = {'Template:Cite newsgroup/doc', 'newsgroup'}, -- unique arguments | citenewsgroup = {'Template:Cite newsgroup/doc', 'newsgroup'}, -- unique arguments | ||
citepodcast = {'Template:Cite podcast/doc'}, | citepodcast = {'Template:Cite podcast/doc'}, | ||
citepressrelease = {'Template:Cite press release/doc'}, | citepressrelease = {'Template:Cite press release/doc'}, | ||
citereport = {'Template:Cite report/doc'}, | citereport = {'Template:Cite report/doc', 'report'}, -- unique arguments | ||
citeserial = {'Template:Cite serial/doc', 'serial'}, -- unique arguments -- no template data | citeserial = {'Template:Cite serial/doc', 'serial'}, -- unique arguments -- no template data | ||
citesign = {'Template:Cite sign/doc'}, | citesign = {'Template:Cite sign/doc'}, | ||
citespeech = {'Template:Cite speech/doc'}, | citespeech = {'Template:Cite speech/doc', 'speech'}, -- unique arguments -- no template data | ||
citessrn = {'Template:Cite | citessrn = {'Template:Cite SSRN/doc', 'ssrn'}, -- preprint arguments -- no template data | ||
citetechreport = {'Template:Cite | citetechreport = {'Template:Cite tech report/doc'}, | ||
citethesis = {'Template:Cite thesis/doc'}, | citethesis = {'Template:Cite thesis/doc', 'thesis'}, -- unique arguments | ||
citeweb = {'Template:Cite web/doc'}, | citeweb = {'Template:Cite web/doc'}, | ||
citation = {'Template:Citation/doc'}, | citation = {'Template:Citation/doc'}, | ||
} | } | ||
--[[--------------------------< N O _ P A G E _ T E M P L A T E S _ T >---------------------------------------- | |||
]] | |||
local no_page_templates_t = {}; | |||
Line 1,025: | Line 1,060: | ||
json = json:match ('<[Tt]emplate[Dd]ata>(.-)</[Tt]emplate[Dd]ata>'); -- remove everything exept the content of the TemplatData tags | json = json:match ('<[Tt]emplate[Dd]ata>(.-)</[Tt]emplate[Dd]ata>'); -- remove everything exept the content of the TemplatData tags | ||
return json and mw.text.jsonDecode (json); -- decode the json string and return as a table; nil if not found | return json and mw.text.jsonDecode (json); -- decode the json string and return as a table; nil if not found | ||
end | |||
--[[--------------------------< V A L I D A T E _ D O C U M E N T _ P A R A M >-------------------------------- | |||
looks for <param> (can be the canonical parameter name or can be an alias) in whitelist.document_parameters_t. | |||
When found, returns true; nil else | |||
<param> is the parameter's name as listed in the TemplateData | |||
]] | |||
local function validate_document_param (param) | |||
if true == whitelist.document_parameters_t[param] then | |||
return true; | |||
end | |||
end | end | ||
Line 1,038: | Line 1,089: | ||
local function validate_basic_param (param) | local function validate_basic_param (param) | ||
if true == whitelist. | if true == whitelist.common_parameters_t[param] then | ||
return true; | return true; | ||
end | end | ||
Line 1,046: | Line 1,097: | ||
--[[--------------------------< V A L I D A T E _ P R E P R I N T _ P A R A M >-------------------------------- | --[[--------------------------< V A L I D A T E _ P R E P R I N T _ P A R A M >-------------------------------- | ||
looks for <param> (can be the canonical parameter name or can be an alias) in whitelist. | looks for <param> (can be the canonical parameter name or can be an alias) in whitelist.preprint_arguments_t{} or | ||
whitelist.limited_basic_arguments{} or whitelist.limited_numbered_arguments{}. When found, returns true; nil else | whitelist.limited_basic_arguments{} or whitelist.limited_numbered_arguments{}. When found, returns true; nil else | ||
<param> is the parameter's name as listed in the TemplateData | <param> is the parameter's name as listed in the TemplateData | ||
<key> is key neccessary to look in the appropriate subtable of whitelist. | <key> is key neccessary to look in the appropriate subtable of whitelist.preprint_arguments_t{} | ||
]] | ]] | ||
local function validate_preprint_param (param, key) | local function validate_preprint_param (param, key) | ||
if true == whitelist. | if true == whitelist.preprint_arguments_t[key][param] or | ||
true == whitelist. | true == whitelist.limited_parameters_t[param] then | ||
-- true == whitelist.limited_basic_arguments_t[param] or | |||
-- true == whitelist.limited_numbered_arguments_t[param] then | |||
return true; | return true; | ||
end | end | ||
Line 1,065: | Line 1,117: | ||
--[[--------------------------< V A L I D A T E _ U N I Q U E _ P A R A M >------------------------------------ | --[[--------------------------< V A L I D A T E _ U N I Q U E _ P A R A M >------------------------------------ | ||
looks for <param> (can be the canonical parameter name or can be an alias) in whitelist. | looks for <param> (can be the canonical parameter name or can be an alias) in whitelist.unique_arguments_t{} or | ||
whitelist.basic_arguments{} or whitelist.numbered_arguments{}. When found, returns true; nil else | whitelist.basic_arguments{} or whitelist.numbered_arguments{}. When found, returns true; nil else | ||
<param> is the parameter's name as listed in the TemplateData | <param> is the parameter's name as listed in the TemplateData | ||
<key> is key neccessary to look in the appropriate subtable of whitelist. | <key> is key neccessary to look in the appropriate subtable of whitelist.unique_arguments_t{} | ||
]] | ]] | ||
local function validate_unique_param (param, key) | local function validate_unique_param (param, key, cfg_aliases_t) | ||
if true == whitelist. | if true == whitelist.unique_arguments_t[key][param] or true == validate_basic_param (param) then | ||
return true; | return true; | ||
end | end | ||
Line 1,100: | Line 1,152: | ||
local function param_error_msg (param) | local function param_error_msg (param) | ||
return '< | return '<span style="font-family:"monospace">|' .. param .. '=</span> is not a valid parameter'; | ||
end | |||
--[[--------------------------< D U P _ A L I A S _ E R R O R_ M S G >----------------------------------------- | |||
]] | |||
local function dup_alias_error_msg (param, alias) | |||
return '<span style="font-family:"monospace">|' .. param .. '=</span> has duplicate aliases: <span font-family:"monospace";>|' .. alias .. '=</span>'; | |||
end | |||
--[[--------------------------< D U P _ A L I A S E S _ C H E C K >-------------------------------------------- | |||
create an associative array of <param> aliases. if <alias> already present in <aliases_t> add an error message | |||
to <out> | |||
]] | |||
local function dup_aliases_check (param, alias, aliases_t, out_t) | |||
if not aliases_t[alias] then | |||
aliases_t[alias] = true; | |||
else | |||
table.insert (out_t, dup_alias_error_msg (param, alias)); | |||
end | |||
end | end | ||
Line 1,110: | Line 1,188: | ||
local function alias_error_msg (param, alias) | local function alias_error_msg (param, alias) | ||
return '<code style="color: inherit; background: inherit; border: none; padding: inherit">|' .. alias .. '=</code> not valid alias of: <code style="color: inherit; background: inherit; border: none; padding: inherit">|' .. param .. '=</code>'; | return '<code style="color: inherit; background: inherit; border: none; padding: inherit">|' .. alias .. '=</code> is not a valid alias of: <code style="color: inherit; background: inherit; border: none; padding: inherit">|' .. param .. '=</code>'; | ||
end | |||
--[[--------------------------< C F G _ A L I A S E S _ T _ M A K E >------------------------------------------ | |||
convert this from cfg.aliases{}: | |||
['AccessDate'] = {'access-date', 'accessdate'} | |||
to this in out_t{} | |||
['access-date'] = 'AccessDate', | |||
['accessdate'] = 'AccessDate', | |||
to test if |accessdate= is an aliases of |access-date=: | |||
if out_t['access-date'] == out_t['accessdate'] | |||
]] | |||
local function cfg_aliasts_t_make () | |||
local out_t = {}; | |||
for meta, params_t in pairs (cfg.aliases) do | |||
if 'table' == type (params_t) then -- metaparameters that are assigned string values do not have aliases | |||
for _, param in ipairs (params_t) do -- for each alias | |||
param = param:gsub ('#', ''); -- get rid of enumerators | |||
out_t[param] = meta; -- add it to the output table | |||
end | |||
end | |||
end | |||
--error (mw.dumpObject (out_t)) | |||
return out_t; | |||
end | end | ||
Line 1,122: | Line 1,228: | ||
When called from a different page: | When called from a different page: | ||
{{#invoke: | {{#invoke:cs1 documentation support|template_data_validate|<canonical template name>}} | ||
where the <canonical template name> is the template's canonical name with or without namespace and or subpages | where the <canonical template name> is the template's canonical name with or without namespace and or subpages | ||
Line 1,129: | Line 1,235: | ||
local function template_data_validate (frame) | local function template_data_validate (frame) | ||
local args_t = getArgs (frame); | local args_t = getArgs (frame); | ||
if not args_t[1] then | if not args_t[1] then | ||
return '<span style= | return '<span style="color:#d33">Error: cs1|2 template name required</span>'; | ||
end | end | ||
local template_idx = args_t[1]:lower():match ('cit[ae][^/]+'); -- args_t[1] has something | local template_idx = args_t[1]:lower():match ('cit[ae][^/]+'); -- args_t[1] has something | ||
if not template_idx then -- but if not a cs1|2 template abandon with error message | if not template_idx then -- but if not a cs1|2 template abandon with error message | ||
return '<span style= | return '<span style="color:#d33">Error: cs1|2 template name required</span>'; | ||
else | else | ||
template_idx = template_idx:gsub (' ', ''); -- is what appears to be a cs1|2 template so strip spaces | template_idx = template_idx:gsub (' ', ''); -- is what appears to be a cs1|2 template so strip spaces | ||
end | end | ||
local cfg_aliases_t = cfg_aliasts_t_make (); | |||
local template_t = templates_t[template_idx]; | local template_t = templates_t[template_idx]; | ||
Line 1,151: | Line 1,259: | ||
else | else | ||
for param, param_t in pairs (json_t['params']) do | for param, param_t in pairs (json_t['params']) do | ||
local param_i = param:gsub ('%d+', '#'); | local param_i; -- this will be the parameter name that gets validated | ||
if param:find ('[Ss]2[Cc][Ii][Dd]') then -- |s2cid*= parameters are not enumerated ... | |||
param_i = param; -- ... so don't convert the '2' to '#' | |||
else | |||
param_i = param:gsub ('%d+', '#'); -- for enumerated parameters, convert the enumerator digits to a single '#' character; all others unmolested | |||
end | |||
local param_is_valid; -- boolean true when param is valid; nil else | local param_is_valid; -- boolean true when param is valid; nil else | ||
if template_t[2] then -- if template is a preprint or uses unique parameters | if template_t[2] then -- if template is a preprint or uses unique parameters of 'document' parameters | ||
if whitelist. | if 'document' == template_t[2] then -- if a {{cite document}} template | ||
param_is_valid = validate_document_param (param_i, template_t[2]); | |||
if param_is_valid then | |||
local aliases_t = {}; -- used by dup_aliases_check | |||
if param_t['aliases'] then | |||
for _, alias in ipairs (param_t['aliases']) do | |||
dup_aliases_check (param, alias, aliases_t, out); | |||
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerator digits to a single '#' character | |||
if not validate_document_param (alias_i, template_t[2]) then -- is 'alias' a known parameter? | |||
table.insert (out, alias_error_msg (param, alias)); -- may be known but is not supported | |||
elseif cfg_aliases_t[param_i:gsub ('#', '')] ~= cfg_aliases_t[alias_i:gsub ('#', '')] then -- is 'alias' known to be an alias of 'param'? | |||
table.insert (out, alias_error_msg (param, alias)); | |||
end | |||
end | |||
end | |||
else -- here when param not valid preprint param | |||
table.insert (out, param_error_msg (param)) | |||
end | |||
elseif whitelist.preprint_arguments_t[template_t[2]] then -- if a preprint template | |||
param_is_valid = validate_preprint_param (param_i, template_t[2]); | param_is_valid = validate_preprint_param (param_i, template_t[2]); | ||
if param_is_valid then | if param_is_valid then | ||
local aliases_t = {}; -- used by dup_aliases_check | |||
if param_t['aliases'] then | if param_t['aliases'] then | ||
for _, alias in ipairs (param_t['aliases']) do | for _, alias in ipairs (param_t['aliases']) do | ||
dup_aliases_check (param, alias, aliases_t, out); | |||
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerator digits to a single '#' character | local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerator digits to a single '#' character | ||
if not validate_preprint_param (alias_i, template_t[2]) then -- is 'alias' a known parameter? | |||
table.insert (out, alias_error_msg (param, alias)); | table.insert (out, alias_error_msg (param, alias)); -- may be known but is not supported | ||
elseif cfg_aliases_t[param_i:gsub ('#', '')] ~= cfg_aliases_t[alias_i:gsub ('#', '')] then -- is 'alias' known to be an alias of 'param'? | |||
table.insert (out, alias_error_msg (param, alias)); | |||
end | end | ||
end | end | ||
Line 1,168: | Line 1,304: | ||
table.insert (out, param_error_msg (param)) | table.insert (out, param_error_msg (param)) | ||
end | end | ||
elseif whitelist. | elseif whitelist.unique_arguments_t[template_t[2]] then -- if a unique parameters template | ||
param_is_valid = validate_unique_param (param_i, template_t[2]); | param_is_valid = validate_unique_param (param_i, template_t[2]); | ||
if param_is_valid then | if param_is_valid then | ||
local aliases_t = {}; -- used by dup_aliases_check | |||
if param_t['aliases'] then | if param_t['aliases'] then | ||
for _, alias in ipairs (param_t['aliases']) do | for _, alias in ipairs (param_t['aliases']) do | ||
dup_aliases_check (param, alias, aliases_t, out); | |||
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character | local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character | ||
if not validate_unique_param (alias_i, template_t[2]) then -- is 'alias' a known parameter? | |||
table.insert (out, alias_error_msg (param, alias)); | |||
elseif cfg_aliases_t[param_i:gsub ('#', '')] ~= cfg_aliases_t[alias_i:gsub ('#', '')] then -- is 'alias' known to be an alias of 'param'? | |||
table.insert (out, alias_error_msg (param, alias)); | table.insert (out, alias_error_msg (param, alias)); | ||
end | end | ||
Line 1,189: | Line 1,329: | ||
param_is_valid = validate_basic_param (param_i); | param_is_valid = validate_basic_param (param_i); | ||
if param_is_valid then | if param_is_valid then | ||
local aliases_t = {}; -- used by dup_aliases_check | |||
if param_t['aliases'] then | if param_t['aliases'] then | ||
for _, alias in ipairs (param_t['aliases']) do | for _, alias in ipairs (param_t['aliases']) do | ||
dup_aliases_check (param, alias, aliases_t, out) | |||
local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character | local alias_i = alias:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character | ||
if not validate_basic_param (alias_i) and not validate_id_alias (param, alias) then -- for isbn13 (while still supported) must not mask the digits | |||
table.insert (out, alias_error_msg (param, alias)); | table.insert (out, alias_error_msg (param, alias)); | ||
elseif cfg_aliases_t[param_i:gsub ('#', '')] ~= cfg_aliases_t[alias_i:gsub ('#', '')] then -- is 'alias' known to be an alias of 'param'? | |||
table.insert (out, alias_error_msg (param, alias)); | |||
end | end | ||
end | end | ||
Line 1,203: | Line 1,347: | ||
end | end | ||
end | end | ||
---------- this emits errors when page/pages/at listed in templatedata of templates that don't support those parameters ---------- | |||
-- if json_t then | |||
-- if ({['citeavmedia']=true, ['citeepisode']=true, ['citemailinglist']=true, ['citenewsgroup']=true, ['citepodcast']=true, ['citeserial']=true, ['citesign']=true, ['citespeech']=true})[template_idx] then | |||
-- local insource_params_t = {}; -- build sequence of pagination params not supported by these templates | |||
-- for _, meta_param in ipairs ({'At', 'Page', 'Pages', 'QuotePage', 'QuotePages'}) do | |||
-- if 'table' == type (cfg.aliases[meta_param]) then | |||
-- for _, alias in ipairs (cfg.aliases[meta_param]) do -- metaparameter is a sequence | |||
-- table.insert (insource_params_t, alias); -- add the aliases from the metaparameter sequence to the table | |||
-- end | |||
-- else -- metaparameter is plain text | |||
-- table.insert (insource_params_t, cfg.aliases[meta_param]); -- add the alias to the table | |||
-- end | |||
-- end | |||
-- | |||
-- for _, param in ipairs (insource_params_t) do | |||
-- if json_t.params[param] then | |||
-- table.insert (out, param_error_msg (param)); -- error; this parameter not supported by this template | |||
-- end | |||
-- end | |||
-- end | |||
-- end | |||
---------- end page/pages/at error detection ---------- | |||
if 0 ~= #out then | if 0 ~= #out then | ||
table.sort (out); | table.sort (out); | ||
out[1] = '*' .. out[1]; -- add a splat to the first error message | out[1] = '*' .. out[1]; -- add a splat to the first error message | ||
-- return table.concat ({'[[' .. template_doc .. ']] TemplateData has errors:<div style="color:#d33; font-style: normal">\n', table.concat (out, '\n*'), '</div>'}); | |||
return table.concat ({ | |||
'[[Template:' .. args_t[1] .. ']] uses ', | |||
whitelist.preprint_arguments_t[template_t[2]] and 'preprint and limited parameter sets' or (whitelist.unique_arguments_t[template_t[2]] and 'unique and standard parameter sets' or 'standard parameter set'), | |||
'; TemplateData has errors:\n', | |||
'<div style="color:#d33; font-style: normal">\n', table.concat (out, '\n*'), '</div>' | |||
}); | |||
else | else | ||
return; -- no errors detected; return nothing | return; -- no errors detected; return nothing | ||
end | |||
end | |||
--[[--------------------------< E R R O R _ C A T _ P A G E _ T A L L Y >-------------------------------------- | |||
loop through Module:Citation/CS1/Configuration error_conditions {} fetching error category names. For each error | |||
category add the number of pages in the category to the tally. Render the number when done. | |||
{{#invoke:cs1 documentation support|error_cat_page_tally}} | |||
]] | |||
local function error_cat_page_tally () | |||
local error_conditions_t = cfg.error_conditions; -- get the table of error conditions | |||
local tally = 0; | |||
local cat_t = {}; -- some error message share a category; save tallied cats here so we don't recount the already counted | |||
local i = 0; -- number of categories | |||
for k, v_t in pairs (error_conditions_t) do | |||
if k:match ('^err') then | |||
if not cat_t[v_t.category] then | |||
cat_t[v_t.category] = true; | |||
tally = tally + mw.site.stats.pagesInCategory (v_t.category, 'pages'); -- get category page count; ignore subcats and files | |||
i = i + 1; | |||
end | |||
end | |||
end | |||
return mw.language.getContentLanguage():formatNum (tally) | |||
end | |||
--[[--------------------------< M A I N T _ C A T _ P A G E _ T A L L Y >-------------------------------------- | |||
loop through Module:Citation/CS1/Configuration error_conditions {} fetching error category names. For each error | |||
category add the number of pages in the category to the tally. Render the number when done. | |||
{{#invoke:cs1 documentation support|maint_cat_page_tally}} | |||
Dynamic subcats of CS1 maint: DOI inactive not counted because these names come and go as time goes by. | |||
]] | |||
local function maint_cat_page_tally () | |||
local error_conditions_t = cfg.error_conditions; -- get the table of error conditions | |||
local tally = 0; | |||
local cat_t = {}; -- some error message share a category; save tallied cats here so we don't recount the already counted | |||
local i = 0; -- number of categories | |||
for k, v_t in pairs (error_conditions_t) do | |||
if not k:match ('^err') then -- if not an error key its a maint key | |||
if not cat_t[v_t.category] then | |||
cat_t[v_t.category] = true; | |||
if 'maint_mult_names' == k or 'maint_numeric_names' == k then | |||
local special_case_translation_t = cfg.special_case_translation; | |||
for _, name in ipairs ({'AuthorList', 'ContributorList', 'EditorList', 'InterviewerList', 'TranslatorList'}) do | |||
local cat_name = v_t.category:gsub ('$1', special_case_translation_t[name]); -- replace $1 with translated list name | |||
tally = tally + mw.site.stats.pagesInCategory (cat_name, 'pages'); -- get category page count; ignore subcats and files | |||
i = i + 1; | |||
end | |||
else | |||
tally = tally + mw.site.stats.pagesInCategory (v_t.category, 'pages'); -- get category page count; ignore subcats and files | |||
i = i + 1; | |||
end | |||
end | |||
end | |||
end | |||
return mw.language.getContentLanguage():formatNum (tally) | |||
end | |||
--[[--------------------------< U N C A T E G O R I Z E D _ N A M E S P A C E _ L I S T E R >------------------ | |||
For use in the Help:CS1 error §Notes | |||
Get namespace names and identifiers from MediaWiki. Make a human readable list of namespace names and identifiers | |||
that cs1|2 does not categorize. | |||
{{#invoke:cs1 documentation support|uncategorized_namespace_lister}} | |||
For convenience, | |||
{{#invoke:cs1 documentation support|uncategorized_namespace_lister|all=<anything>}} | |||
returns a list of all namespace names and identifiers used on the current wiki. Any namespace with an | |||
identifier less than 1, currently Mainspace (0), Special (-1), and Media (-2), is excluded from the list. | |||
]] | |||
local function uncategorized_namespace_lister (frame) | |||
local list_t = {}; | |||
local function compare (a, b) -- local function to sort namespaces numerically by the identifiers | |||
local a_num = tonumber (a:match ('%d+')); -- get identifiers and convert to numbers | |||
local b_num = tonumber (b:match ('%d+')); | |||
return a_num < b_num; -- do the comparison | |||
end | |||
for i, _ in pairs (mw.site.namespaces) do -- for each namespace in the table | |||
if '' == frame.args.all or not frame.args.all then -- when |all= not set, make a list of uncategorized namespaces | |||
if cfg.uncategorized_namespaces[i] then -- if the identifier is listed in our uncategorized namespace list | |||
table.insert (list_t, table.concat ({mw.site.namespaces[i].name, ' (', i, ')'})) -- add name and identifier to our local list | |||
end | |||
elseif 0 < i then -- |all=<anything>: all namespace names and identifiers; ignore identifiers less than 1 | |||
table.insert (list_t, table.concat ({'*', mw.site.namespaces[i].name, ' (', i, ')'})) -- add name and identifier as an unordered list item | |||
end | |||
end | |||
table.sort (list_t, compare); -- ascending numerical sort by identifier | |||
if not frame.args.all then -- when |all= not set, format list of uncategorized namespaces and identifiers | |||
list_t[#list_t] = 'and ' .. list_t[#list_t]; -- add 'and ' to the last name/identifier pair | |||
return table.concat (list_t, ', '); -- make a big string and done | |||
else -- make list of all namespaces and identifiers | |||
return table.concat (list_t, '\n'); -- make a big string and done | |||
end | |||
end | |||
--[[--------------------------< S I N G L E _ L T R _ 2 N D _ L V L _ D O M A I N _ L I S T E R >------------- | |||
for Help:CS1_errors#bad_url, list the supported top level domains that support single-letter 2nd level names | |||
{{#invoke:Module:cs1 documentation support|single_ltr_2nd_lvl_domain_lister}} | |||
]] | |||
local function single_ltr_2nd_lvl_domain_lister () | |||
local out_t = {}; -- output goes here | |||
for _, tld in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- fetch each tld | |||
table.insert (out_t, '.' .. tld); -- prefix with a dot and save in out_t{} | |||
end | |||
return table.concat (out_t, ', '); -- make a big string and done | |||
end | |||
--[[--------------------------< C O D E _ N A M E _ P A I R _ E X I S T S >---------------------------------------- | |||
Returns language code if pair exists, nil if either code doesn't exist or the name doesn't match. | |||
Intended for use by Template:CS1 language sources/core | |||
args[1] is language code | |||
args[2] is language name | |||
]] | |||
local function code_name_pair_exists(frame) | |||
local wiki_language = mw.getContentLanguage():getCode() | |||
local source_list = mw.language.fetchLanguageNames(wiki_language, 'all'); | |||
local code_list = {}; | |||
local name_list = {}; | |||
local override = cfg.lang_tag_remap; | |||
for code, name in pairs(source_list) do | |||
add_to_list(code_list, name_list, override, code, name); | |||
end | |||
local args = getArgs(frame); | |||
local language_code = args[1] | |||
local language_name = args[2] | |||
-- Check if the language code exists and the corresponding name matches | |||
if code_list[language_code] == language_name then | |||
-- Both code and name are a valid pair | |||
return language_code | |||
else | |||
-- Either code doesn't exist or the name doesn't match | |||
return nil | |||
end | end | ||
end | end | ||
Line 1,223: | Line 1,564: | ||
canonical_name_get = canonical_name_get, | canonical_name_get = canonical_name_get, | ||
cat_lister = cat_lister, | cat_lister = cat_lister, | ||
code_name_pair_exists = code_name_pair_exists, | |||
error_cat_page_tally = error_cat_page_tally, | |||
header_make = header_make, | header_make = header_make, | ||
help_text_cats = help_text_cats, | help_text_cats = help_text_cats, | ||
Line 1,230: | Line 1,573: | ||
is_limited_param_template = is_limited_param_template, | is_limited_param_template = is_limited_param_template, | ||
lang_lister = lang_lister, | lang_lister = lang_lister, | ||
maint_cat_page_tally = maint_cat_page_tally, | |||
script_lang_lister = script_lang_lister, | script_lang_lister = script_lang_lister, | ||
single_ltr_2nd_lvl_domain_lister = single_ltr_2nd_lvl_domain_lister, | |||
template_data_validate = template_data_validate, | template_data_validate = template_data_validate, | ||
uncategorized_namespace_lister = uncategorized_namespace_lister, | |||
}; | }; |