什么是黄色视频| 孔子名什么| 10月1是什么星座| 这叫什么| 痉挛是什么意思啊| 敏五行属什么| 看肾挂什么科| 一直很困想睡觉是什么原因| 血沉是查什么| 老年性阴道炎用什么药| 双鱼座女和什么星座最配| 马云是什么大学毕业的| 长期咳白痰是什么原因| 抓包是什么意思| 耳朵里面疼用什么药| lz什么意思| 轰20什么时候首飞| nt值代表什么| 三伏贴什么时候贴最好| 簸箕是什么| 甲骨文是写在什么上面的| 农历5月是什么星座| 为什么女人比男人长寿| 男宠是什么意思| 生完孩子吃什么补身体| 柿子不能和什么食物一起吃| 拌黄瓜需要什么调料| 肚子疼一般是什么原因| 双肾囊肿有什么危害| 内伤是什么意思| aigle是什么牌子| 为什么小便会带血| 贫血有什么症状| 肝衰竭是什么原因引起的| 鹅口疮有什么症状| 食粉是什么粉| 湖北九头鸟是什么意思| 心绞痛吃什么药| 美容美体是干什么的| 什么的蹦跳| 经常吃紧急避孕药有什么危害| 肾透析是什么意思| 叔叔老婆叫什么| 什么叫白内障| 印是什么意思| 孕妇吃什么水果好对胎儿好| 如家是什么内涵| 吃夏枯草有什么副作用| 竹字头均念什么名字| 梦到和男朋友分手是什么征兆| 风湿三项检查是什么| kodak是什么牌子| 什么牌子的山地车好骑又不贵| 财源广进是什么生肖| 我要控制我自己是什么歌| 什么是锆石| 天降横财什么意思| 湿气重用什么泡脚最好| 女生的隐私部位长什么样| 梦见床是什么意思| 什么瓜不能吃| 大面积杀跳蚤用什么药| 退行性变是什么意思| okr是什么| 脚趾第二个比第一个长有什么说法| 做梦梦见自己生孩子是什么意思| 医调委是什么机构| 面部肌肉跳动是什么原因| 米非司酮片是什么药| 梨涡是什么意思| 木加号读什么| 04年的猴是什么命| 1997年7月1日属什么生肖| 麦麸是什么意思| 血包是什么意思| 头胀痛什么原因| kda什么意思| 什么而不舍| 卵巢早衰是什么引起的| 补钙什么时间段最好| 男人喝什么酒壮阳最快| 磨牙是什么原因引起的| 手肿脚肿是什么原因引起的| 二哥是什么意思| 手心红是什么原因| 男性尿频尿急吃什么药| 什么可以误诊为畸胎瘤| 什么望外| 巡演是什么意思| 小龙虾吃什么| 情愫什么意思| 纸可以做什么| 肾病有什么症状| 下腹隐隐作痛什么原因| 宝宝咬人是什么原因| 为什么一般不检查小肠| 便是什么意思| 男人血精是什么原因造成的| 对宫星座是什么意思| 多糖是什么意思| 眼底出血是什么原因造成的| 便秘吃什么食物好| 幽门梗阻是什么意思| tc版是什么意思| 什么水| 孕妇白细胞高是什么原因| 员级职称是什么意思| 男人吃蚂蚱有什么好处| 喜欢一个人是什么感觉| 中位生存期什么意思| 蚂蚁长什么样子| 炒菜用什么锅好| 九月28号是什么星座| 小儿急性喉炎吃什么药| 只是女人容易一往情深是什么歌| 舟状腹见于什么疾病| 公务员干什么工作| 煎中药用什么容器最好| 生吃苦瓜有什么好处和坏处| 脚后跟疼什么原因| 惨无人道是什么意思| 单活胎是什么意思| C反应蛋白高是什么原因| 胀气打嗝是什么原因| 小孩子包皮挂什么科| 58年属什么今年多大| 为什么读研| 节育环嵌顿是什么意思| 还愿有什么讲究| 右耳朵痒是什么预兆| 乳头痒什么原因| 晴纶是什么材质| 梭织是什么意思| 养殖业什么最赚钱农村| 梦见骆驼是什么意思| 海参和辽参有什么区别| 谷草谷丙低是什么原因| 湿气重吃什么水果| 河汉是什么意思| dic是什么意思| 头孢长什么样| 口字五行属什么| 起酥油是什么东西| 婴儿枕头里面装什么好| 副肾是什么药名| 1号来月经什么时候是排卵期| 胸片可以检查出什么| 左眼皮老是跳是什么原因| 梦见舅舅是什么意思| 甲醛超标有什么反应| 茜是什么意思| 清油是什么油| 为什么叫基围虾| 什么的角| 想吃咸的是身体缺什么| 糖耐筛查主要检查什么| eb是什么| 备孕吃什么最容易怀孕| 锁阳泡酒有什么功效| 血糖吃什么水果| 扶苏是什么意思| 巾帼不让须眉是什么意思| 浮萍是什么| 宝宝多吃什么蔬菜好| 打2个喷嚏代表什么| 棍子鱼又叫什么鱼| 一 什么云| 4月10日什么星座| 农历11月18日是什么星座| 规格什么意思| 书生是什么意思| 农历9月11日是什么星座| 梦见龙卷风是什么预兆| 卤什么东西好吃| 女性尿酸低是什么原因| u是什么单位| 来大姨妈喝什么汤比较好| 私处为什么会发黑| 碳14呼气试验阳性是什么意思| 加拿大签证需要什么材料| 蚊子喜欢叮什么样的人| 桥本甲状腺炎有什么症状| 隐翅虫咬了用什么药| 蛇鼠一窝指什么生肖| 在什么前面用英语怎么说| 平诊是什么意思| 女性尿道炎挂什么科| 骨痂是什么意思| 娘是什么意思| 人做梦是什么原因| 灵隐寺求什么最灵验| 医生五行属什么| 梦见红薯是什么意思| 西夏是现在的什么地方| 石斛有什么功效和作用| 肝占位是什么意思| 抗美援朝什么时候结束| 吃榴莲不能和什么一起吃| 为什么叫| 囡囡是什么意思| vc是什么| dan是什么意思| 水马是什么| 排卵日是什么意思| 创面是什么意思| 妇科凝胶排出的是什么| 理工男是什么意思啊| 十点半是什么时辰| 哔哩哔哩是干什么的| 女性漏尿吃什么药最好| 安哥拉树皮有什么功效| 洋葱什么时候种| 喉咙痛吃什么药好| 吃葱有什么好处和坏处| 脸上老长痘痘是什么原因| 斜率是什么| 枸杞和红枣泡水喝有什么好处| 判决书什么时候生效| 头发定型用什么好| 女朋友过生日送什么最好| 走之旁与什么有关| 什么食物含维生素k最多| 心率过快吃什么药最好| 妈妈是什么意思呢| 承五行属性是什么| 头晕目眩是什么意思| 左手大拇指麻木是什么原因| 心脏斑块是什么意思啊| 狗狗细小是什么症状| 甲减吃什么食物好| 平痛新又叫什么| 儿童抗o高会引起什么病| 水彩笔用什么能洗掉| 做b超为什么要憋尿| ct挂号挂什么科| 苕皮是什么做的| magnesium是什么意思| 前列腺增生有什么危害| 双氧水是什么| 什么时候入秋| 铁皮石斛能治什么病| 用酒擦身体有什么好处| 肩周炎吃什么药效果最好| 梦见挖红薯是什么意思| 抵抗力差是什么原因| 一带一路指的是什么| 脯氨酸氨基肽酶阳性是什么意思| 春回大地是指什么生肖| 公务员是干什么的| 矬是什么意思| 法国铁塔叫什么名字| 永垂不朽的垂是什么意思| 1.30是什么星座| 老实是什么意思| 偷窥什么意思| 嘴上起泡是什么原因| 绝经三年了突然又出血了什么原因| 肺气肿有什么症状| 肝胃不和是什么意思| 梅核气是什么病| 黄金为什么那么贵| 清胃火吃什么药| 毛鸡蛋是什么| 手上起小水泡痒是什么原因| 百度

