模块:Infobox

---- This module implements {{Infobox}}-- 中文的此模块对比英文维基多解析了overimage, overcaption,-- overimagerowclass以及header/labal/data*style参数。--localp={}localHtmlBuilder=require('Module:HtmlBuilder')localargs={}localorigArgslocalrootfunctionunion(t1,t2)-- Returns the union of the values of two tables, as a sequence.localvals={}fork,vinpairs(t1)dovals[v]=trueendfork,vinpairs(t2)dovals[v]=trueendlocalret={}fork,vinpairs(vals)dotable.insert(ret,k)endreturnretendlocalfunctiongetArgNums(prefix)-- Returns a table containing the numbers of the arguments that exist-- for the specified prefix. For example, if the prefix was 'data', and-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.localnums={}fork,vinpairs(args)dolocalnum=tostring(k):match('^'..prefix..'([1-9]%d*)$')ifnumthentable.insert(nums,tonumber(num))endendtable.sort(nums)returnnumsendlocalfunctionaddRow(rowArgs)-- Adds a row to the infobox, with either a header cell-- or a label/data cell combination.ifrowArgs.headerthenroot.tag('tr').addClass(rowArgs.rowclass).tag('th').attr('colspan',2).addClass(rowArgs.class).css('text-align','center').cssText(rowArgs.headerstyle).wikitext(rowArgs.header)elseifrowArgs.datathenlocalrow=root.tag('tr')row.addClass(rowArgs.rowclass)ifrowArgs.labelthenrow.tag('th').attr('scope','row').css('text-align','left').cssText(rowArgs.labelstyle).wikitext(rowArgs.label).done()endlocaldataCell=row.tag('td')ifnotrowArgs.labelthendataCell.attr('colspan',2).css('text-align','center')enddataCell.addClass(rowArgs.class).cssText(rowArgs.datastyle).newline().wikitext(rowArgs.data)endendlocalfunctionrenderOverImage()ifnotargs.overimagethenreturnendlocalrow=root.tag('tr')row.addClass(args.overimagerowclass)localtopImage=row.tag('td')topImage.attr('colspan',2)topImage.addClass(args.class)topImage.cssText(args.datastyle)topImage.css('text-align','center')ifargs.overcaptionthentopImage.wikitext(args.overimage..'<br><span style=\"'..args.captionstyle..'\">'..args.overcaption..'</span>')elsetopImage.wikitext(args.overimage)endendlocalfunctionrenderTitle()ifnotargs.titlethenreturnendroot.tag('caption').addClass(args.titleclass).cssText(args.titlestyle).wikitext('\'\'\''..args.title..'\'\'\'')endlocalfunctionrenderAboveRow()ifnotargs.abovethenreturnendroot.tag('tr').tag('th').attr('colspan',2).addClass(args.aboveclass).css('text-align','center').css('font-size','125%').css('font-weight','bold').cssText(args.abovestyle).wikitext(args.above)endlocalfunctionrenderBelowRow()ifnotargs.belowthenreturnendroot.tag('tr').tag('td').attr('colspan','2').addClass(args.belowclass).css('text-align','center').cssText(args.belowstyle).newline().wikitext(args.below)endlocalfunctionrenderSubheaders()ifargs.subheaderthenargs.subheader1=args.subheaderendifargs.subheaderrowclassthenargs.subheaderrowclass1=args.subheaderrowclassendlocalsubheadernums=getArgNums('subheader')fork,numinipairs(subheadernums)doaddRow({data=args['subheader'..tostring(num)],datastyle=args.subheaderstyleorargs['subheaderstyle'..tostring(num)],class=args.subheaderclass,rowclass=args['subheaderrowclass'..tostring(num)]})endendlocalfunctionrenderImages()ifargs.imagethenargs.image1=args.imageendifargs.captionthenargs.caption1=args.captionendlocalimagenums=getArgNums('image')fork,numinipairs(imagenums)dolocalcaption=args['caption'..tostring(num)]localdata=HtmlBuilder.create().wikitext(args['image'..tostring(num)])ifcaptionthendata.tag('br',{selfClosing=true}).done().tag('div').cssText(args.captionstyle).wikitext(caption)endaddRow({data=tostring(data),datastyle=args.imagestyle,class=args.imageclass,rowclass=args['imagerowclass'..tostring(num)]})endendlocalfunctionrenderRows()-- Gets the union of the header and data argument numbers,-- and renders them all in order using addRow.localrownums=union(getArgNums('header'),getArgNums('data'))table.sort(rownums)fork,numinipairs(rownums)doaddRow({header=args['header'..tostring(num)],headerstyle=(args.headerstyleor'')..';'..(args['header'..tostring(num)..'style']or''),label=args['label'..tostring(num)],labelstyle=(args.labelstyleor'')..';'..(args['label'..tostring(num)..'style']or''),data=args['data'..tostring(num)],datastyle=(args.datastyleor'')..';'..(args['data'..tostring(num)..'style']or''),class=args['class'..tostring(num)],rowclass=args['rowclass'..tostring(num)]})endendlocalfunctionrenderNavBar()ifnotargs.namethenreturnendroot.tag('tr').tag('td').attr('colspan','2').css('text-align','right').wikitext(mw.getCurrentFrame():expandTemplate({title='navbar',args={args.name,mini=1}}))endlocalfunctionrenderItalicTitle()localitalicTitle=args['italic title']andmw.ustring.lower(args['italic title'])ifitalicTitle==''oritalicTitle=='force'oritalicTitle=='yes'thenroot.wikitext(mw.getCurrentFrame():expandTemplate({title='italic title'}))endendlocalfunctionrenderTrackingCategories()ifargs.decat~='yes'thenif#(getArgNums('data'))==0andmw.title.getCurrentTitle().namespace==0thenroot.wikitext('[[Category:使用无数据行信息框模板的条目]]')endifargs.child=='yes'andargs.titlethenroot.wikitext('[[Category:使用带有标题参数的嵌入式信息框模板的条目]]')endendendlocalfunction_infobox()-- Specify the overall layout of the infobox, with special settings-- if the infobox is used as a 'child' inside another infobox.ifargs.child~='yes'thenroot=HtmlBuilder.create('table')root.addClass('infobox').addClass(args.bodyclass).attr('cellspacing',3).css('border-spacing','3px')ifargs.subbox=='yes'thenroot.css('padding','0').css('border','none').css('margin','-3px').css('width','auto').css('min-width','100%').css('font-size','small').css('clear','none').css('float','none').css('background-color','transparent')elseroot.css('width','22em').css('text-align','left').css('font-size','small').css('line-height','1.5em')endroot.cssText(args.bodystyle)renderTitle()renderAboveRow()elseroot=HtmlBuilder.create()root.wikitext(args.title)endrenderOverImage()renderSubheaders()renderImages()renderRows()renderBelowRow()renderNavBar()renderItalicTitle()renderTrackingCategories()returntostring(root)endlocalfunctionpreprocessSingleArg(argName)-- If the argument exists and isn't blank, add it to the argument table.-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.iforigArgs[argName]andorigArgs[argName]~=''thenargs[argName]=origArgs[argName]endendlocalfunctionpreprocessArgs(prefixTable,step)-- Assign the parameters with the given prefixes to the args table, in order, in batches-- of the step size specified. This is to prevent references etc. from appearing in the-- wrong order. The prefixTable should be an array containing tables, each of which has-- two possible fields, a "prefix" string and a "depend" table. The function always parses-- parameters containing the "prefix" string, but only parses parameters in the "depend"-- table if the prefix parameter is present and non-blank.iftype(prefixTable)~='table'thenerror("Non-table value detected for the prefix table",2)endiftype(step)~='number'thenerror("Invalid step value detected",2)end-- Get arguments without a number suffix, and check for bad input.fori,vinipairs(prefixTable)doiftype(v)~='table'ortype(v.prefix)~="string"or(v.dependandtype(v.depend)~='table')thenerror('Invalid input detected to preprocessArgs prefix table',2)endpreprocessSingleArg(v.prefix)-- Only parse the depend parameter if the prefix parameter is present and not blank.ifargs[v.prefix]andv.dependthenforj,dependValueinipairs(v.depend)doiftype(dependValue)~='string'thenerror('Invalid "depend" parameter value detected in preprocessArgs')endpreprocessSingleArg(dependValue)endendend-- Get arguments with number suffixes.locala=1-- Counter variable.localmoreArgumentsExist=truewhilemoreArgumentsExist==truedomoreArgumentsExist=falsefori=a,a+step-1doforj,vinipairs(prefixTable)dolocalprefixArgName=v.prefix..tostring(i)iforigArgs[prefixArgName]thenmoreArgumentsExist=true-- Do another loop if any arguments are found, even blank ones.preprocessSingleArg(prefixArgName)end-- Process the depend table if the prefix argument is present and not blank, or-- we are processing "prefix1" and "prefix" is present and not blank, and-- if the depend table is present.ifv.dependand(args[prefixArgName]or(i==1andargs[v.prefix]))thenforj,dependValueinipairs(v.depend)dolocaldependArgName=dependValue..tostring(i)preprocessSingleArg(dependArgName)endendendenda=a+stependendfunctionpreprocessSpecificStyle(styleTable,step)-- Assign the parameters *style to the args tablelocala=1-- Counter variable.localmoreArgumentsExist=truewhilemoreArgumentsExist==truedomoreArgumentsExist=falsefori=a,a+step-1doforj,vinipairs(styleTable)dolocalstyleArgName=v.arg..tostring(i)..'style'iforigArgs[styleArgName]thenmoreArgumentsExist=true-- Do another loop if any arguments are found, even blank ones.preprocessSingleArg(styleArgName)endendenda=a+stependendfunctionp.infobox(frame)-- If called via #invoke, use the args passed into the invoking template.-- Otherwise, for testing purposes, assume args are being passed directly in.ifframe==mw.getCurrentFrame()thenorigArgs=frame:getParent().argselseorigArgs=frameend-- Parse the data parameters in the same order that the old {{infobox}} did, so that-- references etc. will display in the expected places. Parameters that depend on-- another parameter are only processed if that parameter is present, to avoid-- phantom references appearing in article reference lists.preprocessSingleArg('child')preprocessSingleArg('bodyclass')preprocessSingleArg('subbox')preprocessSingleArg('bodystyle')preprocessSingleArg('overimage')preprocessSingleArg('overcaption')preprocessSingleArg('overimagerowclass')preprocessSingleArg('title')preprocessSingleArg('titleclass')preprocessSingleArg('titlestyle')preprocessSingleArg('above')preprocessSingleArg('aboveclass')preprocessSingleArg('abovestyle')preprocessSingleArg('aboverowclass')preprocessArgs({{prefix='subheader',depend={'subheaderstyle','subheaderrowclass'}}},10)preprocessSingleArg('subheaderstyle')preprocessSingleArg('subheaderclass')preprocessArgs({{prefix='image',depend={'caption','imagerowclass'}}},10)preprocessSingleArg('captionstyle')preprocessSingleArg('imagestyle')preprocessSingleArg('imageclass')preprocessArgs({{prefix='header'},{prefix='data',depend={'label'}},{prefix='rowclass'},{prefix='class'}},80)preprocessSpecificStyle({{arg='header'},{arg='label'},{arg='data'}},80)preprocessSingleArg('headerstyle')preprocessSingleArg('labelstyle')preprocessSingleArg('datastyle')preprocessSingleArg('below')preprocessSingleArg('belowclass')preprocessSingleArg('belowstyle')preprocessSingleArg('name')args['italic title']=origArgs['italic title']-- different behaviour if blank or absentpreprocessSingleArg('decat')return_infobox()endreturnp