Module:Footnotes/anchor id list/sandbox: Difference between revisions

Content deleted Content added
sync from live;
 
Restored revision 1291947075 by Hike395 (talk): Nope: wasn't my edits
 
(51 intermediate revisions by 5 users not shown)
Line 1:
require('Module:No globalsstrict');
local data = mw.loadData ('Module:Footnotes/anchor id list/data');
local whitelist = mw.loadData ('Module:Footnotes/whitelist/sandbox');
local Lang_obj = mw.language.getContentLanguage(); -- used by template_name_get() to uppercase first letter of template name TODO: better way to do that?
 
local anchor_id_list = {};
 
local redirect_patterns_anchor = {
'{{%s*[Aa]nchor',
'{{%s*[Aa]nchor for redirect',
'{{%s*[Aa]nchors',
'{{%s*[Aa]nchro',
'{{%s*[Aa]ncor',
}
local redirect_patterns_harvc = {
'{{%s*[Hh]arvc',
'{{%s*[Cc]itec',
}
local redirect_patterns_sfn_whitelist = {
'{{%s*[Ss]fn whitelist',
'{{%s*[Hh]arv whitelist',
}
local redirect_patterns_vcite = {
'{{%s*[Vv]cite',
'{{%s*[Vv]ancite',
-- '{{%s*[Cc]it ', -- disabled 'cit journal & cit paper' redirect to vcite journal but 'cit book', 'cit new', 'cit web' are cs1 redirects
}
local redirects_citation = {
['citation'] = true,
['cite'] = true,
['cite citation'] = true,
['cite study'] = true,
['cite technical standard'] = true,
}
local redirects_date = {
['date'] = true,
Line 37 ⟶ 11:
['isotomos'] = true,
}
local redirects_patent = { -- special case cs1-like templates because uses different parameters for name and date in anchor ID
local redirects_harvc = {
['harvcCite patent'] = true,
['citecCiteref patent'] = true,
['Ref patent'] = true,
}
local redirects_patent = {
['cite patent'] = true,
['citeref patent'] = true,
['ref patent'] = true,
}
local redirects_sfnref = {
Line 90 ⟶ 60:
'|%s*date%s*=%s*',
'|%s*publication%-?date%s*=%s*',
'|%s*air%-?date%s*=%s*',
}
local alias_patterns_harvc_date = { -- normal lua patterns for harvc template
Line 102 ⟶ 73:
}
local patterns_date = { -- normal lua patterns
-- '(%d%d%d%d–%d%d%d%d%l?)$', -- YYYY–YYYY four-digit year range at end (Season YYYY–YYYY); with or without dab
'(%d%d%d%d)%D+(%d%d%d%d%l?)$', -- any range with four-digit years; with or without dab; not two captures
'^(%d%d%d%d–%d%d%l?)$', -- YYYY–YY two-digit year range; with or without dab
'^(c%. %d%d%d%d?%l?)$', -- three- or four-digit circa year; with or without dab
Line 117 ⟶ 89:
'<source.->.-</source>', -- deprecated alias of syntaxhighlight tag
}
local template_skip = { -- templates to be skipped for whatever reason; mostly because they resemble cs1-like templates
local template_skip = {
['citationCitation-attribution'] = true,
}
local global_article_content = nil
local Article_content;
 
local global_anchor_id_list = nil -- exported tables
local global_template_list = nil
local global_article_whitelist = nil
 
 
 
--[[--------------------------< A R T I C L E _ C O N T E N T _ G E T >----------------------------------------
Line 130 ⟶ 108:
 
local function article_content_get ()
if global_article_content then return global_article_content end
if not Article_content then
Article_content local article_content = mw.title.getCurrentTitle():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
for _, tag in ipairs (patterns_tags) do
Article_content article_content = Article_contentarticle_content:gsub (tag, ''); -- remove certain html-like tags and their content
end
end
global_article_content = article_content
return article_content
end
 
Line 161 ⟶ 140:
while parts[i] and 7 > j do -- loop through what should be just positional parameters for names and year (2-6 four names and a date)
if not parts[i]:find ('=') then -- look for equal sign (named paraneter in a template that doesn't support named parameters)
anchor_id[j] = parts[i]; -- positional parameters are saved
j = j+1; -- bump the anchor_id{} indexer
end
Line 181 ⟶ 160:
 
local function date_get (template, aliases)
local date;
local rvalue;
 
Line 210 ⟶ 188:
if rvalue then
for _, pattern in ipairs (patterns_date) do -- spin through the recognized date formats
-- date = rvalue:match (pattern); -- attempt to extract year portion according to the pattern
local date, date2 = rvalue:match (pattern); -- attempt to extract year portion according to the pattern; <date2> gets second year in any range
if date then
if date2 then -- when a second year
date = table.concat ({date, '–', date2}); -- build a date range
end
return date; -- matched so return;
end
Line 349 ⟶ 331:
 
local function template_strip (template)
template = template:gsub ('^{{%s*', ''):gsub ('%s*}}$', '', 1); -- remove outer {{ and }} (cs1|2 template delimiters with trailing/leading whitespace)
template = template:gsub ('%b{}', ''); -- remove any templates from the cs1|2 template
return template;
Line 392 ⟶ 374:
end
 
--[[--------------------------< T E M P L A T E _ N A M E _ F R O M _ M O D U L E >----------------------------
 
if passed a module invocation, return the name of the template represented. Otherwise return the input.
 
{{#invoke:cite|foo|...}} or {{#invoke:cite bar||...}} will return "cite foo" and "cite bar", respectively.
 
]]
 
local function template_name_from_module (template, template_name)
if template_name and template_name:match ('^#invoke%s*:') then -- handle directly-invoked citation modules
template_name = template_name:match ('^#invoke%s*:%s*(.+)'); -- get module name
local func_name = template:match ('^{{[^|}]+%|%s*([^/|}]*)'); -- get function name
if template_name and func_name then -- valid module invocation
return template_name:gsub ('%s+$', '') .. ' ' .. func_name; -- ensure exactly one trailing whitespace between module and function name
end;
return nil -- could not get module and function name
end;
return template_name
end
 
--[[--------------------------< T E M P L A T E _ N A M E _ G E T >--------------------------------------------
Line 403 ⟶ 404:
 
local function template_name_get (template)
local template_name = template:match ('^{{%s*([^/|}]+)'); -- get template name; ignore subpages ~/new, ~/sandbox; parser functions
 
if not template_name then
template_name = template_name_from_module (template, template_name); -- if passed a module invocation, return the name of the template represented
if not template_name or template_name:match ('^#') then -- parser functions, magic words don't count as templates
return nil; -- could not get template name from (possibly corrupt) template; extraneous opening { mid template can cause this;
end;
template_name = template_name:gsub ('%s*$', ''); -- trim trailing whitespace; leading whitespace already removed
return Lang_obj:ucfirst (template_name); -- first character in template name must be uppercase (same as canonical template name) TODO: better way to do this?
template_name = template_name:lower(); -- and lowercase only
return template_name;
end
 
Line 420 ⟶ 423:
]]
 
local function template_params_get (template, paramsparams_t)
template = wikilink_strip (template); -- because piped wikilinks confuse code that builds paramsparams_t{} and because wikilinks not allowed in an anchor id
-- strip templates after getting |ref= value because |ref={{sfnref}} and |ref={{harvid}} are allowed
template = template_strip (template); -- because template markup can confuse code that builds paramsparams_t{} and because templates in name parameters are not allowed
 
templatelocal temp_t = mw.text.split (template:gsub, ('%s*|%s*|', '|'); --split when pipe follows pipe with or without white space, removeon extraneousthe pipe
for _, param in ipairs (temp_t) do
 
if param:find ('=', 1, true) then -- a named parameter?
for param, value in template:gmatch ('|%s*([^=]-)%s*=%s*([^|}]+)') do -- build a table of template parameters and their values
local k, v = param:match ('%s*([^=]-)%s*=%s*([^|}]+)');
if value then -- there must be a value but when
if v then -- there must be a value
if '' ~= valuev and not valuev:match ('^%s$') then -- skip when value is empty string or only whitespace
params params_t[paramk] = mw.text.trim (valuev); -- add trimmed value else
end
end
end
Line 444 ⟶ 449:
 
local function anchor_id_make_harvc (template)
local date = date_get (template, alias_patterns_harvc_date); -- get date; done here because might be in {{date}}; return date if valid; empty string else
local anchor_id;
local params = {}; -- table of harvc parameters
Line 460 ⟶ 465:
end
anchor_id = names_get (params, aliases_harvc_author); -- get the harvc contributor names
 
if anchor_id then -- if names were gotten
return 'CITEREF' .. anchor_id .. date;
end
Line 469 ⟶ 474:
 
 
--[[--------------------------< CA IN TC EH O R E_ FI D _ M A K E _ W R A P P E R >------------------------------------------------------
 
for wrapper templates
 
inspect externally visible |ref= to decide what to do:
|ref= - empty or missing: get names and date from whitelist defaults; override defaults from externally visible template parameters
|ref=harv - same as empty or missing
|ref={{SfnRef|name|name|name|name|year}} - assemble an anchor id from {{sfnref}} positional parameters
|ref={{Harvid|name|name|name|name|year}} - assemble an anchor id from {{harvid}} positional parameters
|ref=none - skip; do nothing because an anchor id intentionally suppressed; TODO: keep with a type code of '0'?
|ref=<text> - save param value because may match an anchor id override value in {{harv}} template |ref= parameter or {{harvc}} |id= parameter
 
]]
 
local function anchor_id_make_wrapper (template)
local ref; -- content of |ref=
local template_name; -- name of the template
local anchor_id; -- the assembled anchor id from this template
local date;
local name_default;
local date_default;
local vol;
local params = {}; -- table of template parameters
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
if not template_name or template_skip[template_name] then
return nil; -- could not extract template name from (possibly corrupted) template (extraneous opening { in the template will cause this)
end
 
date = date_get (template, alias_patterns_date); -- get date; done here because might be in {{date}}
-- if '' == date then
-- date = whitelist.wrapper_templates[template_name][2] or ''; -- no externally visible date so get default date
-- end
 
ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the wrapper template
if not ref then
if template:match ('|%s*ref%s*=([^|}]+)') then -- |ref={{template}} not found; if there is a |ref= param with an assigned value
ref = template:match ('|%s*ref%s*=([^|}]+)'); -- get the value; whitespace is a 'value'
if ref then -- nil when |ref=|... or when |ref=}} (no spaces between assignment operator and pipe or closing brace)
ref = mw.text.trim (ref); -- something, could be just whitespace, so trim leading / trailing whitespace
if '' == ref then -- trimming a string of whitespace makes an empty string
ref = nil; -- make empty ref same as missing ref
end
end
end
end
 
template_params_get (template, params); -- build a table of template parameters and their values
 
local wrap_data = whitelist.wrapper_templates[template_name]
 
if wrap_data[1] then -- is this wrapper a simple-default wrapper?
name_default = wrap_data[1]; -- get the default names
date_default = wrap_data[2]; -- get the default date
else
vol = params['volume'] or 'default';
local fascicle = params['fascicle'] -- some templates use "fascicle" to mean "subvolume"
if fascicle then
local subvol = vol..'/'..fascicle -- if fascicle is used, subvolume = "vol/fascicle"
if wrap_data[subvol] then -- if subvolume exists, use it, otherwise fall back to volume
vol = subvol
end
end
if not wrap_data[vol] then -- make sure this volume exists
vol = 'default'; -- doesn't exist, use default volume
end
name_default = wrap_data[vol][1]; -- get the default names
date_default = wrap_data[vol][2]; -- get the default date
end
 
if 'harv' == ref or not ref then -- |ref=harv specified or |ref= missing or empty
anchor_id = names_get (params, aliases_contributor) or -- get contributor, author, or editor names
names_get (params, aliases_author) or
vnames_get (params, 'vauthors') or -- |vauthors=
names_get (params, aliases_editor) or
vnames_get (params, 'veditors') or -- |veditors=
name_default; -- default names from whitelist
-- whitelist.wrapper_templates[template_name][1]; -- default names from whitelist
 
if '' == date then -- if date not provided in the template
date = date_default; -- use the default date from whitelist
end
 
if anchor_id then -- if names were gotten
anchor_id = 'CITEREF' .. anchor_id .. date;
end
 
elseif ref:match ('%b{}') then -- ref holds a template
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
 
elseif 'none' == ref then -- |ref=none
return nil; -- anchor id expicitly suppressed
else
anchor_id = ref; -- |ref=<text> may match an anchor id override value in {{harv}} template |ref= parameter
end
return anchor_id; -- anchor_id text; nil else
end
 
 
--[[--------------------------< A N C H O R _ I D _ M A K E _ C S 1 2 >----------------------------------------
 
for cs1|2 template and cs1-like templates
 
inspect |ref= to decide what to do:
|ref= - empty or missing: get names and date from template parameters because; all cs1|2 will soon create CITEREF anchor IDs
|ref=harv - get names and date from template parameters
|ref={{SfnRef|name|name|name|name|year}} - assemble an anchor id from {{sfnref}} positional parameters
Line 478 ⟶ 586:
|ref=none - skip; do nothing because an anchor id intentionally suppressed; TODO: keep with a type code of '0'?
|ref=<text> - save param value because may match an anchor id override value in {{harv}} template |ref= parameter or {{harvc}} |id= parameter
 
this no longer applies; all cs1|2 will soon create CITEREF anchor IDs
|ref= - empty or missing
for cs1: skip
if |mode=cs2: spoof |ref=harv
for cs2: get names and date from template parameters
if |mode=cs1: skip
 
]]
 
local function anchor_id_makeanchor_id_make_cs12 (template)
local ref; -- content of |ref=
local template_name; -- name of the template for cs2 detection
local anchor_id; -- the assembled anchor id from this template
local date;
local params = {}; -- table of cs1|2template parameters
template_name = template_name_get (template); -- get lowercasefirst char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
if not template_name or template_skip[template_name] then
return nil; -- could not extract template name from (possibly corrupted) template (extraneous opening { in the template will cause this)
Line 501 ⟶ 602:
 
if redirects_patent[template_name] then
date = date_get (template, alias_patterns_patent_date); -- get date; done here because might be in {{date}}
else
date = date_get (template, alias_patterns_date);
Line 517 ⟶ 618:
end
end
 
-- this disabled because all cs1|2 templates will create CITEREF anchor IDs after next cs1|2 module-suite update
-- if not ref then -- here when |ref= missing or empty
-- if redirects_citation[template_name] then -- could be cs2
-- if template:match ('|%s*mode%s*=%s*cs1') then
-- return nil; -- |ref= missing or empty; citation template but |mode=cs1
-- else
-- ref = 'harv'; -- spoof to handle cs2 as if it were cs1 with |ref=harv
-- end
-- else -- |ref= missing or empty; not a cs2 template
-- if template:match ('|%s*mode%s*=%s*cs2') then
-- ref = 'harv'; -- |ref= missing or empty; not a cs2 template; |mode=cs2; spoof as if it were cs1 with |ref=harv
-- end
-- end
-- end
end
 
template_params_get (template, params); -- build a table of template parameters and their values
 
if 'harv' == ref or not ref then -- |ref=harv notspecified set,or might|ref= bemissing citeor LSA which doesn't support |ref=empty
if 'cite lsa' == template_name then
return 'CITEREF' .. (params.last or '') .. (params.year or ''); -- cite LSA always creates an anchor id using only |last= and |year= (no aliases)
end
-- all cs1|2 templates will create CITEREF anchor IDs after next cs1|2 module-suite update so keep going
-- return nil; -- not cite LSA so done
end
 
if 'harv' == ref or not ref then -- |ref=harv specified or |ref= missing or empty (new cs1|2 default is not default for other templates handled here)
if redirects_patent[template_name] then -- if this is a cite patent template
anchor_id = names_get (params, aliases_inventor); -- inventor names only
Line 565 ⟶ 643:
return nil; -- anchor id expicitly suppressed
-- elseif '' ~= ref then -- ref is never empty string here -- |ref=<text>
else
anchor_id = ref; -- |ref=<text> may match an anchor id override value in {{harv}} template |ref= parameter
Line 576 ⟶ 653:
--[[--------------------------< L I S T _ A D D >--------------------------------------------------------------
 
adds an <item> to the <list> table; for anchor IDs, the boolean <encode> argument must be set true; no return value
 
]]
 
local function list_add (item, list, encode)
if item then -- if there was an anchor id extracteditem
if encode then -- for anchor IDs ...
item = mw.uri.anchorEncode (item); -- encode to remove wikimarkup, convert spaces to underscores etc
end
if not list[item] then -- if not already saved
list[item] = 1; -- save it
else -- here when this anchor iditem already saved
list[item] = list[item] + 1; -- to indicate that there are multiple same name/date citationsitems
end
end
Line 603 ⟶ 680:
 
local function anchor_id_make_anchor (template, anchor_id_list)
template = template:gsub ('^{{[^|]+|', ''):gsub ('}}$', '', 1); -- remove outer {{ and }} (anchorand template delimiters)name
 
template = template:gsub ('^[^|]+|', ''); -- remove template name and first pipe
template = wikilink_strip (template); -- strip any wikilink markup (there shouldn't be any but just in case)
Line 610 ⟶ 687:
local anchor_id;
for param in template:gmatch ('%b{}') do -- loop through the template; remove and save templates (presumed to be sfnref or harvid)
table.insert (params, param); -- save it
template = template:gsub ('%b{}', '', 1); -- remove it from source template
Line 617 ⟶ 694:
for _, t in ipairs (params) do -- spin through the templates in params
anchor_id = sfnref_get (t); -- attempt to decode {{sfnref}} and {{harvid}}
if anchor_id then -- nil when not {{sfnref}} andor {{harvid}}
list_add (anchor_id, anchor_id_list, true); -- add anchor ID to the list
end
Line 636 ⟶ 713:
 
 
--[[--------------------------< CA IN TC EH O R E_ I FD _ L I S T _ M A K E >--------------------------------------------
 
makes a list of anchor ids from cs1|2, cs1|2-like, vcite xxx, and harvc, anchor, wikicite templates
 
Because cs1|2 wrapper templates can, and often do, hide |ref=, the author and date parameters inside the wrapper,
these parameters are not available in the article's wikisource so {{harv}}, {{sfn}}, and {{harvc}} templates that
link correctly to those wrapper templates will incorrectly show error messages. Use |ignore-err=yes in the {{harv}},
{{sfn}}, and {{harvc}} templates to supress the error message.
 
creates a list of templates used in the article for use with the whitelist
 
creates a list of article-local whitelisted anchor IDs from {{sfn whitelist}}
 
]]
 
local function anchor_id_list_make ()
local anchor_id_list = {}
article_content_get (); -- attempt to get this article's content
local template_list = {}
local article_whitelist = {}
local article_content = article_content_get (); -- attempt to get this article's content
 
if ''article_content == Article_content'' then -- when there is no article content
return ''; -- no point in continuing
end
local template; -- place to hold the template that we found
local template_name;
local anchor_id; -- place to hold an anchor id as it is extracted / decoded
local tstart, tend = Article_content:find ('{{%s*[Cc]it[ae]'); -- find the first cs1|2-like template
 
local find_pattern = '%f[{]{{[^{]';
while tstart do -- nil when cs1|2 template not found
template local tstart, tend = Article_contentarticle_content:matchfind ('%b{}', tstartfind_pattern); -- getfind the wholefirst template; do not find template variables: {{{template var|}}}
 
while tstart do
if template then -- necessary?
anchor_idtemplate = anchor_id_makearticle_content:match (template'%b{}', tstart); -- extract an anchor idget fromthe thiswhole template
if not template then
list_add (anchor_id, anchor_id_list, true)
break; -- template is nil for some reason (last template missing closing }} for example) so declare ourselves done
end
template_name = template_name_get (template); -- get first char uppercase trimmed template name; ignore subpages ~/new, ~/sandbox
tstart = tend; -- reset the search starting index
list_add (template_name, template_list); -- add this template's name to the list
tstart, tend = Article_content:find ('{{%s*[Cc]it[ae]', tstart); -- search for another cs1|2 template
end
 
if data.known_templates_cs12 [template_name] then
for _, pattern in ipairs (redirect_patterns_harvc) do
tstart, tend anchor_id = Article_content:findanchor_id_make_cs12 (patterntemplate); -- findextract an anchor theid firstfrom harvcthis template
list_add (anchor_id, anchor_id_list, true)
 
while tstart do -- nil when harvc template not found
elseif data.known_templates_vcite [template_name] then
template = Article_content:match ('%b{}', tstart); -- get the whole template
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the vcite template
if templateref then -- necessary?|ref={{template}}
anchor_id = anchor_id_make_harvcsfnref_get (templateref); -- extractreturns ancontent anchorof id{{sfnref}} fromor {{harvid}}; thisnil templateelse
list_add (anchor_id, anchor_id_list, true);
endelse
local params = {};
tstart = tend; -- reset the search starting index
tstart, tend = Article_content:find (pattern, tstart); -- search for another harvc template
end
end
 
for _, pattern in ipairs (redirect_patterns_vcite) do -- for each of the vcite family template base patterns
tstart, tend = Article_content:find (pattern); -- find the first vcite template
while tstart do -- nil when vcite template not found
template = Article_content:match ('%b{}', tstart); -- get the whole template
if template then -- necessary?
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}} because we will strip templates from the vcite template
if ref then -- |ref={{template}}
anchor_id = sfnref_get (ref); -- returns content of {{sfnref}} or {{harvid}}; nil else
list_add (anchor_id, anchor_id_list, true);
else
local params = {};
local template_name = template_name_get (template); -- get lowercase trimmed template name; ignore subpages ~/new, ~/sandbox
 
template_params_get (template, params); -- build a table of template parameters and their values
 
anchor_id = params['ref']; -- when both set, vcite uses value from |ref=
if not anchor_id and params['harvid'] then
anchor_id = 'CITEREF' .. params['harvid']; -- in vcite, |harvid= auto-adds 'CITEREF' prefix to the value in |harvid=
end
list_add (anchor_id, anchor_id_list, true);
end
list_add (anchor_id, anchor_id_list, true);
end
 
elseif data.known_templates_harvc [template_name] then
tstart = tend; -- reset the search starting index
tstart, tendanchor_id = Article_content:findanchor_id_make_harvc (pattern, tstarttemplate); -- searchextract an anchor forid anotherfrom vcitethis template
list_add (anchor_id, anchor_id_list, true);
end
end
elseif data.known_templates_wikicite [template_name] then
tstart, tend = Article_content:find ('{{%s*[Ww]ikicite'); -- find the first {{wikicite}} template
 
while tstart do -- nil when cs1|2 template not found
template = Article_content:match ('%b{}', tstart); -- get the whole template
 
if template then
local ref = template:match ('|%s*ref%s*=%s*(%b{})'); -- first look for |ref={{sfnref}} or |ref={{harvid}}
Line 729 ⟶ 788:
elseif template:match ('|%s*id%s*=%s*(%b{})') then
anchor_idref = template:match ('|%s*id%s*=%s*(%b{})');
anchor_id = 'Reference-' .. sfnref_get (ref);
 
elseif template:match ('|%s*id%s*=([^|}]+)') then
anchor_id = 'Reference-' .. template:match ('|%s*id%s*=([^|}]+)'); -- plain-text
Line 741 ⟶ 801:
list_add (anchor_id, anchor_id_list, true);
end
end
tstart = tend; -- reset the search starting index
tstart, tend = Article_content:find ('{{%s*[Ww]ikicite', tstart); -- search for another cs1|2 template
end
for _, pattern in ipairs (redirect_patterns_anchor) do
tstart, tend = Article_content:find (pattern); -- find the first anchor template
while tstart do -- nil when anchor template not found
template = Article_content:match ('%b{}', tstart); -- get the whole template
if template then -- necessary?
anchor_id_make_anchor (template, anchor_id_list); -- extract anchor ids from this template if any
end
tstart = tend; -- reset the search starting index
tstart, tend = Article_content:find (pattern, tstart); -- search for another anchor template
end
end
 
elseif data.known_templates_anchor [template_name] then
anchor_id_make_anchor (template, anchor_id_list); -- extract anchor ids from this template if any
elseif data.known_templates_sfn_whitelist [template_name] then
template = template:gsub ('^{{[^|]+|', ''):gsub ('}}$', '', 1); -- remove outer {{ and }} and template name
template = mw.text.trim (template, '%s|'); -- trim leading trailing white space and pipes
template = mw.text.split (template, '%s*|%s*'); -- make a table of the template's parameters
 
for _, anchor_id in ipairs (template) do -- spin through this template's parameter
mw.logObject (anchor_id_list, 'anchor_id_list')
if '' ~= anchor_id and not article_whitelist[anchor_id] then
return anchor_id_list;
anchor_id = mw.uri.anchorEncode (anchor_id)
end
article_whitelist[anchor_id] = 1; -- add to the whitelist
end
end
 
elseif template_name and whitelist.wrapper_templates[template_name] then
anchor_id = anchor_id_make_wrapper (template); -- extract an anchor id from this template if possible
list_add (anchor_id, anchor_id_list, true);
 
--[[--------------------------< T E M P L A T E _ L I S T _ M A K E >------------------------------------------
elseif template_name and template_name:match ('^Cit[ea]') then -- not known, not known wrapper; last gasp, try as cs1-like
anchor_id = anchor_id_make_cs12 (template); -- extract an anchor id from this template if possible
list_add (anchor_id, anchor_id_list, true);
end
 
tstart, tend = article_content:find (find_pattern, tend); -- search for another template; begin at end of last search
makes a list of templates use in the article.
end
 
mw.logObject (anchor_id_list, 'anchor_id_list');
]]
mw.logObject (template_list, 'template_list');
mw.logObject (article_whitelist, 'article_whitelist');
 
local Lang_obj = mw.language.getContentLanguage();
 
global_anchor_id_list = anchor_id_list
local function template_list_make ()
global_template_list = template_list
article_content_get (); -- attempt to get this article's content
global_article_whitelist = article_whitelist
 
if '' == Article_content then -- when there is no article content
return ''; -- no point in continuing
end
 
local template_list = {};
for template in Article_content:gmatch ('{{%s*(.-)[|}]') do
if template and not template:match ('^#') then -- found a template or magic word; ignore magic words
template=mw.text.trim (template); -- trim whitespace
template = Lang_obj:ucfirst (template); -- first character in template name must be uppercase (same as canonical template name)
list_add (template, template_list); -- add to list with (unused) tally
end
end
mw.logObject (template_list, 'template_list')
return template_list;
end
 
--[[--------------------------< C I T E R E F _ P A T T E R N S _ M A K E >--------------------------------------------
 
Scans template_list to look for wrapper templates that generate citerefs that require Lua patterns.
--[[--------------------------< A R T I C L E _ L O C A L _ W H I T E L I S T _ M A K E >----------------------
 
This scan is only done once per page load, to save time
makes a list of templates use in the article.
 
]]
 
local function article_local_whitelist_make citeref_patterns_make()
if not global_template_list then return end
article_content_get (); -- attempt to get this article's content
local citeref_patterns = {}
 
local template_patterns = whitelist.wrapper_template_patterns
if '' == Article_content then -- when there is no article content
for _, p in ipairs(template_patterns) do
return ''; -- no point in continuing
for _, t in ipairs(p[1]) do -- loop through list of template wrappers
end
if global_template_list[t] then -- if wrapper is found in article, record corresponding patterns
 
for _, pat in ipairs(p[2]) do
local article_whitelist = {};
table.insert(citeref_patterns, pat)
local tstart, tend;
end
local template;
break
end
for _, pattern in ipairs (redirect_patterns_sfn_whitelist) do
end
tstart, tend = Article_content:find (pattern); -- find the first whitelist template
end
mw.logObject(citeref_patterns,'citeref_patterns')
while tstart do -- nil when whitelist template not found
return citeref_patterns
template = Article_content:match ('%b{}', tstart); -- get the whole template
if template then -- necessary?
template = template:gsub (pattern, ''):gsub ('}}$', '', 1); -- remove outer {{ and }} and template name
template = mw.text.trim (template, '%s|'); -- trim leading trailing white space and pipes
template = mw.text.split (template, '%s*|%s*'); -- make a table of the template's parameters
 
for _, anchor_id in ipairs (template) do -- spin through this template's parameter
if '' ~= anchor_id and not article_whitelist[anchor_id] then
article_whitelist[anchor_id] = 1; -- add to the whitelist
end
end
end
tstart = tend; -- reset the search starting index
tstart, tend = Article_content:find (pattern, tstart); -- search for another whitelist template
end
end
 
mw.logObject (article_whitelist, 'article_whitelist')
return article_whitelist;
end
 
Line 843 ⟶ 870:
]]
 
-- First create global_anchor_id_list, global_template_list, global_article_whitelist
anchor_id_list_make()
 
-- Then stuff them (and derived tables) into return table
return {
anchor_id_list = anchor_id_list_make()global_anchor_id_list or {}, -- table of anchor ids available in this article
article_whitelist = article_local_whitelist_make()global_article_whitelist or {}, -- table of anchor ids with false-positive error message to be suppressed
template_list = template_list_make()global_template_list or {}, -- table of templates used in this article
citeref_patterns = citeref_patterns_make() or {}, -- table of Lua patterns to search for citeref from wrappers
}