Module:Cs1 documentation support: Difference between revisions
Content deleted Content added
Johnrdorazio (talk | contribs) m 1 revision imported |
use require('strict') instead of require('Module:No globals') |
||
Line 1: | Line 1: | ||
require(' |
require('strict'); |
||
local getArgs = require ('Module:Arguments').getArgs; |
local getArgs = require ('Module:Arguments').getArgs; |
||
local cfg = mw.loadData ('Module:Citation/CS1/Configuration'); -- load the configuration module |
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 |
local exclusion_lists = { -- TODO: move these tables into a separate ~/data module and mw.loadData() it |
||
Line 170: | 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 |
||
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 187: | Line 191: | ||
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 200: | 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 (ietf_list, name_list, override, code, name); |
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 208: | 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 223: | Line 237: | ||
table.sort (result); |
table.sort (result); |
||
table.insert (result, 1, templatestyles .. '<div class="div-col" style="column-width: |
table.insert (result, 1, templatestyles .. '<div class="div-col" style="column-width:16em">'); |
||
table.insert (out, table.concat (result, '\n*')); |
table.insert (out, table.concat (result, '\n*')); |
||
table.insert (out, '</div>'); |
table.insert (out, '</div>'); |
||
Line 267: | Line 281: | ||
table.sort (result); |
table.sort (result); |
||
table.insert (result, 1, templatestyles .. '<div class="div-col" style="column-width: |
table.insert (result, 1, templatestyles .. '<div class="div-col" style="column-width:16em">'); |
||
table.insert (out, table.concat (result, '\n*')); |
table.insert (out, table.concat (result, '\n*')); |
||
table.insert (out, '</div>'); |
table.insert (out, '</div>'); |
||
Line 661: | 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 670: | Line 684: | ||
local function cat_link_make (cat) |
local function cat_link_make (cat) |
||
return table.concat ({'[[:Category:', cat, ']]'}); |
return table.concat ({'[[:Category:', cat, ']]'}); |
||
end |
|||
--[[--------------------------< S C R I P T _ C A T _ L I S T E R >-------------------------------------------- |
|||
utility function to get script-language categories |
|||
]] |
|||
local lang_list_t = mw.language.fetchLanguageNames ('en', 'all'); |
|||
local function script_cat_lister (script_lang_codes_t, lang_code_remap_t, cats_list_t) |
|||
for _, lang_code in ipairs (script_lang_codes_t) do |
|||
local lang_name = lang_code_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 |
|||
cats_list_t[cat] = 1; -- and save it |
|||
end |
|||
end |
end |
||
Line 746: | Line 777: | ||
list_live_cats[cat] = 1; -- add to the list |
list_live_cats[cat] = 1; -- add to the list |
||
end |
end |
||
script_cat_lister (cfg.script_lang_codes, cfg.lang_code_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' |
||
for _, cat in pairs (sb_cfg.prop_cats) do -- get the |
for _, cat in pairs (sb_cfg.prop_cats) do -- get the sandbox module's categories |
||
cat = cat:gsub ('|(.*)$', ''); -- strip sort key if any |
cat = cat:gsub ('|(.*)$', ''); -- strip sort key if any |
||
list_sbox_cats[cat] = 1; -- add to the list |
list_sbox_cats[cat] = 1; -- add to the list |
||
end |
end |
||
script_cat_lister (sb_cfg.script_lang_codes, sb_cfg.lang_code_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 854: | 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 out = {}; -- output goes here |
|||
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 args[1] and error_conditions[args[1]] then -- must have error_condition key and it must exist |
|||
local title_obj = mw.title.getCurrentTitle(); -- get a title object for the currently displayed page |
|||
table.insert (out, '{{#ifeq:{{FULLPAGENAME}}|Category:'); -- the beginning with category prefix |
|||
local name_space = title_obj.nsText; |
|||
table.insert (out, error_conditions[args[1]].category); -- fetch the error category name (the reference that {{FULLPAGENAME}} must equate to) |
|||
if ('Category' == name_space) and (error_cat == title_obj.text) then -- if this is the category page for the error message |
|||
table. |
return table.concat ({'Category:', error_cat}); -- no link; just category name |
||
else -- here when currently displayed page is other than the error message category |
|||
table.insert (out, '|'); -- the necessary pipe |
|||
local pages = ''; -- default empty strin for concatenation |
|||
table.insert (out, cat_link_make (error_conditions[args[1]].category)); -- one the help page or elsewhere so link to the category |
|||
if 'yes' == args_t.pages then -- if we should display category page count: TODO: do we need to keep this? |
|||
table.insert (out, '}}'); -- and close the #ifeq |
|||
pages = mw.site.stats.pagesInCategory (error_cat, 'all'); -- get category page count |
|||
if 'yes' == args.pages then |
|||
pages = table.concat ({' (', mw.language.getContentLanguage():formatNum (pages), ' page', (1 == pages) and ')' or 's)'}); -- make renderable text |
|||
table.insert (out, ' ({{PAGESINCATEGORY:'); |
|||
end |
|||
table.insert (out, error_conditions[args[1]].category); -- fetch the error category name |
|||
return table.concat ({'[[:Category:', error_cat, ']]', pages}); -- link to category with or without page count |
|||
table.insert (out, '}} pages)'); |
|||
end |
end |
||
else |
else |
||
return '<span style=" |
return '<span style="color:#d33">unknown error_conditions key: ' .. (args[1] or 'key missing') .. '</span>'; |
||
end |
end |
||
return frame:preprocess (table.concat (out)); -- make a big string, preprocess, and done |
|||
end |
end |
||
Line 892: | Line 927: | ||
{{#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 903: | Line 942: | ||
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 910: | Line 949: | ||
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 919: | Line 958: | ||
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}); |
|||
end |
|||
return table.concat ({out_str, frame:extensionTag ('templatestyles', '', {src='Module:Citation/CS1/styles.css'})}); |
|||
--[[--------------------------< T E M P L A T E S _ T >-------------------------------------------------------- |
|||
This table is a k/v table of sequence tables. The keys in this table are collapsed lowercase form of the cs1|2 |
|||
template names ({{ROOTPAGENAME}}): |
|||
Template:Cite AV media -> citeavmedia |
|||
Each subsequence table holds: |
|||
[1] documentation page where the TemplateData json is stored ({{cite book}} is the oddball) |
|||
[2] key to 'preprint_arguments' and unique_arguments' 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 |
|||
the content of the TemplateData |
|||
]] |
|||
local templates_t = { |
|||
citearxiv = {'Template:Cite_arXiv/doc', 'arxiv'}, -- preprint arguments |
|||
citeavmedia = {'Template:Cite AV media/doc', 'audio-visual'}, -- unique arguments |
|||
citeavmedianotes = {'Template:Cite AV media notes/doc'}, -- no template data |
|||
citebiorxiv = {'Template:Cite bioRxiv/doc', 'biorxiv'}, -- preprint arguments |
|||
citebook = {'Template:Cite book/TemplateData'}, |
|||
citeciteseerx = {'Template:Cite citeseerx/doc', 'citeseerx'}, -- no template data; preprint uses limited arguments |
|||
citeconference = {'Template:Cite conference/doc', 'conference'}, -- unique arguments |
|||
citeencyclopedia = {'Template:Cite encyclopedia/doc'}, |
|||
citeepisode = {'Template:Cite episode/doc', 'episode'}, -- unique arguments |
|||
citeinterview = {'Template:Cite interview/doc'}, |
|||
citejournal = {'Template:Cite journal/doc'}, |
|||
citemagazine = {'Template:Cite magazine/doc'}, |
|||
citemailinglist = {'Template:Cite mailing list/doc', 'mailinglist'}, -- unique arguments -- no template data |
|||
citemap = {'Template:Cite map/TemplateData', 'map'}, -- unique arguments |
|||
citenews = {'Template:Cite news/doc'}, |
|||
citenewsgroup = {'Template:Cite newsgroup/doc', 'newsgroup'}, -- unique arguments |
|||
citepodcast = {'Template:Cite podcast/doc'}, |
|||
citepressrelease = {'Template:Cite press release/doc'}, |
|||
citereport = {'Template:Cite report/doc', 'report'}, -- unique arguments |
|||
citeserial = {'Template:Cite serial/doc', 'serial'}, -- unique arguments -- no template data |
|||
citesign = {'Template:Cite sign/doc'}, |
|||
citespeech = {'Template:Cite speech/doc', 'speech'}, -- unique arguments -- no template data |
|||
citessrn = {'Template:Cite ssrn/doc', 'ssrn'}, -- preprint arguments -- no template data |
|||
citetechreport = {'Template:Cite techreport/doc'}, |
|||
citethesis = {'Template:Cite thesis/doc', 'thesis'}, -- unique arguments |
|||
citeweb = {'Template:Cite web/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 = {}; |
|||
--[[--------------------------< I D E N T I F I E R _ A L I A S E S _ T >-------------------------------------- |
|||
a table of the identifier aliases |
|||
]] |
|||
local identifier_aliases_t = {} |
|||
for identifier, handler in pairs (cfg.id_handlers) do -- for each identifier |
|||
local aliases_t = {}; -- create a table |
|||
for _, alias in ipairs (handler.parameters) do -- get the alaises |
|||
aliases_t[alias] = true; -- and add them to the table in a form that mimics the whitelist tables |
|||
end |
|||
identifier_aliases_t[identifier:lower()] = aliases_t; -- add new table to the identifier aliases table; use lowercase identifier base name for the key |
|||
end |
|||
--[[--------------------------< T E M P L A T E _ D A T A _ J S O N _ G E T >---------------------------------- |
|||
get template doc page content and extract the content of the TemplateData tags (case insensitive) |
|||
<template> is the canonical name of the template doc page (with namespace) that holds the template data; usually |
|||
Template:Cite xxx/doc (except Template:Cite book/TemplateData) |
|||
]] |
|||
local function template_data_json_get (template) |
|||
local json = mw.title.new (template):getContent() or ''; -- get the content of the article or ''; new pages edited w/ve do not have 'content' until saved; ve does not preview; phab:T221625 |
|||
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 |
|||
end |
|||
--[[--------------------------< 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.basic_arguments{} and if |
|||
necessary in whitelist.numbered_arguments{}. When found, returns true; nil else |
|||
<param> is the parameter's name as listed in the TemplateData |
|||
]] |
|||
local function validate_basic_param (param) |
|||
if true == whitelist.basic_arguments[param] or true == whitelist.numbered_arguments[param] then |
|||
return true; |
|||
end |
|||
end |
|||
--[[--------------------------< 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.preprint_arguments{} or |
|||
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 |
|||
<key> is key neccessary to look in the appropriate subtable of whitelist.preprint_arguments{} |
|||
]] |
|||
local function validate_preprint_param (param, key) |
|||
if true == whitelist.preprint_arguments[key][param] or |
|||
true == whitelist.limited_basic_arguments[param] or |
|||
true == whitelist.limited_numbered_arguments[param] then |
|||
return true; |
|||
end |
|||
end |
|||
--[[--------------------------< 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.unique_arguments{} or |
|||
whitelist.basic_arguments{} or whitelist.numbered_arguments{}. When found, returns true; nil else |
|||
<param> is the parameter's name as listed in the TemplateData |
|||
<key> is key neccessary to look in the appropriate subtable of whitelist.unique_arguments{} |
|||
]] |
|||
local function validate_unique_param (param, key, cfg_aliases_t) |
|||
if true == whitelist.unique_arguments[key][param] or true == validate_basic_param (param) then |
|||
return true; |
|||
end |
|||
end |
|||
--[[--------------------------< V A L I D A T E _ I D _ P A R A M >-------------------------------------------- |
|||
looks for <param> <alias> in identifier_aliases_t{}. When found, returns true; nil else |
|||
<param> is the parameter's name as listed in the TemplateData |
|||
<alias> is the alias that we're looking for |
|||
]] |
|||
local function validate_id_alias (param, alias) |
|||
return identifier_aliases_t[param] and identifier_aliases_t[param][alias]; |
|||
end |
|||
--[[--------------------------< P A R A M _ E R R O R_ M S G >------------------------------------------------- |
|||
]] |
|||
local function param_error_msg (param) |
|||
return '<code style="color: inherit; background: inherit; border: none; padding: inherit">|' .. param .. '=</code> is not a valid parameter'; |
|||
end |
|||
--[[--------------------------< A L I A S _ E R R O R_ M S G >------------------------------------------------- |
|||
]] |
|||
local function alias_error_msg (param, alias) |
|||
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 |
|||
--[[--------------------------< T E M P L A T E _ D A T A _ V A L I D A T E >---------------------------------- |
|||
compairs parameter names listed in a cs1|2 template's TemplateData structure (everything between <TemplateData> |
|||
and </TemplateData> tag case insensitive). Returns error messages when errors found, empty string else. |
|||
{{#invoke:Cs1 documentation support|template_data_validate|{{ROOTPAGENAME}}}} |
|||
When called from a different page: |
|||
{{#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 |
|||
]] |
|||
local function template_data_validate (frame) |
|||
local args_t = getArgs (frame); |
|||
if not args_t[1] then |
|||
return '<span style="color:#d33">Error: cs1|2 template name required</span>'; |
|||
end |
|||
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 |
|||
return '<span style="color:#d33">Error: cs1|2 template name required</span>'; |
|||
else |
|||
template_idx = template_idx:gsub (' ', ''); -- is what appears to be a cs1|2 template so strip spaces |
|||
end |
|||
local cfg_aliases_t = cfg_aliasts_t_make (); |
|||
local template_t = templates_t[template_idx]; |
|||
local out = {}; |
|||
local template_doc = template_t[1]; |
|||
local json_t = template_data_json_get (template_doc); |
|||
if not json_t then |
|||
table.insert (out, 'Error: can\'t find TemplateData'); |
|||
else |
|||
for param, param_t in pairs (json_t['params']) do |
|||
local param_i = param:gsub ('%d+', '#'); -- in case an enumerated parameter, convert the enumerate digits to a single '#' character |
|||
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 whitelist.preprint_arguments[template_t[2]] then -- if a preprint template |
|||
param_is_valid = validate_preprint_param (param_i, template_t[2]); |
|||
if param_is_valid then |
|||
if param_t['aliases'] then |
|||
for _, alias in ipairs (param_t['aliases']) do |
|||
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)); -- 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.unique_arguments[template_t[2]] then -- if a unique parameters template |
|||
param_is_valid = validate_unique_param (param_i, template_t[2]); |
|||
if param_is_valid then |
|||
if param_t['aliases'] then |
|||
for _, alias in ipairs (param_t['aliases']) do |
|||
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)); |
|||
end |
|||
end |
|||
end |
|||
else -- here when param not valid unique parameter |
|||
table.insert (out, param_error_msg (param)) |
|||
end |
|||
else -- should never be here if coder is doing the right thing ... |
|||
table.insert (out, 'internal error: unexpected keyword in templates_t: ' .. template_t[2]); |
|||
break; |
|||
end |
|||
else -- here when not unique or preprint |
|||
param_is_valid = validate_basic_param (param_i); |
|||
if param_is_valid then |
|||
if param_t['aliases'] then |
|||
for _, alias in ipairs (param_t['aliases']) do |
|||
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)); |
|||
end |
|||
end |
|||
end |
|||
else -- here when param not valid |
|||
table.insert (out, param_error_msg (param)) |
|||
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 |
|||
table.sort (out); |
|||
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[template_t[2]] and 'preprint and limited parameter sets' or (whitelist.unique_arguments[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 |
|||
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) |
|||
--TEMP DEVELOPMENT 2022-07-09 -- delete at next module update |
|||
local cfg = mw.loadData ('Module:Citation/CS1/Configuration/sandbox'); -- load the SANDBOX configuration module |
|||
--END TEMP DEVELOPMENT |
|||
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 |
end |
||
Line 937: | Line 1,429: | ||
canonical_name_get = canonical_name_get, |
canonical_name_get = canonical_name_get, |
||
cat_lister = cat_lister, |
cat_lister = cat_lister, |
||
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 944: | Line 1,437: | ||
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, |
||
template_data_validate = template_data_validate, |
|||
uncategorized_namespace_lister = uncategorized_namespace_lister, |
|||
}; |
}; |