Jump to content

Module:Harvc

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Trappist the monk (talk | contribs) at 11:41, 8 November 2014 (no date: n.d. or nd;). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

f = {
	args_default = {
		err_msg = '',
		page_sep = ", p. ",
		pages_sep = ", pp. ",
	}
};

--[[--------------------------< T R I M >----------------------------------------------------------------------

strip leading and trailing white space from positional parameters.

]]

function trim( str )
	if str == nil then
		return '';
	end
	return str:match( "^%s*(.-)%s*$");
end    


--[[--------------------------< I S _ S E T >------------------------------------------------------------------

Whether variable is set or not

]]

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 function mimics the {{sfn}} and {{harv}} templates, but it does not display an author-date list, just an
author list.  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	
	span_open_tag = '<span id="CITEREF' .. table.concat ({args.last1, args.last2, args.last3, args.last4, args.year}) .. '" class="citation">'
 
 -- 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 is_set (args.last3) and is_set (args.last2) and is_set (args.last1) then
		contributors = args.last1 .. args.first .. ', ' .. args.last2 .. ' &amp; ' .. args.last3;
	elseif is_set (args.last2) and is_set (args.last1) then
		contributors = args.last1 .. args.first .. ' &amp; ' .. args.last2;
	elseif 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 is_set (args.in3) and is_set (args.in2) and is_set (args.in1) then
		source = args.in1 .. ', ' .. args.in2 .. ' &amp; ' .. args.in3;
	elseif is_set (args.in2) and is_set (args.in1) then
		source = args.in1 .. ' &amp; ' .. args.in2;
	elseif 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.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.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
--		args.url='';															-- if no contribution set url to empty string so we don't link the error message
	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;