Module:Ref info: Difference between revisions
Appearance
Content deleted Content added
Significantly improve execution speed (collect a list of templates to avoid re-scanning the entire page many more times than needed; generally reduce calls to string manipulation functions like trim when not needed) |
←Blanked the page Tags: Blanking Reverted |
||
Line 1: | Line 1: | ||
-- This module counts the number of times that various reference tags and cs1|2 templates appear. |
|||
-- {{#invoke:ref_info|ref_info}} |
|||
-- {{ref info}} |
|||
-- {{ref info|aristotle}} |
|||
require('strict'); |
|||
local data = mw.loadData ('Module:Ref info/data'); |
|||
--mw.logObject (data.cs12_stripped_list, 'data.cs12_stripped_list') |
|||
local collapsible_tables = { |
|||
['cs1'] = '', -- collapsible wiki-tables of names and counts |
|||
['cs2'] = '', |
|||
['cs1_like'] = '', |
|||
['vcite'] = '', |
|||
['sfn'] = '', |
|||
['harv'] = '', |
|||
} |
|||
--[[--------------------------< T E M P L A T E _ N A M E _ T A B L E _ M A K E >------------------------------ |
|||
makes a collapsed html table that holds a list of cs1 or cs2 template used in an article. The list occupies a |
|||
single row of the parent table. |
|||
]] |
|||
local function template_name_table_make (name_list, group) |
|||
local name_table = {}; |
|||
local function comp (a, b) -- used in following table.sort() |
|||
return a:lower() < b:lower(); -- case-insensitive ascending alpha sort |
|||
end |
|||
table.insert (name_table, '\n|-\n|scope="row" colspan="2" style="vertical-align:top;text-align:left" |\n'); -- create a blank row in parent table for this table |
|||
table.insert (name_table, '{| class="mw-collapsible mw-collapsed nowrap" style="margin: 0.2em auto auto; width:100%;"\n') -- open the collapsed list table; style aligns show/hide toggle |
|||
table.insert (name_table, '| List of '); -- begin simple header row always displays |
|||
table.insert (name_table, group); -- template group (cs1, cs2 TODO: vcite? harv?) |
|||
table.insert (name_table, ' templates \n'); -- end of simple heading |
|||
table.insert (name_table, '|-\n|\n<hr /><ul>\n'); -- new row, row content begins with <hr />; open unordered list |
|||
local t = {}; |
|||
for k, v in pairs (name_list) do -- spin through the list |
|||
table.insert (t, string.format ('<li>%s (%s)</li>', k, v)) -- make pretty unordered list of name with count |
|||
end |
|||
if not t[1] then |
|||
return ''; -- nothing in the list so abandon |
|||
end |
|||
table.sort (t, comp); -- case-insensitive ascending alpha sort |
|||
table.insert (t, '</ul>\n'); -- close unordered list |
|||
table.insert (name_table, table.concat (t, '\n')); -- make a string and add to main table |
|||
table.insert (name_table, '\n|}'); -- close the table |
|||
return table.concat (name_table); -- return html table as a string |
|||
end |
|||
--[[--------------------------< C O L L E C T _ T E M P L A T E S >-------------------------------------------- |
|||
function to collect every template |
|||
]] |
|||
local function collect_templates (Article_content) |
|||
local template_list = {}; |
|||
local tstart, tend = Article_content:find ("{{%s*[^|}]+%s*[|}]"); -- find the first template |
|||
while tstart do -- nil when template not found |
|||
local template = Article_content:match ('%b{}', tstart); -- get the whole template |
|||
if template then |
|||
template_list[#template_list+1] = template |
|||
end |
|||
tstart = tend; -- reset the search starting index |
|||
tstart, tend = Article_content:find ("{{%s*[^|}]+%s*[|}]", tstart); -- search for another template |
|||
end |
|||
return template_list; |
|||
end |
|||
--[[--------------------------< C O U N T _ P A T T E R N >---------------------------------------------------- |
|||
this is a general purpose function used to count occurrences of <pattern> in <text> |
|||
]] |
|||
local function count_pattern (text, pattern) |
|||
local _; |
|||
local count; |
|||
_, count = mw.ustring.gsub (text, pattern, '%1'); |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ L A S T >-------------------------------------------------- |
|||
makes a count of those cs1|2 templates that use |last= or |last1= (or any of the selected aliases of these). |
|||
]] |
|||
local function count_cs1_last (template, count) |
|||
local _, tally; |
|||
for _, param in ipairs (data.last_param_patterns) do |
|||
_, tally = mw.ustring.gsub (template, '|%s*' .. param .. '%s*=%s*[^}|]', '%1'); -- count occurences of that pattern |
|||
count = count + tally; -- accumulate a total |
|||
end |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ A U T H O R >---------------------------------------------- |
|||
makes a count of those cs1|2 templates that use |author= or |author1= (or any of the selected aliases of these). |
|||
]] |
|||
local function count_cs1_author (template, count) |
|||
local _, tally; |
|||
for _, param in ipairs (data.author_param_patterns) do |
|||
_, tally = mw.ustring.gsub (template, '|%s*' .. param .. '%s*=%s*[^}|]', '%1'); -- count occurences of that pattern |
|||
count = count + tally; -- accumulate a total |
|||
end |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ A U T H O R S >-------------------------------------------- |
|||
makes a count of those cs1|2 templates that use |authors= (or any of the selected aliases). |
|||
]] |
|||
local function count_cs1_authors (template, count) |
|||
local _, tally; |
|||
for _, param in ipairs (data.authors_param_patterns) do |
|||
_, tally = mw.ustring.gsub (template, '|%s*' .. param .. '%s*=%s*[^}|]', '%1'); -- count occurences of that pattern |
|||
count = count + tally; -- accumulate a total |
|||
end |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ V A U T H O R S >------------------------------------------ |
|||
makes a count of those cs1|2 templates that use |vauthors=. |
|||
]] |
|||
local function count_cs1_vauthors (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*vauthors%s*=%s*[^}|]', '%1'); -- count occurences of that pattern |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ D A T E S _ D M Y >---------------------------------------- |
|||
Using the lists of cs1|2 templates, make a count of just those templates that have |date=DD Month YYYY where |
|||
DD is one or two digits or a range DD-DD Month YYYY |
|||
]] |
|||
local function count_cs1_dates_dmy (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*date%s*=%s*%d?%d%s+%a+%s+%d%d%d%d', '%1'); -- dd Month yyyy |
|||
count = count + tally; -- accumulate a total |
|||
_, tally = mw.ustring.gsub (template, '|%s*date%s*=%s*%d?%d[%-–]%d?%d%s+%a+%s+%d%d%d%d', '%1'); -- dd-dd Month yyyy |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ D A T E S _ M D Y >---------------------------------------- |
|||
Using the lists of cs1|2 templates, make a count of just those templates that have |date=Month DD, YYYY where |
|||
DD is one or two digits or a range Month DD-DD, YYYY |
|||
]] |
|||
local function count_cs1_dates_mdy (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*date%s*=%s*%a+%s+%d?%d%s*,%s+%d%d%d%d', '%1'); -- Month dd, yyyy |
|||
count = count + tally; -- accumulate a total |
|||
_, tally = mw.ustring.gsub (template, '|%s*date%s*=%s*%a+%s+%d?%d[%-–]%d?%d%s*,%s+%d%d%d%d', '%1'); -- Month dd-dd, yyyy |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ D A T E S _ Y M D >---------------------------------------- |
|||
Using the lists of cs1|2 templates, make a count of just those templates that have |date=YYYY-MM-DD |
|||
]] |
|||
local function count_cs1_dates_ymd (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*date%s*=%s*%d%d%d%d%-%d%d%-%d%d', '%1'); -- yyyy-mm-dd |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ D F _ D M Y >---------------------------------------------- |
|||
Using the lists of cs1|2 templates, make a count of just those templates that have |df=xxx (with a value) |
|||
]] |
|||
local function count_cs1_df_dmy (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*df%s*=%s*dmy%-?a?l?l?', '%1'); -- |df=dmy |df=dmy-all |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ D F _ M D Y >---------------------------------------------- |
|||
Using the lists of cs1|2 templates, make a count of just those templates that have |df=xxx (with a value) |
|||
]] |
|||
local function count_cs1_df_mdy (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*df%s*=%s*mdy%-?a?l?l?', '%1'); -- |df=mdy |df=mdy-all |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ D F _ Y M D >---------------------------------------------- |
|||
Using the lists of cs1|2 templates, make a count of just those templates that have |df=xxx (with a value) |
|||
]] |
|||
local function count_cs1_df_ymd (template, count) |
|||
local _, tally; |
|||
_, tally = mw.ustring.gsub (template, '|%s*df%s*=%s*ymd%-?a?l?l?', '%1'); -- |df=ymd |df=ymd-all |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 2 _ M O D E >-------------------------------------------------- |
|||
make a count of those cs1|2 templates that have |mode=cs1 or |mode=cs2 |
|||
]] |
|||
local function count_cs12_mode (template, count, mode) |
|||
local _, tally; |
|||
mode = 1 == mode and 'cs1' or 'cs2'; |
|||
_, tally = mw.ustring.gsub (template, '|%s*mode%s*=%s*' .. mode, '%1'); -- |mode=cs1 or |mode=cs2 |
|||
count = count + tally; -- accumulate a total |
|||
return count; |
|||
end |
|||
--[[--------------------------< C S 1 _ C S 2 _I N F O _ G E T >----------------------------------------------- |
|||
Using the list of cs1|2 templates, make a count of those templates. Make lists of cs1|2 templates used. Count |
|||
different author-name styles, date styles. |
|||
]] |
|||
local function cs1_cs2_info_get (template_list, pattern, template_name_list, object) |
|||
local total = 0; |
|||
for _, template in ipairs (template_list) do -- go through all cs1|2 like templates |
|||
if template:match("^" .. pattern) then |
|||
local name = template:match ('^{{%s*([^|}]-)%s*|'); -- get template name |
|||
if not template_name_list[name] then -- if not already saved |
|||
template_name_list[name] = 1; -- save it |
|||
else -- here when this name already saved |
|||
template_name_list[name] = template_name_list[name] + 1; -- to indicate that there are multiple same name templates |
|||
end |
|||
total = total + 1; -- tally total number of cs1 templates |
|||
-- count various date properties |
|||
object['cs1_dmy_dates']['count'] = count_cs1_dates_dmy (template, object['cs1_dmy_dates']['count']); -- count of |date=dmy |
|||
object['cs1_mdy_dates']['count'] = count_cs1_dates_mdy (template, object['cs1_mdy_dates']['count']); -- count of |date=mdy |
|||
object['cs1_ymd_dates']['count'] = count_cs1_dates_ymd (template, object['cs1_ymd_dates']['count']); -- count of |date=ymd |
|||
object['cs1_dates_df_dmy']['count'] = count_cs1_df_dmy (template, object['cs1_dates_df_dmy']['count']); -- count of |df=dmy |
|||
object['cs1_dates_df_mdy']['count'] = count_cs1_df_mdy (template, object['cs1_dates_df_mdy']['count']); -- count of |df=dmy |
|||
object['cs1_dates_df_ymd']['count'] = count_cs1_df_ymd (template, object['cs1_dates_df_ymd']['count']); -- count of |df=dmy |
|||
-- count various author-name properties |
|||
object['cs1_last']['count'] = count_cs1_last (template, object['cs1_last']['count']); -- count of |lastn= |
|||
object['cs1_author']['count'] = count_cs1_author (template, object['cs1_author']['count']); -- count of |authorn= |
|||
object['cs1_authors']['count'] = count_cs1_authors (template, object['cs1_authors']['count']); -- count of |authors= |
|||
object['cs1_vauthors']['count'] = count_cs1_vauthors (template, object['cs1_vauthors']['count']); -- count of |vauthors= |
|||
object['cs1_mode']['count'] = count_cs12_mode (template, object['cs1_mode']['count'], 1); -- count of |mode=cs1 |
|||
object['cs2_mode']['count'] = count_cs12_mode (template, object['cs2_mode']['count'], 2); -- count of |mode=cs2 |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 >------------------------------------------------------------ |
|||
Using the list of cs1 templates, make a count of just those templates as dictated by base_pattern. |
|||
makes a list of cs1 templates in the article |
|||
]] |
|||
local function count_cs1 (Article_content, base_pattern, object) |
|||
local pattern; |
|||
local total = 0; |
|||
local cs1_template_name_list = {}; |
|||
local templates = collect_templates (Article_content) |
|||
for i, cs1_template in ipairs (data.cs1_template_patterns) do |
|||
pattern = string.format (base_pattern, cs1_template); -- make a pattern for the selected cs1 template |
|||
total = total + cs1_cs2_info_get (templates, pattern, cs1_template_name_list, object); |
|||
end |
|||
collapsible_tables.cs1 = template_name_table_make (cs1_template_name_list, 'cs1'); |
|||
--mw.logObject (cs1_template_name_list, 'cs1_template_name_list') |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ R E F S >-------------------------------------------------- |
|||
Using the list of cs1 templates, make a count of just those references as dictated by base_pattern. |
|||
]] |
|||
local function count_cs1_refs (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.cs1_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected cs1 template |
|||
_, count = mw.ustring.gsub (text, pattern, '%1'); -- count occurences of that pattern |
|||
total = total + count; -- accumulate a total |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ L I K E _ T E M P L A T E S >------------------------------ |
|||
make a count of cs1-like templates as dictated by <pattern>. |
|||
]] |
|||
local function count_cs1_like_templates (Article_content, pattern) |
|||
local tstart, tend = Article_content:find (pattern); -- find the first cs1-like template |
|||
local total = 0; |
|||
local template_name_list = {}; |
|||
while tstart do -- nil when cs1-like template not found |
|||
local template = Article_content:match ('%b{}', tstart); -- get the template in the ref |
|||
if template then -- necessary? |
|||
local name = template:match ('{{%s*([^|}]-)%s*|'); -- get template name |
|||
name = name:gsub (' +', ' '); -- replace multiple space chars with a single char |
|||
if not data.cs12_stripped_list[name] then -- if not a cs1|2 template |
|||
if not template_name_list[name] then -- if not already saved |
|||
template_name_list[name] = 1; -- save it |
|||
else -- here when this name already saved |
|||
template_name_list[name] = template_name_list[name] + 1; -- to indicate that there are multiple same name templates |
|||
end |
|||
total = total + 1; -- tally total number of cs1-like templates |
|||
end |
|||
end |
|||
tstart = tend; -- reset the search starting index |
|||
tstart, tend = Article_content:find (pattern, tstart); -- search for another cs1|2 template |
|||
end |
|||
collapsible_tables.cs1_like = template_name_table_make (template_name_list, 'cs1-like'); |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 1 _ L I K E _ R E F S >---------------------------------------- |
|||
make a count of cs1-like references as dictated by <pattern>. |
|||
]] |
|||
local function count_cs1_like_refs (Article_content, pattern) |
|||
local tstart, tend = Article_content:find (pattern); -- find the first cs1-like template |
|||
local total = 0; |
|||
while tstart do -- nil when cs1-like reference not found |
|||
local template = Article_content:match ('%b{}', tstart); -- get the template in the ref |
|||
if template then -- necessary? |
|||
local name = template:match ('{{%s*([^|}]-)%s*|'); -- get template name |
|||
name = name:gsub (' +', ' '); -- replace multiple space chars with a single char |
|||
if not data.cs12_stripped_list[name] then -- if not a cs1|2 template |
|||
total = total + 1; -- tally total number of cs1-like references |
|||
end |
|||
end |
|||
tstart = tend; -- reset the search starting index |
|||
tstart, tend = Article_content:find (pattern, tstart); -- search for another cs1|2 template |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 2 >------------------------------------------------------------ |
|||
Using the list of cs2 templates, make a count of those templates as dictated by base_pattern. |
|||
make a list of cs2 templates in the article |
|||
]] |
|||
local function count_cs2 (Article_content, base_pattern, object) |
|||
local pattern; |
|||
local count, total = 0, 0; |
|||
local cs2_template_name_list = {}; |
|||
local templates = collect_templates (Article_content) |
|||
for i, cs2_template in ipairs (data.cs2_template_patterns) do |
|||
pattern = string.format (base_pattern, cs2_template); -- make a pattern for the selected cs2 template |
|||
total = total + cs1_cs2_info_get (templates, pattern, cs2_template_name_list, object); |
|||
end |
|||
collapsible_tables.cs2 = template_name_table_make (cs2_template_name_list, 'cs2'); |
|||
--mw.logObject (cs2_template_name_list, 'cs2_template_name_list') |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C S 2 _ R E F S >-------------------------------------------------- |
|||
Using the list of cs2 templates, make a count of those references as dictated by base_pattern. |
|||
]] |
|||
local function count_cs2_refs (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.cs2_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected cs1 template |
|||
_, count = mw.ustring.gsub (text, pattern, '%1'); -- count occurences of that pattern |
|||
total = total + count; -- accumulate a total |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ V C I T E >-------------------------------------------------------- |
|||
Using the list of vcite templates, make a count of just those templates as dictated by base_pattern. |
|||
makes a list of vcite templates in the article |
|||
]] |
|||
local function count_vcite (Article_content, base_pattern, object) |
|||
local _; |
|||
local pattern; |
|||
local total = 0; |
|||
local templates = collect_templates (Article_content) |
|||
local vcite_template_name_list = {}; |
|||
for i, vcite_template in ipairs (data.vcite_template_patterns) do |
|||
pattern = string.format (base_pattern, vcite_template); -- make a pattern for the selected vcite template |
|||
for _, template in ipairs (templates) do |
|||
if template:match ("^" .. pattern) then |
|||
local name = template:match ('^{{%s*([^|}]-)%s*|'); -- get template name |
|||
if not vcite_template_name_list[name] then -- if not already saved |
|||
vcite_template_name_list[name] = 1; -- save it |
|||
else -- here when this name already saved |
|||
vcite_template_name_list[name] = vcite_template_name_list[name] + 1; -- to indicate that there are multiple same name templates |
|||
end |
|||
total = total + 1; -- tally total number of vcite templates |
|||
end |
|||
end |
|||
end |
|||
collapsible_tables.vcite = template_name_table_make (vcite_template_name_list, 'vcite'); |
|||
--mw.logObject (vcite_template_name_list, 'vcite_template_name_list') |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ V C I T E _ R E F S >---------------------------------------------- |
|||
Using the list of cs1 templates, make a count of just those references as dictated by base_pattern. |
|||
]] |
|||
local function count_vcite_refs (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.vcite_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected vcite template |
|||
_, count = mw.ustring.gsub (text, pattern, '%1'); -- count occurences of that pattern |
|||
total = total + count; -- accumulate a total |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< S F N _ H A R V _I N F O _ G E T >--------------------------------------------- |
|||
Using the list of sfn and harv templates, make a count of those templates. Make lists of sfn and harv templates |
|||
used. |
|||
]] |
|||
local function sfn_harv_info_get (templates, pattern, template_name_list, object) |
|||
local total = 0; |
|||
for _, template in ipairs (templates) do |
|||
if template:match ("^" .. pattern) then |
|||
local name = template:match ('{{%s*([^|}]-)%s*|'); -- get template name |
|||
if not template_name_list[name] then -- if not already saved |
|||
template_name_list[name] = 1; -- save it |
|||
else -- here when this name already saved |
|||
template_name_list[name] = template_name_list[name] + 1; -- to indicate that there are multiple same name templates |
|||
end |
|||
total = total + 1; -- tally total number of templates |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ S F N >------------------------------------------------------------ |
|||
Using the list of sfn templates, make a count of just those templates as dictated by base_pattern. |
|||
makes a list of sfn templates in the article |
|||
]] |
|||
local function count_sfn (Article_content, base_pattern, object) |
|||
local _; |
|||
local pattern; |
|||
local total = 0; |
|||
local templates = collect_templates (Article_content) |
|||
local sfn_template_name_list = {}; |
|||
for i, sfn_template in ipairs (data.sfn_template_patterns) do |
|||
pattern = string.format (base_pattern, sfn_template); -- make a pattern for the selected template |
|||
total = total + sfn_harv_info_get (templates, pattern, sfn_template_name_list, object); |
|||
end |
|||
collapsible_tables.sfn = template_name_table_make (sfn_template_name_list, 'sfn'); |
|||
--mw.logObject (sfn_template_name_list, 'sfn_template_name_list') |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ H A R V >---------------------------------------------------------- |
|||
Using the list of harv templates, make a count of just those templates as dictated by base_pattern. |
|||
makes a list of harv templates in the article |
|||
]] |
|||
local function count_harv (Article_content, base_pattern, object) |
|||
local _; |
|||
local pattern; |
|||
local total = 0; |
|||
local templates = collect_templates (Article_content) |
|||
local harv_template_name_list = {}; |
|||
for i, harv_template in ipairs (data.harv_template_patterns) do |
|||
pattern = string.format (base_pattern, harv_template); -- make a pattern for the selected template |
|||
total = total + sfn_harv_info_get (templates, pattern, harv_template_name_list, object); |
|||
end |
|||
collapsible_tables.harv = template_name_table_make (harv_template_name_list, 'harv'); |
|||
--mw.logObject (harv_template_name_list, 'harv_template_name_list') |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ H A R V _ R E F S >------------------------------------------------ |
|||
Using the list of harv templates, make a count of those references as dictated by base_pattern. |
|||
]] |
|||
local function count_harv_refs (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.harv_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected cs1 template |
|||
_, count = mw.ustring.gsub (text, pattern, '%1'); -- count occurences of that pattern |
|||
total = total + count; -- accumulate a total |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ R E F B E G I N >-------------------------------------------------- |
|||
Using the list of cleanup templates, make a count of those templates as dictated by base_pattern. |
|||
]] |
|||
local function count_refbegin (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local template_list = collect_templates (text) |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.refbegin_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected template |
|||
for _, template in ipairs(template_list) do |
|||
if template:match ("^" .. pattern) then |
|||
total = total + 1 |
|||
end |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ R P >-------------------------------------------------------------- |
|||
Using the list of cleanup templates, make a count of those templates as dictated by base_pattern. |
|||
]] |
|||
local function count_rp (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local template_list = collect_templates (text) |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.rp_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected template |
|||
for _, template in ipairs(template_list) do |
|||
if template:match ("^" .. pattern) then |
|||
total = total + 1 |
|||
end |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ C L E A N U P >---------------------------------------------------- |
|||
Using the list of cleanup templates, make a count of those templates as dictated by base_pattern. |
|||
]] |
|||
local function count_cleanup (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local template_list = collect_templates (text) |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.cleanup_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected cleanup template |
|||
for _, template in ipairs(template_list) do |
|||
if template:match ("^" .. pattern) then |
|||
total = total + 1 |
|||
end |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ D E A D _ L I N K S >---------------------------------------------- |
|||
Using the list of dead link templates, make a count of those templates as dictated by base_pattern. |
|||
]] |
|||
local function count_dead_links (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local template_list = collect_templates (text) |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.dead_link_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected template |
|||
for _, template in ipairs(template_list) do |
|||
if template:match ("^" .. pattern) then |
|||
total = total + 1 |
|||
end |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< C O U N T _ W E B A R C H I V E >---------------------------------------------- |
|||
Using the list of webarchive aliases, make a count of those templates as dictated by base_pattern. |
|||
]] |
|||
local function count_webarchive (text, base_pattern) |
|||
local _; |
|||
local pattern; |
|||
local template_list = collect_templates (text) |
|||
local count, total = 0, 0; |
|||
for i, template in ipairs (data.webarchive_template_patterns) do |
|||
pattern = string.format (base_pattern, template); -- make a pattern for the selected template |
|||
for _, template in ipairs(template_list) do |
|||
if template:match ("^" .. pattern) then |
|||
total = total + 1 |
|||
end |
|||
end |
|||
end |
|||
return total; |
|||
end |
|||
--[[--------------------------< H A S _ L D R >---------------------------------------------------------------- |
|||
returns a string set to 'yes' if the article uses list defined references. ldr uses {{reflist |refs=...}} or |
|||
<references>...</references>. Here we do simple 'find's to make the determination. |
|||
It is also possible to do ldr with {{refbegin}} ... {{refend}} |
|||
the pattern value is passed to this function but ignored |
|||
]] |
|||
local function has_ldr (text) |
|||
local pattern; |
|||
for i, template in ipairs (data.reflist_template_patterns) do |
|||
pattern = string.format ('{{%%s*%s[^}]*|%%s*refs%%s*=%%s*[^}|]+', template); -- make a pattern using the selected reflist template |
|||
if mw.ustring.find (text, '{{%s*[Rr]eflist[^}]*|%s*refs%s*=%s*[^}|]+') then -- does page use {{Reflist |refs=...}}? |
|||
return 'yes' |
|||
end |
|||
end |
|||
if mw.ustring.find (text, '<references>[^<]+') then -- no reflist template, does page use <references>...</references>? |
|||
return 'yes' |
|||
else |
|||
return 'no'; |
|||
end |
|||
end |
|||
--[[--------------------------< H A S _ U S E _ X X X _ D A T E S >-------------------------------------------- |
|||
returns string set to either of 'dmy' or 'mdy' |
|||
TODO: needs companion |cs1-dates= support somehow ... 2 separate tests? one detects {{use xxx dates |cs1-dates=xx}} the other detects {{use xxx dates}}? |
|||
Also, detect conflicting |df= parameters? |
|||
]] |
|||
local global_df; |
|||
local function has_use_xxx_dates (text, pattern) |
|||
local ret_val = 'no'; -- presume not found |
|||
local df_template_patterns = { -- table of redirects to {{Use dmy dates}} and {{Use mdy dates}} |
|||
'{{ *[Uu]se (dmy) dates *[|}]', -- 915k -- sorted by approximate transclusion count |
|||
'{{ *[Uu]se *(mdy) *dates *[|}]', -- 161k |
|||
'{{ *[Uu]se (DMY) dates *[|}]', -- 2929 |
|||
'{{ *[Uu]se *(dmy) *[|}]', -- 250 + 34 |
|||
'{{ *([Dd]my) *[|}]', -- 272 |
|||
'{{ *[Uu]se (MDY) dates *[|}]', -- 173 |
|||
'{{ *[Uu]se *(mdy) *[|}]', -- 59 + 12 |
|||
'{{ *([Mm]dy) *[|}]', -- 9 |
|||
'{{ *[Uu]se (MDY) *[|}]', -- 3 |
|||
'{{ *([Dd]MY) *[|}]', -- 2 |
|||
'{{ *([Mm]DY) *[|}]', -- 0 |
|||
-- '{{ *[Uu]se(mdy) *[|}]', |
|||
-- '{{ *[Uu]se(mdy)dates *[|}]', |
|||
-- '{{ *[Uu]se(dmy) *[|}]', |
|||
} |
|||
for _, pattern in ipairs (df_template_patterns) do -- loop through the patterns looking for {{Use dmy dates}} or {{Use mdy dates}} or any of their redirects |
|||
local start, _, match = text:find(pattern); -- match is the three letters indicating desired date format |
|||
if match then |
|||
ret_val = match; -- set return value to the global date format |
|||
global_df = match; -- save for |df= tests |
|||
text = text:match ('%b{}', start); -- get the whole use xxx dates template |
|||
if text:match ('| *cs1%-dates *= *[lsy][sy]?') then -- look for |cs1-dates=publication date length access-/archive-date length |
|||
ret_val = ret_val .. ' [' .. text:match ('| *cs1%-dates *= *([lsy][sy]?)') .. ']'; |
|||
end |
|||
break; -- loop escape |
|||
end |
|||
end |
|||
return ret_val; |
|||
end |
|||
--[[--------------------------< O B J E C T S T A B L E >---------------------------------------------------- |
|||
Here we define various properties and values necessary to the counting of referencing objects |
|||
]] |
|||
local objects = { |
|||
['unnamed_refs'] = { -- count unnamed ref tags |
|||
['func'] = count_pattern, -- the function that does the work for this object |
|||
['pattern'] = '(<ref>)', -- a pattern that the function uses to find and count this object |
|||
['count'] = 0, -- the returned result (called count because that is the most common but can be 'yes' or 'no' etc |
|||
['label'] = 'unnamed refs' -- a label and markup for displaying the result; used with string.format() |
|||
}, |
|||
['named_refs'] = { -- count named ref tags |
|||
['func'] = count_pattern, |
|||
['pattern'] = '(<ref%s+name%s*=%s*[%a%d%p ]+>)', |
|||
['count'] = 0, |
|||
['label'] = 'named refs' |
|||
}, |
|||
['self_closed_refs'] = { -- count self closed ref tags |
|||
['func'] = count_pattern, |
|||
['pattern'] = '(<ref%s*name%s*=%s*["%a%d%p ]+/>)', |
|||
['count'] = 0, |
|||
['label'] = 'self closed' |
|||
}, |
|||
['r_templates'] = { -- count R templates (wrapper for self closed refs) |
|||
['func'] = count_pattern, |
|||
['pattern'] = '({{%s*[Rr]%s*|)', |
|||
['count'] = 0, |
|||
['label'] = 'R templates' |
|||
}, |
|||
['refn_templates'] = { -- count Refn templates |
|||
['func'] = count_pattern, |
|||
['pattern'] = '({{%s*[Rr]efn%s*|)', |
|||
['count'] = 0, |
|||
['label'] = 'Refn templates' |
|||
}, |
|||
['bare_url_refs'] = { -- count bare url refs |
|||
['func'] = count_pattern, -- TODO: separate function to detect protocol relative urls? |
|||
['pattern'] = '(<ref[^>]*>%s*http[^<%s]+%s*</ref>)', |
|||
['count'] = 0, |
|||
['label'] = '<span style="font-size:inherit" class="error">bare url refs</span>' |
|||
}, |
|||
['ext_link_refs'] = { -- count unlabeled external link refs |
|||
['func'] = count_pattern, -- TODO: separate function to detect protocol relative urls? |
|||
['pattern'] = '(<ref[^>]*>%[%s*http[^%]<%s]+%][^<]*</ref>)', |
|||
['count'] = 0, |
|||
['label'] = '<span style="font-size:inherit" class="error">bare ext link refs</span>' |
|||
}, |
|||
['cs1_like_refs'] = { -- count cs1 refs and refs that look like cs1 (cite something) |
|||
['func'] = count_cs1_like_refs, |
|||
['pattern'] = '(<ref[^>]*>[^<{]*{{%s*[Cc]ite%s+[^|]+)', |
|||
['count'] = 0, |
|||
['label'] = 'cs1-like refs' |
|||
}, |
|||
['cs1_refs'] = { -- count cs1 refs only |
|||
['func'] = count_cs1_refs, |
|||
['pattern'] = '(<ref[^>]*>[^<{]*{{%%s*%s%%s*|)', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'cs1 refs' |
|||
}, |
|||
['cs1_like_templates'] = { -- count templates that look like cs1 |
|||
['func'] = count_cs1_like_templates, |
|||
['pattern'] = '({{%s*[Cc]ite%s+[^|]+)', |
|||
['count'] = 0, |
|||
['label'] = 'cs1-like templates' |
|||
}, |
|||
['cs1_templates'] = { -- count cs1 templates only |
|||
['func'] = count_cs1, |
|||
['pattern'] = '({{%%s*%s%%s*|)', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'cs1 templates' |
|||
}, |
|||
['cs2_refs'] = { -- count cs2 refs |
|||
['func'] = count_cs2_refs, |
|||
['pattern'] = '(<ref[^>]*>[^<{]*{{%%s*%s%%s*|)', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'cs2 refs' |
|||
}, |
|||
['cs2_templates'] = { -- count cs2 templates |
|||
['func'] = count_cs2, |
|||
['pattern'] = '{{%%s*%s%%s*|', |
|||
['count'] = 0, |
|||
['label'] = 'cs2 templates' |
|||
}, |
|||
['vcite_refs'] = { -- count vancite, vcite, and vcite2 refs |
|||
-- ['func'] = count_pattern, |
|||
-- ['pattern'] = '(<ref[^>]*>[^<{]*{{%s*[Vv]a?n?cite2?%s+[^|]+)', |
|||
['func'] = count_vcite_refs, |
|||
['pattern'] = '(<ref[^>]*>[^<{]*{{%%s*%s%%s*|)', |
|||
['count'] = 0, |
|||
['label'] = 'vcite refs' |
|||
}, |
|||
['vcite_templates'] = { -- count vancite templates |
|||
['func'] = count_vcite, |
|||
['pattern'] = '{{%%s*%s%%s*|', |
|||
-- ['func'] = count_pattern, |
|||
-- ['pattern'] = '({{%s*[Vv]a?n?cite2?%s+[^|]+)', |
|||
['count'] = 0, |
|||
['label'] = 'vcite templates' |
|||
}, |
|||
['wikicite_templates'] = { -- count wikicite templates |
|||
['func'] = count_pattern, |
|||
['pattern'] = '({{%s*[Ww]ikicite%s*|)', |
|||
['count'] = 0, |
|||
['label'] = 'wikicite templates' |
|||
}, |
|||
['harv_refs'] = { -- count harv refs |
|||
['func'] = count_harv_refs, |
|||
['pattern'] = '(<ref[^>]*>[^<{]*{{%%s*%s%%s*|)', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'harv refs' |
|||
}, |
|||
['harv_templates'] = { -- count harv templates |
|||
['func'] = count_harv, |
|||
['pattern'] = '({{%%s*%s%%s*|)', |
|||
['count'] = 0, |
|||
['label'] = 'harv templates' |
|||
}, |
|||
['sfn_templates'] = { -- count sfn templates |
|||
['func'] = count_sfn, |
|||
['pattern'] = '({{%%s*%s%%s*|)', |
|||
['count'] = 15, |
|||
['label'] = 'sfn templates' |
|||
}, |
|||
['rp_templates'] = { -- count rp templates |
|||
['func'] = count_rp, |
|||
['pattern'] = '({{%%s*%s%%s*[|}])', |
|||
['count'] = 0, |
|||
['label'] = 'rp templates' |
|||
}, |
|||
['ldr'] = { -- does this article use list defined references? |
|||
['func'] = has_ldr, |
|||
['pattern'] = '', -- uses multiple patterns which are defined in the function |
|||
['count'] = 'no', |
|||
['label'] = 'uses ldr' |
|||
}, |
|||
['refbegin_templates'] = { -- count refbegin templates - bibliography lists |
|||
['func'] = count_refbegin, |
|||
['pattern'] = '({{%%s*%s%%s*[|}])', |
|||
['count'] = 0, |
|||
['label'] = 'refbegin templates' |
|||
}, |
|||
['cleanup_templates'] = { -- count cleanup templates |
|||
['func'] = count_cleanup, |
|||
['pattern'] = '({{%%s*%s%%s*[|}])', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'cleanup templates' |
|||
}, |
|||
['dead_link_templates'] = { -- count deadlink templates (includes redirects) |
|||
['func'] = count_dead_links, |
|||
['pattern'] = '({{%%s*%s%%s*[|}])', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'dead link templates' |
|||
}, |
|||
['webarchive_templates'] = { -- count webarchive templates (includes redirects) |
|||
['func'] = count_webarchive, |
|||
['pattern'] = '({{%%s*%s%%s*|)', -- will be modified in the func by string.format() |
|||
['count'] = 0, |
|||
['label'] = 'webarchive templates' |
|||
}, |
|||
['use_xxx_dates'] = { -- does this article use list defined references? |
|||
['func'] = has_use_xxx_dates, |
|||
['pattern'] = nil, -- uses multiple patterns that are defined in the function |
|||
['count'] = 'no', |
|||
['label'] = 'use xxx dates' |
|||
}, |
|||
['cs1_dates_df_dmy'] = { -- count |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 df dmy' |
|||
}, |
|||
['cs1_dates_df_mdy'] = { -- count |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 df mdy' |
|||
}, |
|||
['cs1_dates_df_ymd'] = { -- count |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 df ymd' |
|||
}, |
|||
['cs1_dmy_dates'] = { -- count cs1 templates only |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 dmy dates' |
|||
}, |
|||
['cs1_mdy_dates'] = { -- count cs1 templates only |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 mdy dates' |
|||
}, |
|||
['cs1_ymd_dates'] = { -- count cs1 templates only |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 ymd dates' |
|||
}, |
|||
['cs1_last'] = { -- count cs1 templates only |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 last/first' |
|||
}, |
|||
['cs1_author'] = { -- count cs1 templates only |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 author' |
|||
}, |
|||
['cs1_authors'] = { -- count cs1 templates only |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 authors' |
|||
}, |
|||
['cs1_vauthors'] = { |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1|2 vauthors' |
|||
}, |
|||
['cs1_mode'] = { |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs1 mode' |
|||
}, |
|||
['cs2_mode'] = { |
|||
['func'] = nil, -- handled by cs1_cs2_info_get() |
|||
['pattern'] = nil, |
|||
['count'] = 0, |
|||
['label'] = 'cs2 mode' |
|||
}, |
|||
} |
|||
-- here we set the order in which the objects are processed |
|||
local teaser_order = {'unnamed_refs', 'named_refs', 'self_closed_refs'} -- for use by {{ref info banner}} to create its 'teaser' when |_teaser=yes |
|||
local order = {'unnamed_refs', 'named_refs', 'self_closed_refs', -- these three are always output |
|||
'r_templates', -- this and the others only produce output when ... |
|||
'refn_templates', -- ... their count is not 0 or not 'no' |
|||
'bare_url_refs', |
|||
'ext_link_refs', |
|||
'cs1_refs', |
|||
'cs1_templates', |
|||
'cs1_like_refs', |
|||
'cs1_like_templates', |
|||
'cs2_refs', |
|||
'cs2_templates', |
|||
'vcite_refs', 'vcite_templates', |
|||
'wikicite_templates', |
|||
'harv_refs', 'harv_templates', |
|||
'sfn_templates', |
|||
'rp_templates', |
|||
'ldr', |
|||
'refbegin_templates', |
|||
'cleanup_templates', |
|||
'dead_link_templates', |
|||
'webarchive_templates', |
|||
'use_xxx_dates', |
|||
'cs1_dates_df_dmy', |
|||
'cs1_dates_df_mdy', |
|||
'cs1_dates_df_ymd', |
|||
'cs1_dmy_dates', |
|||
'cs1_mdy_dates', |
|||
'cs1_ymd_dates', |
|||
'cs1_last', |
|||
'cs1_author', |
|||
'cs1_authors', |
|||
'cs1_vauthors', |
|||
'cs1_mode', |
|||
'cs2_mode', |
|||
}; |
|||
--[[--------------------------< R E F _ I N F O >-------------------------------------------------------------- |
|||
the working part of Template:Ref info |
|||
]] |
|||
local function ref_info (frame) |
|||
local text; -- unparsed page content |
|||
local title; -- page title without namespace or interwiki references |
|||
local nstitle; -- page title with namespace and interwiki references |
|||
local page_title_object; -- |
|||
local output = {}; |
|||
local i=1; |
|||
local style = frame.args.style or ''; -- styling css for output table |
|||
if frame.args[1] then |
|||
page_title_object = mw.title.new(frame.args[1]); -- title object for the page specified in the template call |
|||
else |
|||
page_title_object = mw.title.getCurrentTitle(); -- title object for the current page |
|||
end |
|||
text = page_title_object:getContent(); -- the unparsed content of the selected page |
|||
if nil == text then |
|||
return string.format ('<span style="font-size:100%%" class="error">{{ref info}} – page is empty or does not exist: %s</span>', frame.args[1] or 'no page'); |
|||
end |
|||
--error (mw.dumpObject (frame:getParent().args)) |
|||
text = require('Module:Wikitext Parsing').PrepareText(text) -- escape the content of nowiki tags/html comments |
|||
nstitle = page_title_object.prefixedText; -- the title of the page (with namespace) |
|||
title = page_title_object.text; -- the title of the page (without namespace) |
|||
if 'yes' == frame:getParent().args._teaser then |
|||
for _, object in ipairs (teaser_order) do -- loop through teaser_order sequence and search for the related objects |
|||
if objects[object].func then |
|||
objects[object].count = objects[object].func (text, objects[object].pattern, objects) -- do the search and store the result |
|||
end |
|||
end |
|||
objects['named_refs'].count = objects['named_refs'].count - objects['self_closed_refs'].count; |
|||
for _, object in ipairs (teaser_order) do -- loop through order and search for the related objects |
|||
table.insert (output, string.format ('%s = %s', objects[object].label, objects[object].count)); |
|||
end |
|||
return table.concat (output, '; '); |
|||
end |
|||
for i, object in ipairs (order) do -- loop through order and search for the related objects |
|||
if objects[object].func then |
|||
objects[object].count = objects[object].func (text, objects[object].pattern, objects) -- do the search and store the result |
|||
end |
|||
end |
|||
-- for those that count duplicates remove the duplicates from the counts |
|||
objects['named_refs'].count = objects['named_refs'].count - objects['self_closed_refs'].count; |
|||
table.insert (output, string.format ('{| class="wikitable" style="text-align:right; %s"\n|+reference info for [[%s|%s]]', style, nstitle, title)); -- output table header |
|||
for i, object in ipairs (order) do -- loop through order and search for the related objects |
|||
if i<=3 then -- first three (reference tags) are always output |
|||
table.insert (output, string.format ('%s\n|%s', objects[object].label, objects[object].count)); |
|||
elseif 'string' == type (objects[object].count) then -- objects[object].count can be a string or a number |
|||
if 'no' ~= objects[object].count then -- if a string and not 'no' ... |
|||
table.insert (output, string.format ('%s\n|%s', objects[object].label, objects[object].count)); -- output the result |
|||
end |
|||
elseif 'number' == type (objects[object].count) then -- if a number ... |
|||
if 0 < objects[object].count then -- ... and count is greater than zero ... |
|||
table.insert (output, string.format ('%s\n|%s', objects[object].label, objects[object].count)); -- ... output the result |
|||
end |
|||
end |
|||
end |
|||
output = {table.concat (output,'\n|-\n! scope="row" | ')}; -- concat an intermediate result |
|||
table.insert (output, collapsible_tables.cs1); -- add the collapsible tables |
|||
table.insert (output, collapsible_tables.cs2); |
|||
table.insert (output, collapsible_tables.cs1_like); |
|||
table.insert (output, collapsible_tables.vcite); |
|||
table.insert (output, collapsible_tables.sfn); |
|||
table.insert (output, collapsible_tables.harv); |
|||
table.insert (output, '\n|-\n|scope="row" colspan="2" style="text-align:center"|[[Template:Ref_info#Output_meanings|explanations]]\n|-\n|}'); |
|||
return table.concat (output); |
|||
end |
|||
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ |
|||
]] |
|||
return { |
|||
ref_info = ref_info, |
|||
} |