梦见自己流产了是什么征兆

require('strict');
local getArgs = require ('Module:Arguments').getArgs;


--[[--------------------------< A R G S _ D E F A U L T >------------------------------------------------------

a table to specify initial values.

]]

local args_default = {
    group = '',
	bracket_left = '',
	bracket_right = '',
	bracket_year_left = '',
	bracket_year_right = '',
	postscript = '',
	page = '',
	pages = '',
	location = '',
	page_sep = ", p.&nbsp;",
	pages_sep = ", pp.&nbsp;",
	ref = '',
	template = 'harv',															-- if template name not provided in {{#invoke:}} use this
	};


--[[--------------------------< T A R G E T _ C H E C K >------------------------------------------------------

look for anchor_id (CITEREF name-list and year or text from |ref=) in anchor_id_list

the 'no target' error may be suppressed with |ignore-err=yes when target cannot be found because target is inside
a template that wraps another template; 'multiple targets' error may not be suppressed

]]

local function target_check (anchor_id, args)
	local namespace = mw.title.getCurrentTitle().namespace;
	local anchor_id_list_module = mw.loadData ('Module:Footnotes/anchor_id_list');
	local anchor_id_list = anchor_id_list_module.anchor_id_list;
	local article_whitelist = anchor_id_list_module.article_whitelist;
	local template_list = anchor_id_list_module.template_list;
    local citeref_patterns = anchor_id_list_module.citeref_patterns
	
	local whitelist_module = mw.loadData ('Module:Footnotes/whitelist');
	local whitelist = whitelist_module.whitelist;

	local tally = anchor_id_list[anchor_id];									-- nil when anchor_id not in list; else a tally
	local msg;
	local category;

	if not tally then
		if args.ignore then
			return '';															-- if ignore is true then no message, no category
		end
		
		if article_whitelist and article_whitelist[anchor_id] then				-- if an article-local whitelist and anchor ID is in it
			return '';															-- done
		end
		
		local wl_anchor_id = anchor_id;											-- copy to be modified to index into the whitelist
		
		if args.year then														-- for anchor IDs created by this template (not in |ref=) that have a date
			if args.year:match ('%d%l$') or										-- use the date value to determine if we should remove the disambiguator
				args.year:match ('n%.d%.%l$') or
				args.year:match ('nd%l$') then
					wl_anchor_id = wl_anchor_id:gsub ('%l$', '');				-- remove the disambiguator
			end
		end		

		local t_tbl = whitelist[wl_anchor_id];									-- get list of templates associated with this anchor ID

		if t_tbl then															-- when anchor ID not whitelisted t_tbl is nil
			for _, t in ipairs (t_tbl) do										-- spin through the list of templates associated with this anchor ID
				if template_list[t] then										-- if associated template is found in the list of templates in the article
					return '';													-- anchor ID is whitlisted and article has matching template so no error
				end
			end
		end

        for _, pattern in ipairs(citeref_patterns) do                           -- load patterns for wrapper templates on this page
           if anchor_id:match(pattern) then                                     -- spin through the special patterns and try to match
              return ''
           end
        end
  

		msg = 'no target: ' .. anchor_id;										-- anchor_id not found
mw.log(msg)
        if namespace == 10 and not args.show then                               -- do not generate error message in template namespace
           return ''
        end
		category = '[[Category:Harv and Sfn no-target errors]]';

	elseif 1 < tally then
		msg = 'multiple targets (' .. tally .. '×): ' .. anchor_id;				-- more than one anchor_id in this article
mw.log(msg)
        if namespace == 10 and not args.show then                               -- do not generate error message in template namespace
           return ''
        end
		category = 0 == namespace and '[[Category:Harv and Sfn multiple-target errors]]' or '';								-- only categorize in article space
		return '<span class="error harv-error" style="display: inline; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category;
	end

--	category = 0 == namespace and '[[Category:Harv and Sfn template errors]]' or '';	-- only categorize in article space
	category = 0 == namespace and category or '';								-- only categorize in article space

-- display based on args.show (no display by default)
    local display = args.show and 'inline' or 'none'
    return msg and '<span class="error harv-error" style="display: '..display..'; font-size:100%"> ' .. args.template .. ' error: ' .. msg .. ' ([[:Category:Harv and Sfn template errors|help]])</span>' .. category or '';

end


--[[--------------------------< 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)
	YYYY–YY		(separator is endash)

return true when param has a recognized form; false else

]]

local patterns_date= {
	'^%d%d%d%d?%l?$',
	'^n%.d%.%l?$',
	'^nd%l?$',
	'^c%. %d%d%d%d?%l?$',
	'^%d%d%d%d–%d%d%d%d%l?$',
	'^%d%d%d%d–%d%d%l?$',
	}

local function is_year (param, args)
	args.year = '';																-- used for harv error; 
	
	for _, pattern in ipairs (patterns_date) do
		if mw.ustring.match (param, pattern) then
			args.year = param;													-- used for harv error; 
			return true;
		end
	end
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;
	local err_msg = ''

	if args.P5 ~= '' then
		if is_year (args.P5, args) 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, args) then
			result = table.concat ({args.P1, ', ', args.P2, ' &amp; ', 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, args) then
			result = table.concat ({args.P1, ' &amp; ', 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, ' ', ' &amp; ', args.P3});	-- three names
		end
			
	elseif args.P2 ~= '' then
		if is_year (args.P2, args) 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, ' &amp; ', 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
		local anchor_id;
		if args.ref ~= '' then
			anchor_id = mw.uri.anchorEncode (args.ref);
			err_msg = target_check (anchor_id, args);
			result = table.concat ({'[[#', anchor_id, '|', result, ']]'});
		else
			anchor_id = mw.uri.anchorEncode (table.concat ({'CITEREF', args.P1, args.P2, args.P3, args.P4, args.P5}));
			err_msg = target_check (anchor_id, args);
			result = table.concat ({'[[#', anchor_id, '|', 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 .. err_msg;
end


--[[--------------------------< H Y P H E N _ T O _ D A S H >--------------------------------------------------

Converts a hyphen to a dash under certain conditions.  The hyphen must separate
like items; unlike items are returned unmodified.  These forms are modified:
	letter - letter (A - B)
	digit - digit (4-5)
	digit separator digit - digit separator digit (4.1-4.5 or 4-1-4-5)
	letterdigit - letterdigit (A1-A5) (an optional separator between letter and
		digit is supported – a.1-a.5 or a-1-a-5)
	digitletter - digitletter (5a - 5d) (an optional separator between letter and
		digit is supported – 5.a-5.d or 5-a-5-d)

any other forms are returned unmodified.

str may be a comma- or semicolon-separated list

This code copied from Module:Citation/CS1.  The only modification is to require Module:Citation/CS1/Utilities
so that it has access to the functions is_set() and has_accept_as_written()

]]

local function hyphen_to_dash( str )
	local utilities = require ('Module:Citation/CS1/Utilities');				-- only modification so that this function has access to is_set() and has_accept_as_written()

	if not utilities.is_set (str) then
		return str;
	end

	local accept; -- Boolean

	str = str:gsub ('&[nm]dash;', {['&ndash;'] = '–', ['&mdash;'] = '—'});		-- replace &mdash; and &ndash; entities with their characters; semicolon mucks up the text.split
	str = str:gsub ('&#45;', '-'); -- replace HTML numeric entity with hyphen character

	str = str:gsub ('&nbsp;', ' '); -- replace &nbsp; entity with generic keyboard space character
	
	local out = {};
	local list = mw.text.split (str, '%s*[,;]%s*');								-- split str at comma or semicolon separators if there are any

	for _, item in ipairs (list) do												-- for each item in the list
		item, accept = utilities.has_accept_as_written (item);					-- remove accept-this-as-written markup when it wraps all of item
		if not accept and mw.ustring.match (item, '^%w*[%.%-]?%w+%s*[%-–—]%s*%w*[%.%-]?%w+$') then	-- if a hyphenated range or has endash or emdash separators
			if item:match ('^%a+[%.%-]?%d+%s*%-%s*%a+[%.%-]?%d+$') or			-- letterdigit hyphen letterdigit (optional separator between letter and digit)
				item:match ('^%d+[%.%-]?%a+%s*%-%s*%d+[%.%-]?%a+$') or			-- digitletter hyphen digitletter (optional separator between digit and letter)
				item:match ('^%d+[%.%-]%d+%s*%-%s*%d+[%.%-]%d+$') or			-- digit separator digit hyphen digit separator digit
				item:match ('^%d+%s*%-%s*%d+$') or								-- digit hyphen digit
				item:match ('^%a+%s*%-%s*%a+$') then							-- letter hyphen letter
					item = item:gsub ('(%w*[%.%-]?%w+)%s*%-%s*(%w*[%.%-]?%w+)', '%1–%2');	-- replace hyphen, remove extraneous space characters
			else
				item = mw.ustring.gsub (item, '%s*[–—]%s*', '–');				-- for endash or emdash separated ranges, replace em with en, remove extraneous whitespace
			end
		end
		table.insert (out, item);												-- add the (possibly modified) item to the output table
	end

	local temp_str = '';														-- concatenate the output table into a comma separated string
	temp_str, accept = utilities.has_accept_as_written (table.concat (out, ', ')); -- remove accept-this-as-written markup when it wraps all of concatenated out
	if accept then
		temp_str = utilities.has_accept_as_written (str);						-- when global markup removed, return original str; do it this way to suppress boolean second return value
		return temp_str;
	else
		return temp_str;														-- else, return assembled temp_str
	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.

]]

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.group = pframe.args.group or '';
	args.page = pframe.args.p or pframe.args.page or '';
	args.pages = pframe.args.pp or pframe.args.pages or '';
	args.pages = ('' ~= args.pages) and hyphen_to_dash (args.pages) or '';
	args.location = pframe.args.at or pframe.args.loc or '';
	args.ref = pframe.args.ref or pframe.args.Ref or '';
	args.ignore = ('yes' == pframe.args['ignore-false-positive']) or ('yes' == pframe.args['ignore-err']);

	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

	if args.P5 and not is_year (args.P5, args) then
		local i = 6;															-- initialize the indexer to the sixth positional parameter
		while pframe.args[i] do													-- in case there are too many authors loop through the authors looking for a year
			local v = mw.text.trim (pframe.args[i]);							-- trim
			if is_year (v, args) then											-- if a year
				args.P5 = v;													-- overwrite whatever was in args.P5 with year
				break;															-- and abandon the search
			end
			i = i + 1;															-- bump the indexer
		end
	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 by sfn() and sfnm().  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 and '%' because '%20' (space character) is a lua 'invalid capture index'
		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={group=args.group, name=name}, content=result});	

	
