モジュールの解説[作成]

local p = {}  --[[ Template:Tnavbar ]] function p.tnavbar(frame) 	local r = mw.html.create()													--出力用 	local args = frame.args 	if not args[1] then return '&nbsp;' end 	 	local function tf(x) 		return x == '1' and true or false 	end 	args.plain = tf(args.plain) 	args.div = tf(args.div) 	args.nodiv = tf(args.nodiv) 	args.mini = tf(args.mini) 	args.viewplain = tf(args.viewplain) 	args.fontstyle = args.fontcolor ~= '' and ((args.fontstyle or '') .. ';color:' .. args.fontcolor .. ';') or args.fontstyle or '' 	 	local divTag = r:tag('div') 		:addClass('noprint') 		:addClass('plainlinks') 		:addClass('navbar') 		:addClass('hlist') 		:css('white-space', 'nowrap') 		:css('font-size', '60%') 		:css('font-weight', 'normal') 	 	if args.nodiv then 		divTag:css('display', 'inline') 			:css('padding', '0 0.5em') 	else 		divTag:css('background-color', 'transparent') 			:css('padding', '0') 			:css('color', '#000') 	end 	divTag:cssText(args.fontstyle) 		:cssText(args.style) 	 	if not (args.plain or args.mini or args.viewplain) then 		divTag:tag('span') 			:css('font-size', '125%') 			:node('このテンプレートを:&nbsp;') 	end 	 	local disp = args.mini and {'表', '話', '編', '歴'} or {'表示', 'ノート', '編集', '履歴'} 	local ns = {'Template:', 'Template_talk:', 'Template:', 'Template:'} 	local query = {nil, nil, 'action=edit', 'action=history'} 	local title = {'このテンプレートを表示します', 'このテンプレートのトークを表示します', 'このテンプレートを編集します。保存の前にプレビューを忘れずに。', 'このテンプレートの過去の版を表示します'} 	local color = {'', 'color:#002bb8;', 'color:#002bb8;', 'color:#002bb8;'} 	local i = 0 	local i_end = args.viewplain and 1 or 4 	local ulTag = divTag:tag('ul') 		:css('display', 'inline') 	for i = 1, i_end do 		local liTag = ulTag:tag('li') 		local l = {open = '', link = '', close = ''} 		if query[i] then 			l.open = '[' 			l.link = tostring(mw.uri.canonicalUrl(ns[i] .. args[1], query[i])) .. ' ' 			l.close = ']' 		else 			l.open = '[[' 			l.link = ns[i] .. args[1] .. '|' 			l.close = ']]' 		end 		liTag:wikitext(l.open .. l.link) 			:tag('span') 				:attr('title', title[i]) 				:css('font-size', '125%') 				:cssText(color[i]) 				:cssText(args.fontstyle) 				:node(disp[i]) 				:done() 			:wikitext(l.close) 	end 	 	return tostring(r) end   --[[ Define Arguments ]] local getArgs local args = {} local border local child, none = false, false local rowspan = 0 local basestyle = '' local odd, even = 'odd', 'even'  local list, liststyle = {}, {} local group, groupstyle = {}, {} local colheader, colheadercolspan, colheaderstyle = {}, {}, {} local col, colstyle, colwidth = {}, {}, {} local colfooter, colfootercolspan, colfooterstyle = {}, {}, {} local abbr, state = {}, {} local sect, section = {}, {} local secttitlestyle = {} local content, contentstyle = {} local image, imageleft = {}, {}  local function defArgs(frame) 	if not getArgs then 		getArgs = require('Module:Arguments').getArgs 	end 	args = getArgs(frame, {parentOnly = true}) 	border = args.border or args[1] 	child, none = (border == 'subgroup' or border == 'child'), (border == 'none') 	collapsible = (args.state == 'plain' or args.state == 'off') and '' or 'mw-collapsible ' 	 	if args.basestyle then basestyle = args.basestyle .. ';' end 	 	local sortable_mt = { 		__lt = function(a, b) return a.index < b.index end, 		__concat = function(a, b) 			local strA = (type(a) == 'table') and a.content or a or '' 			local strB = (type(b) == 'table') and b.content or b or '' 			return strA .. strB 		end 	} 	local function sortable_args(tbl, index, content) 		table.insert(tbl, {index = index, content = content}) 		setmetatable(tbl[#tbl], sortable_mt) 	end 	local switch = { 		--common 		list = function(num, v) sortable_args(list, num, '\n' .. v) end, 		liststyle = function(num, v) liststyle[num] = v end, 		group = function(num, v) group[num] = v end, 		groupstyle = function(num, v) groupstyle[num] = v end, 		--for with_columns 		colheader = function(num,v) colheader[num] = v end, 		colheadercolspan = function(num,v) colheadercolspan[num] = v end, 		colheaderstyle = function(num,v) colheaderstyle[num] = v end, 		col = function(num, v) sortable_args(col, num, '\n' .. v) end, 		colstyle = function(num,v) colstyle[num] = v end, 		colwidth = function(num,v) colwidth[num] = v end, 		colfooter = function(num,v) colfooter[num] = v end, 		colfootercolspan = function(num,v) colfootercolspan[num] = v end, 		colfooterstyle = function(num,v) colfooterstyle[num] = v end, 		--for with_collapsible_groups 		abbr = function(num, v) abbr[num] = v end, 		state = function(num, v) state[num] = v end, 		sect = function(num, v) group[num] = v end, 		section = function(num, v) group[num] = v end, 		secttitlestyle = function(num, v) groupstyle[num] = v end, 		content = function(num, v) sortable_args(content, num, '\n' .. v) end, 		contentstyle = function(num, v) liststyle[num] = v end, 		image = function(num, v) image[num] = v end, 		imageleft = function(num, v) imageleft[num] = v end, 	} 	 	for k, v in pairs(args) do 		local str1, num, str2 = string.match(k, '(%D+)(%d+)(%D*)') 		str1, num, str2 = str1 or '', tonumber(num), str2 or '' 		if switch[str1 .. str2] and num then switch[str1 .. str2](num, v) end 	end 	 	table.sort(list) 	rowspan = #list end  --[[ top ]] local function top(baseTag) 	local nav 	local bodyTable 	if baseTag == nil or baseTag == '' then 		baseTag = mw.html.create() 	end 	if child then 		baseTag:wikitext('</div>') 		nav = baseTag 	elseif not none then 		nav = baseTag:tag('div') 			:addClass('navbox') 			:addClass(args.navboxclass) 			:css('border-collapse', 'collapse') 			:cssText(args.bodystyle) 			:cssText(args.style) 			:css('padding', '3px') 		if args.title or args.above then 			nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title or args.above)) 		else 			nav:attr('aria-label', 'Navbox') 		end 	else 		nav = baseTag 	end 	 	bodyTable = nav:tag('table') 		:addClass('nowraplinks') 		:addClass(args.bodyclass)  	if args.title and (args.state ~= 'plain' and args.state ~= 'off') then 		if args.state == 'collapsed' then args.state = 'mw-collapsed' end 		bodyTable 			:addClass('mw-collapsible') 			:addClass(args.state or 'autocollapse') 	end  	if child or border == 'none' then 		bodyTable 			:addClass('navbox-subgroup') 			:cssText(args.bodystyle) 			:cssText(args.style) 	else  -- regular navbox - bodystyle and style will be applied to the wrapper table 		bodyTable 			:addClass('navbox-inner') 			:css('background', 'transparent') 			:css('color', 'inherit') 	end 	bodyTable:css('min-width', '100%') 		:css('border-spacing', '0px') 		:css('border-collapse', 'separate') 		:cssText(args.innerstyle) 	 	return baseTag, bodyTable end  --[[ title and navbar ]] local function title(tbl) 	if not args.title then return tbl end 	local titleRow = tbl:tag('tr') 	 	if args.titlegroup then 		titleRow 			:tag('th') 				:attr('scope', 'row') 				:addClass('navbox-group') 				:addClass(args.titlegroupclass) 				:cssText(args.basestyle) 				:cssText(args.groupstyle) 				:cssText(args.titlegroupstyle) 				:wikitext(args.titlegroup) 	end  	local titleCell = titleRow:tag('th'):attr('scope', 'col')  	if args.titlegroup then 		titleCell 			:css('width', '100%') 	end 	 	local titleColspan = 2 	if args.imageleft then titleColspan = titleColspan + 1 end 	if args.image then titleColspan = titleColspan + 1 end 	if args.titlegroup then titleColspan = titleColspan - 1 end  	titleCell 		:cssText(args.basestyle) 		:cssText(args.titlestyle) 		:addClass('navbox-title') 		:attr('colspan', titleColspan) 	 	if (args.navbar == 'plain') or (not args.name and (child or none)) then 		titleCell 			:tag('div') 				:css('float', 'left') 				:css('width', '6em') 				:node('&nbsp;') 	elseif args.navbar ~= 'off' then 		local tbl = {args = {args.name, mini = '1', fontstyle = basestyle .. (args.titlestyle or '') .. ';border:none;', fontcolor = ''}} 		titleCell 			:tag('div') 				:css('float', 'left') 				:css('width', '6em') 				:css('text-align', 'left') 				:node(p.tnavbar(tbl)) 	end 	 	if child or border == 'none' then 		titleCell 			:tag('div') 				:attr('id', mw.uri.anchorEncode(args.title)) 				:addClass(args.titleclass) 				:css('font-size', '100%') 				:css('margin', '0 6em') 				:node(args.title) 	else 		titleCell 			:tag('div') 				:attr('id', mw.uri.anchorEncode(args.title)) 				:addClass(args.titleclass) 				:css('font-size', '110%') 				:css('margin', '0 6em') 				:node(args.title) 	end  	return tbl end  local function getAboveBelowColspan() 	local ret = 2 	if args.imageleft then ret = ret + 1 end 	if args.image then ret = ret + 1 end 	return ret end  --[[ above ]] local function above(tbl) 	if not args.above then return tbl end  	tbl:tag('tr') 		:tag('td') 			:addClass('navbox-abovebelow') 			:addClass(args.aboveclass) 			:cssText(args.basestyle) 			:cssText(args.abovestyle) 			:attr('colspan', getAboveBelowColspan()) 			:newline() 			:node(args.above) 	return tbl end 	 --[[ body ]] --first group/list and images local function body1(tbl) 	local row = tbl:tag('tr') 	if args.imageleft then 		row 			:tag('td') 				:addClass('navbox-image') 				:addClass(args.imageclass) 				:css('width', '1px') 				:css('padding', '0px 2px 0px 0px') 				:cssText(args.imageleftstyle) 				:attr('rowspan', rowspan) 				:tag('div') 					:node(args.imageleft) 	end 	local j = list[1].index 	if group[j] then 		local groupCell = row:tag('th')  		groupCell 			:attr('scope', 'row') 			:addClass('navbox-group') 			:addClass(args.groupclass) 			:cssText(args.basestyle) 			:css('width', args.groupwidth or '1%')  		groupCell 			:cssText(args.groupstyle) 			:cssText(groupstyle[j]) 			:wikitext(group[j]) 	end  	local listCell = row:tag('td')  	if group[j] then 		listCell 			:css('text-align', 'left') 			:css('border-left-width', '2px') 			:css('border-left-style', 'solid') 	else 		listCell:attr('colspan', 2) 	end  	if not args.groupwidth then 		listCell:css('width', '100%') 	end  	local rowstyle 	if odd == 'odd' then 		rowstyle = args.oddstyle 	else 		rowstyle = args.evenstyle 	end  	listCell 		:css('padding', '0px') 		:cssText(args.liststyle) 		:cssText(rowstyle) 		:cssText(liststyle[j]) 		:addClass('navbox-list') 		:addClass('navbox-' .. (args.evenodd == 'swap' and even or args.evenodd or odd)) 		:addClass(args.listclass) 		:tag('div') 			:css('padding', (args.list1padding or args.listpadding or '0em 0.25em')) 			:node(list[1].content) 			:newline() 	if args.image then 		row 			:tag('td') 				:addClass('navbox-image') 				:addClass(args.imageclass) 				:css('width', '1px') 				:css('padding', '0px 0px 0px 2px') 				:cssText(args.imagestyle) 				:attr('rowspan', rowspan) 				:tag('div') 					:node(args.image) 	end 	return tbl end  --remaining groups/lists local function body2(tbl) 	for i = 2, #list do 		odd, even = even, odd 		local j = list[i].index 		local row = tbl:tag('tr') 		if group[j] then 			local groupCell = row:tag('th') 			groupCell 				:attr('scope', 'row') 				:addClass('navbox-group') 				:addClass(args.groupclass) 				:cssText(args.basestyle) 				:css('width', args.groupwidth or '1%')  			groupCell 				:cssText(args.groupstyle) 				:cssText(groupstyle[j]) 				:node(group[j]) 		end  		local listCell = row:tag('td')  		if group[j] then 			listCell 				:css('text-align', 'left') 				:css('border-left-width', '2px') 				:css('border-left-style', 'solid') 		else 			listCell:attr('colspan', 2) 		end  		if not args.groupwidth then 			listCell:css('width', '100%') 		end  		local rowstyle 		if odd == 'odd' then 			rowstyle = args.oddstyle 		else 			rowstyle = args.evenstyle 		end 		listCell 			:css('padding', '0px') 			:cssText(args.liststyle) 			:cssText(rowstyle) 			:cssText(liststyle[j]) 			:addClass('navbox-list') 			:addClass('navbox-' .. (args.evenodd == 'swap' and even or args.evenodd or odd)) 			:addClass(args.listclass) 			:tag('div') 				:css('padding', (args.listpadding or '0em 0.25em')) 				:node(list[i].content) 				:newline() 	end 	return tbl end  --[[ below ]] local function below(tbl) 	if not args.below then return tbl end  	tbl:tag('tr') 		:tag('td') 			:addClass('navbox-abovebelow') 			:addClass(args.belowclass) 			:cssText(args.basestyle) 			:cssText(args.belowstyle) 			:attr('colspan', getAboveBelowColspan()) 			:newline() 			:node(args.below) 	return tbl end  --[[ Template:Navbox ]] function p.navbox(frame) 	defArgs(frame) 	local res 	local firstTableTag 	res, firstTableTag = top() 	firstTableTag = title(firstTableTag) 	firstTableTag = above(firstTableTag) 	if list[1] then 		firstTableTag = body1(firstTableTag) 	end 	firstTableTag = body2(firstTableTag) 	firstTableTag = below(firstTableTag) 	if child then 		res:wikitext('<div>') 	end 	return tostring(res) end  --[[ Template:Navbox subgroup ]] function p.subgroup(frame) 	defArgs(frame) 	if not border then child = true end 	args.groupstyle = 'padding:' .. (args.grouppadding or '0 0.75em') .. ';' .. (args.groupstyle or '') 	 	local res 	local firstTableTag 	res, firstTableTag = top() 	firstTableTag = title(firstTableTag) 	firstTableTag = above(firstTableTag) 	if list[1] then 		firstTableTag = body1(firstTableTag) 	end 	firstTableTag = body2(firstTableTag) 	firstTableTag = below(firstTableTag) 	if not border then res:wikitext('<div>') end 	return tostring(res) end  --[[ Template:Navbox with columns ]] function p.with_columns(frame) 	defArgs(frame) 	table.sort(col) 	local res 	local firstTableTag 	res, firstTableTag = top() 	 	firstTableTag = title(firstTableTag) 	firstTableTag = above(firstTableTag) 	 	if col[1] then 		local j = col[1].index 		local cols = mw.html.create('table') 			:addClass('navbox-columns-table') 			:css('border-spacing', '0px') 			:css('border-collapse', 'separate') 			:css('text-align', 'left') 			:cssText((colheader[j] or args.fullwidth) and 'width:100%;' or 'margin:0 auto;') 			:cssText(args.coltablestyle) 		--Header row 		if colheader[j] then 			local headerRow = cols:tag('tr') 				:addClass('navbox-abovebelow') 				:css('font-weight', 'bold') 				:cssText(args.colheaderstyle) 			for i = 1, #col do 				local j = col[i].index 				if colheader[j] then 					headerRow:tag('td') 						:attr('colspan', colheadercolspan[j] or '1') 						:cssText(colheaderstyle[j]) 						:node(colheader[j]) 				end 			end 		end 		--Main columns 		local row = cols:tag('tr') 			:css('vertical-align', 'top') 			:cssText(args.colstyle) 		if not (colheader[j] or colfooter[j] or args.fullwidth) then 			local paddingoff = args.padding and string.find(args.padding, '^0[ep]?[mx]?%?;?') 			if not paddingoff then 				row:tag('td') 					:css('width', args.padding or '5em') 					:wikitext('&nbsp;&nbsp;&nbsp;') 			end 		end 		for i = 1, #col do 			local j = col[i].index 			row:tag('td') 				:css('padding', '0') 				:cssText(args.oddcolstyle) 				:cssText(colstyle[j]) 				:css('width', colwidth[j] or args.colwidth or '10em') 				:node(col[i].content) 			args.oddcolstyle, args.evencolstyle = args.evencolstyle, args.oddcolstyle 		end 		--Footer row 		if colfooter[j] then 			row = cols:tag('tr') 				:addClass('navbox-abovebelow') 				:css('font-weight', 'bold') 				:cssText(args.colfooterstyle) 			for i = 1, #col do 				local j = col[i].index 				if colfooter[j] then 					row:tag('td') 						:attr('colspan', colfootercolspan[j] or '1') 						:cssText(colfooterstyle[j]) 						:node(colfooter[j]) 				end 			end 		end 		cols = mw.html.create():wikitext('</div>'):wikitext(tostring(cols)):wikitext('<div>') 		table.insert(list, {index=1, content=cols}) 		rowspan = rowspan + 1 	end 	 	firstTableTag = body1(firstTableTag) 	firstTableTag = body2(firstTableTag) 	firstTableTag = below(firstTableTag) 	return tostring(res) end  --[[ Template:Navbox with collapsible groups ]] function p.with_collapsible_groups(frame) 	local res 	local firstTableTag 	defArgs(frame) 	table.sort(content) 	res, firstTableTag = top() 	firstTableTag = title(firstTableTag) 	firstTableTag = above(firstTableTag) 	 	local i = 1 	local function funcList(rowTag) 		list[i] = list[i] or content[i] 		local j = list[i].index 		args.state = state[j] or args.selected and (args.selected == abbr[j] or args.selected == group[j]) and '' or 'mw-collapsed' 		args.name = nil 		args.titlestyle = basestyle .. (args.groupstyle or '') .. ';' .. (args.secttitlestyle or '') .. ';' .. (groupstyle[j] or '') 		args.liststyle = (args.liststyle or '') .. ';' .. (args.contentstyle or '') .. ';' .. (liststyle[j] or '') 		args.title, group[j] = group[j], nil 		args.image = image[j] 		args.imageleft = imageleft[j] 		rowspan = 1 		local baseTag = rowTag:tag('td') 			:cssText(args.groupwidth and '' or 'width:100%;') 			:css('padding', '0px') 			:cssText(args.liststyle) 			:cssText(odd == 'odd' and (args.oddstyle or '') or (args.evenstyle or '')) 			:cssText(liststyle[j]) 			:addClass('navbox-list') 			:addClass('navbox-' .. (args.evenodd == 'swap' and even or args.evenodd or odd)) 			:addClass(args.listclass) 			:tag('div') 		if args.title then 			local tableTag 			none = true 			baseTag, tableTag = top(baseTag) 			tableTag = title(tableTag) 			tableTag = body1(tableTag)       if child then         baseTag:wikitext('<div>')       end 		else 			baseTag:node(list[i].content) 		end 	end 	 	--i = 1 	local row = firstTableTag:tag('tr') 	if args.imageleft then 		row:tag('td') 			:addClass('navbox-image') 			:addClass(args.imageclass) 			:css('width', '0') 			:css('padding', '0 2px 0 0') 			:cssText(args.imageleftstyle) 			:attr('rowspan', rowspan) 			:node(args.imageleft) 	end 	funcList(row) 	if args.image then 		row:tag('td') 			:css('width', '0%') 			:css('padding', '0 0 0 2px') 			:cssText(args.imagestyle) 			:attr('rowspan', rowspan) 			:node(args.image) 	end 	--i > 2 	for i = 2, #list do 		row = firstTableTag:tag('tr') 		list[1] = list[i] 		funcList(row) 	end 	 	firstTableTag = below(firstTableTag)   if child then 		res:wikitext('<div>') 	end 	child, none = (border == 'subgroup' or border == 'child'), (border == 'none') --再定義 	return tostring(res) end  --[[ Template:NavboxYears Template:NavboxYears2 ]] local function calc_years(args, fmtLink) 	local numtab = tonumber(args.tab) or 0 	local numstart = tonumber(args.start) 	local numend = tonumber(args['end']) 	local numstep = tonumber(args.step) or 1 	if numstart and numend then 		if numtab > 0 then 			for i = 2, numtab + 1 do 				args[i] = nil 			end 		end 		local numD = numend - numstart + 1 		for i = 1, numD, numstep do 			args[i + numtab + 1] = numstart + i - 1 		end 	end 	local res = mw.html.create('table') 	res 		:css('width', '100%') 		:css('border-spacing', '0px') 		:css('border-collapse', 'separate') 		:css('text-align', 'center') 	local h = 1 	repeat 		h = h + 1 		local row = res:tag('tr') 		for i = 2, 11 do 			local tdTag = row:tag('td') 				:css('width', '10%') 			if (tonumber(args[i]) or -1) > 0 then 				tdTag:wikitext('[[' .. fmtLink(args[1], args[i]) .. '|' .. args[i] .. ']]') 			else 				tdTag:wikitext(args[i]) 			end 			args[i], args[i + 10] = args[i + 10], args[i + h * 10] 		end 	until not args[2] 	return tostring(res) end  local function years(frame, fmtLink) 	defArgs(frame) 	if args.var then fmtLink = function(str, num) return str:gsub(args.var, num) end end 	if args.name then 		args.style = 'width:' .. (args.width or '38em') .. ';' .. (args.style or '') 		local res 		local firstTableTag 		res, firstTableTag = top() 		if args.title then  			firstTableTag = title(firstTableTag) 		end 		if args.above then 			firstTableTag = above(firstTableTag) 		end 		if not list[1] and args[1] then list[1] = {index = 1, content = calc_years(args, fmtLink)} end 		if list[1] then 			firstTableTag = body1(firstTableTag) 		end 		firstTableTag = body2(firstTableTag) 		if args.below then 			firstTableTag = below(firstTableTag) 		end 		return tostring(res) 	else 		return calc_years(args, fmtLink) 	end end  function p.years(frame) 	local fmtLink = function(str, num) return str .. num end 	return years(frame, fmtLink) end  function p.years2(frame) 	local fmtLink = function(str, num) return num .. str end 	return years(frame, fmtLink) end  return p