Module:Harvc
Appearance
![]() | This module depends on the following other modules: |
![]() | This module uses TemplateStyles: |
Implements {{Harvc}}.
f = {
args_default = {
err_msg = '',
page_sep = ", p. ",
pages_sep = ", pp. ",
}
};
--[[--------------------------< I S _ S E T >------------------------------------------------------------------
Whether variable is set or not. A varable is set when it is not nil and not empty.
]]
function is_set( var )
return not (var == nil or var == '');
end
--[[--------------------------< C O R E >----------------------------------------------------------------------
Assembles the various parts provided by the template into a properly formatted bridging citation. Adds punctuation
and text; encloses the whole within a span with id and class attributes.
This creates a CITEREF anchor from |last1= through |last4= and |year=. It also creates a CITEREF link from |in1= through
|in4= and |year=. It is presumed that the dates of contributions are the same as the date of the enclosing work.
Even though not displayed, a year parameter is still required for the CITEREF anchor
]]
function core( args )
local span_open_tag; -- holds CITEREF and css
local contributors = ''; -- chapter or contribution authors
local source = ''; -- editor/author date list that forms a CITEREF link to a full citation; mimics harvnb output except year in parentheses
local in_text = ' In '; --
local result; -- the assemby of the above output
-- form the CITEREF anchor
if is_set (args.id) then
span_open_tag = '<span id="' .. args.id .. '" class="citation">'; -- for use when contributor name is same as source name
else
span_open_tag = '<span id="CITEREF' .. table.concat ({args.last1, args.last2, args.last3, args.last4, args.year}) .. '" class="citation">';
end
-- form the contributors list; similar to {{sfn}} and {{harv}}, 1 to 4 names but no date and also allows first contributor given name
if args.first ~= '' then
args.first = ', ' .. args.first;
end
if is_set (args.last4) and is_set (args.last3) and is_set (args.last2) and is_set (args.last1) then
contributors = args.last1 .. args.first .. ' et al.';
elseif not is_set (args.last4) and is_set (args.last3) and is_set (args.last2) and is_set (args.last1) then
contributors = args.last1 .. args.first .. ', ' .. args.last2 .. ' & ' .. args.last3;
elseif not is_set (args.last4) and not is_set (args.last3) and is_set (args.last2) and is_set (args.last1) then
contributors = args.last1 .. args.first .. ' & ' .. args.last2;
elseif not is_set (args.last4) and not is_set (args.last3) and not is_set (args.last2) and is_set (args.last1) then
contributors = args.last1 .. args.first;
else
args.err_msg = args.err_msg .. ' author missing from contributor list.';
end
--form the source author-date list
if is_set (args.in4) and is_set (args.in3) and is_set (args.in2) and is_set (args.in1) then
source = args.in1 .. ' et al.';
elseif not is_set (args.in4) and is_set (args.in3) and is_set (args.in2) and is_set (args.in1) then
source = args.in1 .. ', ' .. args.in2 .. ' & ' .. args.in3;
elseif not is_set (args.in4) and not is_set (args.in3) and is_set (args.in2) and is_set (args.in1) then
source = args.in1 .. ' & ' .. args.in2;
elseif not is_set (args.in4) and not is_set (args.in3) and not is_set (args.in2) and is_set (args.in1) then
source = args.in1;
else
args.err_msg = args.err_msg .. ' author missing from source list.'
end
if args.year:match('^[1-9]%d%d%d?%l?$') or args.year:match('^n%.d%.%l?$') or args.year:match('^nd%l?$') then -- 3 or 4 digits, n.d., or nd and optional disambiguator
source = source .. ' (' .. args.year .. ')';
else
args.err_msg = args.err_msg .. ' invalid or missing year.'; -- error message if year not provided or malformed
end
--assemble CITEREF wikilink
source = "[[#CITEREF" .. mw.uri.anchorEncode(table.concat ({args.in1, args.in2, args.in3, args.in4, args.year})) .. "|" .. source .. "]]";
--combine contribution with url to make external link
if args.url ~= '' then
args.contribution = '[' .. args.url .. ' ' .. args.contribution .. ']'; -- format external link
end
if args.separator ~= contributors:sub(-1) then
contributors = contributors .. args.separator; -- add separator if not same as last character in name list (|first=John S. or et al.)
end
-- pages and other insource location
if args.p ~= '' then
args.p = args.page_sep .. args.p;
elseif args.pp ~= '' then
args.p = args.pages_sep .. args.pp; -- args.p not set so use it to hold common insource location info
end
if args.loc ~= '' then
args.p = args.p .. ', ' .. args.loc; -- add arg.loc to args.p
end
--wrap error messages in span
args.err_msg = '<span style="font-size:100%" class="error">' .. args.err_msg .. '</span>';
if ',' == args.separator then
in_text = in_text:lower(); -- CS2 style use lower case
end
-- and put it all together
result = span_open_tag .. contributors .. ' "' .. args.contribution .. '"' .. args.separator .. in_text .. source .. args.p .. args.postscript .. '</span>' .. args.err_msg;
return result;
end
--[[--------------------------< F . H A R V C >----------------------------------------------------------------
Entry point from {{harvc}} template. Fetches parent frame parameters, does a bit of simple error checking
]]
function f.harvc (frame)
local args = f.args_default;
pframe = frame:getParent();
args.contribution = pframe.args.c or -- chapter or contribution
pframe.args.chapter or
pframe.args.contribution or '';
args.first = pframe.args.first or pframe.args.first1 or ''; -- (optional) first author's given name; given names for other authors not supported
args.id = pframe.args.id or '';
args.in1 = pframe.args['in'] or pframe.args.in1 or ''; -- source editor surnames; 'in' is a Lua reserved keyword
args.in2 = pframe.args.in2 or '';
args.in3 = pframe.args.in3 or '';
args.in4 = pframe.args.in4 or '';
args.last1 = pframe.args.last or pframe.args.last1 or ''; -- contribution author(s)
args.last2 = pframe.args.last2 or '';
args.last3 = pframe.args.last3 or '';
args.last4 = pframe.args.last4 or '';
args.p = pframe.args.p or ''; -- source page number(s) or location
args.pp = pframe.args.pp or '';
args.loc = pframe.args.loc or '';
args.separator = pframe.args.sep or pframe.args.separator; -- !! before postscript!! element separator defaults to full stop
args.postscript = pframe.args.ps or pframe.args.postscript;
if not is_set (args.postscript) then
if not is_set (args.separator) then
args.postscript = '.'; -- neither set so set to defaults
args.separator = '.';
elseif ',' == args.separator then
args.postscript = ''; -- CS2 and postscript not set; no terminal punctuation
else
args.postscript = '.'; -- separator not CS2 and postscript not set; use default terminal punctuation
end
else -- if here, postscript set
if 'none' == args.postscript:lower() then -- if |ps=none or |postscript=none then
args.postscript = ''; -- no postscript
end
end
if not is_set (args.separator) then
args.separator = '.'; -- not set in template and we didn't set it here so set to default
end
args.url = pframe.args.url or ''; -- url for chapter or contribution
args.year = pframe.args.year or '';
if not is_set (args.contribution) then
args.err_msg = args.err_msg .. ' required contribution is missing.'; -- error message if source not provided
args.contribution = args.url; -- if set it will give us linkable text
end
if args.last1 == args.in1 and
args.last2 == args.in2 and
args.last3 == args.in3 and
args.last4 == args.in4 and
not is_set (args.id) then
args.err_msg = args.err_msg .. ' required |id= parameter missing.'; -- error message if contributor and source are the same
end
return core (args);
end
--[[
function f.sfn( frame )
local args = f.args_default;
pframe = frame:getParent();
args.postscript = pframe.args.postscript or pframe.args.ps or ".";
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 "";
args.P1 = trim( pframe.args[1] ) or "";
args.P2 = trim( pframe.args[2] ) or "";
args.P3 = trim( pframe.args[3] ) or "";
args.P4 = trim( pframe.args[4] ) or "";
args.P5 = trim( pframe.args[5] ) or "";
local result = core( args );
local name = "FOOTNOTE" .. args.P1 .. args.P2 ..
args.P3 .. args.P4 .. args.P5 .. args.page .. args.pages .. args.location;
result = frame:extensionTag{ name = "ref", args = {name=name}, content=result };
return result;
end
]]
return f;