end


--[[--------------------------< S F N M >----------------------------------------------------------------------

common entry point for {{sfnm}} and {{sfnmp}}

Distinguishing features (brackets) are specified in this module's {{#invoke}} in the respective templates.

]]

local function sfnm (frame)
	local args = args_default;													-- create a copy of the default table
	local pframe = frame:getParent();											-- point to the template's parameter table
	
	local n = 1;																-- index of source; this is the 'n' in na1, ny, etc
	local first_pnum = 1;														-- first of a pair of positional parameters
	local second_pnum = 2;														-- second of a pair of positional parameters

	local last_ps = 0;															-- index of the last source with |nps= set
	local last_index = 0;														-- index of the last source; these used to determine which of |ps= or |nps= will terminate the whole rendering

	local out = {};																-- table to hold rendered sources
	local footnote = {'FOOTNOTE'};												-- all author, date, insource location stuff becomes part of the reference's footnote id; added as we go

	for k, v in pairs (frame.args) do											-- override defaults with values provided in the #invoke: if any
		args[k] = v;	   
	end
	
	while true do
		if not pframe.args[table.concat ({n, 'a1'})] and not pframe.args[first_pnum] then
			break;																-- no na1 or matching positional parameter so done
		end
		
		if pframe.args[table.concat ({n, 'a1'})] then							-- does this source use named parameters?
			for _, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do				-- initialize for this source
				args[v] = '';
			end

			for i, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do				-- extract author and year parameters for this source
				args[v] = pframe.args[table.concat ({n, 'a', i})] or '';		-- attempt to assign author name
				if '' == args[v] then											-- when there wasn't an author name
					args[v] = pframe.args[table.concat ({n, 'y'})] or '';		-- attempt to assign year
					break;														-- done with author/date for this source
				end
			end

		else																	-- this source uses positional parameters
			args.P1 = mw.text.trim (pframe.args[first_pnum]);					-- yes, only one author supported
			args.P2 = (pframe.args[second_pnum] and mw.text.trim (pframe.args[second_pnum])) or '';	-- when positional author, year must also be positional

			for _, v in ipairs ({'P3', 'P4', 'P5'}) do							-- blank the rest of these for this source
				args[v] = '';
			end

			first_pnum = first_pnum + 2;										-- source must use positional author and positional year
			second_pnum = first_pnum + 1;										-- bump these for possible next positional source
		end
		
		args.postscript = pframe.args[table.concat ({n, 'ps'})] or '';
		if 'none' == args.postscript then										-- this for compatibility with other footnote templates; does nothing
			args.postscript = '';
		end
		args.group = pframe.args.group or '';									-- reference group
		args.ref = pframe.args[table.concat ({n, 'ref'})] or '';				-- alternate reference for this source

		args.page = pframe.args[table.concat ({n, 'p'})] or '';					-- insource locations for this source
		args.pages = pframe.args[table.concat ({n, 'pp'})] or '';
		args.pages = ('' ~= args.pages) and hyphen_to_dash (args.pages) or '';
		args.location = pframe.args[table.concat ({n, 'loc'})] or pframe.args[table.concat ({n, 'at'})] or '';
		args.ignore = ('yes' == pframe.args[table.concat ({n, 'ignore-false-positive'})]) or ('yes' == pframe.args[table.concat ({n, 'ignore-err'})]);

		table.insert (out, core (args));										-- save the rendering of this source
		
		for k, v in ipairs ({'P1', 'P2', 'P3', 'P4', 'P5'}) do					-- create the FOOTNOTE id
			if '' ~= args[v] then
				table.insert (footnote, args[v]);
			end
		end
		for k, v in ipairs ({'page', 'pages', 'location'}) do					-- these done separately so that we can strip uri-reserved characters from extlinked page numbers 
			if '' ~= args[v] then
				table.insert (footnote, strip_url (args[v]))
			end
		end
		
		last_index = n;															-- flags used to select terminal postscript from nps or from end_ps
		if '' ~= args.postscript then							
			last_ps = n;
		end
		
		n = n+1;																-- bump for the next one
	end
	
	local name = table.concat (footnote):gsub ('%s+', ' ');						-- put the footnote together and strip redundant space
	
	args.end_ps = pframe.args.postscript or pframe.args.ps or '.';				-- this is the postscript for the whole not for the individual sources
	if 'none' == args.end_ps then												-- not an original sfnm parameter value; added for compatibility with other footnote templates
		args.end_ps = '';
	end

	local result = table.concat ({table.concat (out, '; '), (last_index == last_ps) and '' or  args.end_ps});
	return frame:extensionTag ({name='ref', args={group=args.group, name=name}, content=result});
