Module:Footnotes: Difference between revisions
From All Skies Encyclopaedia
imported>Trappist the monk synch from sandbox; |
imported>Trappist the monk consolidating and abandoning Template:Harvard citation/core; |
||
| Line 1: | Line 1: | ||
require('Module:No globals'); | |||
--[[--------------------------< A R G S _ D E F A U L T >------------------------------------------------------ | |||
a table to specify initial values. | |||
]] | |||
local args_default = { | |||
bracket_left = "", | |||
bracket_right = "", | |||
bracket_year_left = "", | |||
bracket_year_right = "", | |||
postscript = "", | |||
page = "", | |||
pages = "", | |||
location = "", | |||
page_sep = ", p. ", | |||
pages_sep = ", pp. ", | |||
ref = "", | |||
}; | |||
--[[--------------------------< I S _ Y E A R >---------------------------------------------------------------- | |||
evaluates param to see if it is one of these forms with or without lowercase letter disambiguator: | |||
YYYY | |||
n.d. | |||
nd | |||
c. YYYY | |||
YYYY–YYYY (separator is endash) | |||
return true when param has a recognized form; false else | |||
]] | |||
local function is_year (param) | local function is_year (param) | ||
| Line 32: | Line 40: | ||
function core( args ) | --[[--------------------------< C O R E >---------------------------------------------------------------------- | ||
returns an anchor link (CITEREF) formed from one to four author names, year, and insource location (|p=, |pp=, loc=) | |||
]] | |||
local function core( args ) | |||
local result; | local result; | ||
| Line 77: | Line 91: | ||
if args.ref ~= 'none' then | if args.ref ~= 'none' then | ||
if args.ref ~= | if args.ref ~= '' then | ||
result = | result = table.concat ({'[[#', mw.uri.anchorEncode (args.ref), '|', result, ']]'}); | ||
else | else | ||
result = | result = table.concat ({'[[#CITEREF', mw.uri.anchorEncode (table.concat ({args.P1, args.P2, args.P3, args.P4, args.P5})), '|', result, ']]'}); | ||
end | end | ||
end | end | ||
if args.page ~= | if args.page ~= '' then | ||
result = result | result = table.concat ({result, args.page_sep, args.page}); | ||
elseif args.pages ~= | elseif args.pages ~= ''then | ||
result = result | result = table.concat ({result, args.pages_sep, args.pages}); | ||
end | end | ||
if args.location ~= | if args.location ~= '' then | ||
result = result | result = table.concat ({result, ', ', args.location}); | ||
end | end | ||
| Line 98: | Line 112: | ||
end | end | ||
--[[--------------------------< A R G S _ F E T C H >--------------------------------------------------------- | |||
Because all of the templates share a common set of parameters, a single common function to fetch those parameters | |||
from frame and parent frame. | |||
]] | |||
function | local function args_fetch (frame, ps) | ||
local args = | local args = args_default; -- create a copy of the default table | ||
pframe = frame:getParent(); | local pframe = frame:getParent(); -- point to the template's parameter table | ||
args. | for k, v in pairs (frame.args) do -- override defaults with values provided in the #invoke: if any | ||
args. | args[k] = v; | ||
end | |||
args.postscript = pframe.args.postscript or pframe.args.ps or ps; | |||
if 'none' == args.postscript then | |||
args.postscript = ''; | |||
end | |||
args.page = pframe.args.p or pframe.args.page or ""; | args.page = pframe.args.p or pframe.args.page or ""; | ||
args.pages = pframe.args.pp or pframe.args.pages or ""; | args.pages = pframe.args.pp or pframe.args.pages or ""; | ||
args.location = pframe.args.loc or ""; | args.location = pframe.args.loc or ""; | ||
args.ref = pframe.args.ref or pframe.args.Ref or ""; | args.ref = pframe.args.ref or pframe.args.Ref or ""; | ||
for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- loop through the five positional parameters and trim if set else empty string | |||
args[v] = (pframe.args[i] and mw.text.trim (pframe.args[i])) or ""; | |||
end | |||
return | return args; | ||
end | end | ||
--[[--------------------------< H A R V A R D _ C I T A T I O N >---------------------------------------------- | |||
common entry point for: | |||
{{harvard citation}} aka {{harv}} | |||
{{Harvard citation no brackets}} aka {{harvnb}} | |||
{{harvcol}} | |||
{{harvcolnb}} | |||
{{harvcoltxt}} | |||
args | {{Harvard citation text}} aka {{harvtxt}} | ||
{{Harvp}} | |||
Distinguishing features (brackets and page separators) are specified in this module's {{#invoke}} in the respective templates. | |||
]] | |||
local function harvard_citation (frame) | |||
local args = args_fetch (frame, ''); -- get the template and invoke parameters; default postscript is empty string | |||
return core( args ); | return core (args); | ||
end | end | ||
function | |||
local | --[[--------------------------< S T R I P _ U R L >------------------------------------------------------------ | ||
for | |||
used only by sfn(). This function fixes an issue with reference tooltip gadget where the tooltip is not displayed | |||
when an insource locator (|p=, |pp=, |loc=) has an external wikilink that contains a # character | |||
strip uri-reserved characters from urls in |p=, |pp-, and |loc= parameters The researved characters are: | |||
!#$&'()*+,/:;=?@[] | |||
]] | |||
local function strip_url (pages) | |||
local escaped_uri; | |||
if not pages or ('' == pages) then | |||
return pages; | |||
end | |||
for uri in pages:gmatch ('%[(%a[%w%+%.%-]*://%S+)') do -- for each external link get the uri | |||
escaped_uri = uri:gsub ("([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); -- save a copy with lua pattern characters escaped | |||
uri = uri:gsub ("[!#%$&'%(%)%*%+,/:;=%?@%[%]%.]", ''); -- remove reserved characters | |||
pages = pages:gsub (escaped_uri, uri, 1); -- replace original uri with the stripped version | |||
end | end | ||
return pages; | |||
end | |||
--[[--------------------------< S F N >------------------------------------------------------------------------ | |||
entry point for {{sfn}} and {{sfnp}} | |||
]] | |||
local function sfn (frame) | |||
local args = args_fetch (frame, '.'); -- get the template and invoke parameters; default postscript is a dot | |||
args | |||
local result = core( args ); | local result = core (args); -- go make a CITEREF anchor | ||
-- put it all together and then strip redundant spaces | -- put it all together and then strip redundant spaces | ||
local name = table.concat ({'FOOTNOTE', args.P1, args.P2, args.P3, args.P4, args.P5, args.page, args.pages, args.location}):gsub ('%s+', ' '); | local name = table.concat ({'FOOTNOTE', args.P1, args.P2, args.P3, args.P4, args.P5, strip_url (args.page), strip_url (args.pages), strip_url (args.location)}):gsub ('%s+', ' '); | ||
return frame:extensionTag ({name='ref', args={name=name}, content=result}); | |||
end | end | ||
return | |||
--[[--------------------------< E X P O R T T A B L E >------------------------------------------------------ | |||
]] | |||
return { | |||
harvard_citation = harvard_citation, | |||
sfn = sfn, | |||
}; | |||
Revision as of 12:15, 11 August 2018
Documentation for this module may be created at Module:Footnotes/doc
require('Module:No globals');
--[[--------------------------< A R G S _ D E F A U L T >------------------------------------------------------
a table to specify initial values.
]]
local args_default = {
bracket_left = "",
bracket_right = "",
bracket_year_left = "",
bracket_year_right = "",
postscript = "",
page = "",
pages = "",
location = "",
page_sep = ", p. ",
pages_sep = ", pp. ",
ref = "",
};
--[[--------------------------< I S _ Y E A R >----------------------------------------------------------------
evaluates param to see if it is one of these forms with or without lowercase letter disambiguator:
YYYY
n.d.
nd
c. YYYY
YYYY–YYYY (separator is endash)
return true when param has a recognized form; false else
]]
local function is_year (param)
return param:match ('^%d%d%d%d?%l?$') or param:match ('^n%.d%.%l?$') or param:match ('^nd%l?$') or param:match ('^c%. %d%d%d%d?%l?$') or param:match ('^%d%d%d%d–%d%d%d%d%l?$');
end
--[[--------------------------< C O R E >----------------------------------------------------------------------
returns an anchor link (CITEREF) formed from one to four author names, year, and insource location (|p=, |pp=, loc=)
]]
local function core( args )
local result;
if args.P5 ~= "" then
if is_year (args.P5) then
result = table.concat ({args.P1, ' et al. ', args.bracket_year_left, args.P5, args.bracket_year_right});
else
args.P5 = ''; -- when P5 not a year don't include in anchor
result = table.concat ({args.P1, ' et al.'}); -- and don't render it
end
elseif args.P4 ~= "" then
if is_year (args.P4) then
result = table.concat ({args.P1, ', ', args.P2, ' & ', args.P3, ' ', args.bracket_year_left, args.P4, args.bracket_year_right}); -- three names and a year
else
result = table.concat ({args.P1, ' et al.'}); -- four names
end
elseif args.P3 ~= "" then
if is_year (args.P3) then
result = table.concat ({args.P1, ' & ', args.P2, ' ', args.bracket_year_left, args.P3, args.bracket_year_right}); -- two names and a year
else
result = table.concat ({args.P1, ', ', args.P2, ' ', ' & ', args.P3}); -- three names
end
elseif args.P2 ~= "" then
if is_year (args.P2) then
result = table.concat ({args.P1, ' ', args.bracket_year_left, args.P2, args.bracket_year_right}); -- one name and year
else
result = table.concat ({args.P1, ' & ', args.P2}); -- two names
end
else
result = args.P1; -- one name
end
-- when author-date result ends with a dot (typically when the last positional parameter holds 'n.d.')
-- and when no in-source location (no |p=, |pp=, or |loc=)
-- and when the first or only character in args.postscript is a dot
-- remove the author-date result trailing dot
-- the author-date result trailing dot will be replaced later with the content of args.postscript (usually a dot)
if ('.' == result:sub(-1)) and ('.' == args.postscript:sub(1)) and ('' == args.page) and ('' == args.pages) and ('' == args.location) then
result = result:gsub ('%.$', '');
end
if args.ref ~= 'none' then
if args.ref ~= '' then
result = table.concat ({'[[#', mw.uri.anchorEncode (args.ref), '|', result, ']]'});
else
result = table.concat ({'[[#CITEREF', mw.uri.anchorEncode (table.concat ({args.P1, args.P2, args.P3, args.P4, args.P5})), '|', result, ']]'});
end
end
if args.page ~= '' then
result = table.concat ({result, args.page_sep, args.page});
elseif args.pages ~= ''then
result = table.concat ({result, args.pages_sep, args.pages});
end
if args.location ~= '' then
result = table.concat ({result, ', ', args.location});
end
result = table.concat ({args.bracket_left, result, args.bracket_right, args.postscript}):gsub ('%s+', ' '); -- strip redundant spaces
return result;
end
--[[--------------------------< A R G S _ F E T C H >---------------------------------------------------------
Because all of the templates share a common set of parameters, a single common function to fetch those parameters
from frame and parent frame.
]]
local function args_fetch (frame, ps)
local args = args_default; -- create a copy of the default table
local pframe = frame:getParent(); -- point to the template's parameter table
for k, v in pairs (frame.args) do -- override defaults with values provided in the #invoke: if any
args[k] = v;
end
args.postscript = pframe.args.postscript or pframe.args.ps or ps;
if 'none' == args.postscript then
args.postscript = '';
end
args.page = pframe.args.p or pframe.args.page or "";
args.pages = pframe.args.pp or pframe.args.pages or "";
args.location = pframe.args.loc or "";
args.ref = pframe.args.ref or pframe.args.Ref or "";
for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do -- loop through the five positional parameters and trim if set else empty string
args[v] = (pframe.args[i] and mw.text.trim (pframe.args[i])) or "";
end
return args;
end
--[[--------------------------< H A R V A R D _ C I T A T I O N >----------------------------------------------
common entry point for:
{{harvard citation}} aka {{harv}}
{{Harvard citation no brackets}} aka {{harvnb}}
{{harvcol}}
{{harvcolnb}}
{{harvcoltxt}}
{{Harvard citation text}} aka {{harvtxt}}
{{Harvp}}
Distinguishing features (brackets and page separators) are specified in this module's {{#invoke}} in the respective templates.
]]
local function harvard_citation (frame)
local args = args_fetch (frame, ''); -- get the template and invoke parameters; default postscript is empty string
return core (args);
end
--[[--------------------------< S T R I P _ U R L >------------------------------------------------------------
used only by sfn(). This function fixes an issue with reference tooltip gadget where the tooltip is not displayed
when an insource locator (|p=, |pp=, |loc=) has an external wikilink that contains a # character
strip uri-reserved characters from urls in |p=, |pp-, and |loc= parameters The researved characters are:
!#$&'()*+,/:;=?@[]
]]
local function strip_url (pages)
local escaped_uri;
if not pages or ('' == pages) then
return pages;
end
for uri in pages:gmatch ('%[(%a[%w%+%.%-]*://%S+)') do -- for each external link get the uri
escaped_uri = uri:gsub ("([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); -- save a copy with lua pattern characters escaped
uri = uri:gsub ("[!#%$&'%(%)%*%+,/:;=%?@%[%]%.]", ''); -- remove reserved characters
pages = pages:gsub (escaped_uri, uri, 1); -- replace original uri with the stripped version
end
return pages;
end
--[[--------------------------< S F N >------------------------------------------------------------------------
entry point for {{sfn}} and {{sfnp}}
]]
local function sfn (frame)
local args = args_fetch (frame, '.'); -- get the template and invoke parameters; default postscript is a dot
local result = core (args); -- go make a CITEREF anchor
-- put it all together and then strip redundant spaces
local name = table.concat ({'FOOTNOTE', args.P1, args.P2, args.P3, args.P4, args.P5, strip_url (args.page), strip_url (args.pages), strip_url (args.location)}):gsub ('%s+', ' ');
return frame:extensionTag ({name='ref', args={name=name}, content=result});
end
--[[--------------------------< E X P O R T T A B L E >------------------------------------------------------
]]
return {
harvard_citation = harvard_citation,
sfn = sfn,
};