end


--[[--------------------------< S F N R E F >------------------------------------------------------------------

implements {{sfnref}}

]]

local function sfnref (frame)
	local args = getArgs (frame);
	local out = {};
	
	for i=1, 5 do																-- get the first five args if there are five args
		if args[i] then
			out[i] = args[i];
		else
			break;																-- less than 5 args break out
		end
	end
	
	if 5 == #out then															-- when we have seen five args there may bemore
		local i = 6;															-- initialize the indexer to the sixth positional parameter
		while args[i] do														-- in case there are too many authors loop through the authors looking for a year
			if is_year (args[i], args) then										-- if a year
				out[5] = args[i];												-- overwrite whatever was in args[5] with year
				break;															-- and abandon the search
			end
			i = i + 1;															-- bump the indexer
		end
	end
	
	return mw.uri.anchorEncode ('CITEREF' .. table.concat (out));
end


--[[--------------------------< E X P O R T E D   F U N C T I O N S >------------------------------------------
]]

return {
	harvard_citation = harvard_citation,
	sfn = sfn,
	sfnm = sfnm,
	sfnref = sfnref,
    target_check = target_check,
	};
氨基酸态氮是什么 泡果酒用什么酒好 马踏飞燕什么意思 blanc什么意思 zoom是什么
一班三检是指什么 拔罐拔出水是什么原因 父亲节是什么时候 云吞面是什么面 蛋白肉是什么东西做的
什么床垫好 什么季节掉头发最厉害 肠道感染吃什么消炎药 荪是什么意思 cp什么意思网络用语
吃什么减肥效果最好最快 掉头发挂什么科 女性口臭都是什么原因 枸杞子和什么泡水喝补肾壮阳 吃什么食物对胰腺好
孕妇d2聚体高是什么原因hcv7jop7ns2r.cn 9.22是什么星座hcv8jop7ns0r.cn 黄芪主要治疗什么hcv8jop5ns4r.cn poems综合征是什么病hcv9jop5ns5r.cn 烂漫什么意思hcv9jop3ns7r.cn
阴阳先生是干什么的hcv9jop6ns8r.cn tr是什么意思hcv8jop1ns0r.cn 描红是什么意思hcv9jop1ns6r.cn 尿酸高肌酐高是什么原因呢hcv9jop2ns8r.cn 胸闷挂什么科室hcv9jop7ns0r.cn
今年42岁属什么生肖mmeoe.com 起风疹的原因是什么引起的hcv9jop6ns8r.cn 冰岛茶属于什么茶hcv7jop6ns0r.cn 椰青是什么xscnpatent.com 怹是什么意思gangsutong.com
李白和杜甫并称什么hcv8jop7ns7r.cn 久负盛名的负是什么意思hcv9jop3ns6r.cn 龟头上抹什么药能延时tiangongnft.com 平均血小板体积低是什么原因hcv9jop3ns8r.cn 奶咖是什么hcv9jop8ns3r.cn
百度