---- This module implements {{Infobox}}--localp={}localnavbar=require('Module:Navbar')._navbarlocalargs={}localorigArgslocalrootlocalfunctionnotempty(s)returnsands:match('%S')endlocalfunctionfixChildBoxes(sval,tt)ifnotempty(sval)thenlocalmarker='<span class=special_infobox_marker>'locals=svals=mw.ustring.gsub(s,'(<%s*[Tt][Rr])',marker..'%1')s=mw.ustring.gsub(s,'(</[Tt][Rr]%s*>)','%1'..marker)ifs:match(marker)thens=mw.ustring.gsub(s,marker..'%s*'..marker,'')s=mw.ustring.gsub(s,'([\r\n]|-[^\r\n]*[\r\n])%s*'..marker,'%1')s=mw.ustring.gsub(s,marker..'%s*([\r\n]|-)','%1')s=mw.ustring.gsub(s,'(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)'..marker,'%1')s=mw.ustring.gsub(s,'(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)'..marker,'%1')s=mw.ustring.gsub(s,'^(%{|[^\r\n]*[\r\n]%s*)'..marker,'%1')s=mw.ustring.gsub(s,'([\r\n]%{|[^\r\n]*[\r\n]%s*)'..marker,'%1')s=mw.ustring.gsub(s,marker..'(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)','%1')s=mw.ustring.gsub(s,marker..'(%s*\n|%})','%1')endifs:match(marker)thenlocalsubcells=mw.text.split(s,marker)s=''fork=1,#subcellsdoifk==1thens=s..subcells[k]..'</'..tt..'></tr>'elseifk==#subcellsthenlocalrowstyle=' style="display:none"'ifnotempty(subcells[k])thenrowstyle=''ends=s..'<tr'..rowstyle..'><'..tt..' colspan=2>\n'..subcells[k]elseifnotempty(subcells[k])thenif(k%2)==0thens=s..subcells[k]elses=s..'<tr><'..tt..' colspan=2>\n'..subcells[k]..'</'..tt..'></tr>'endendendendreturnselsereturnsvalendendlocalfunctionunion(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):cssText(rowArgs.rowstyle):attr('id',rowArgs.rowid):tag('th'):attr('colspan',2):attr('id',rowArgs.headerid):addClass(rowArgs.class):addClass(args.headerclass):css('text-align','center'):cssText(args.headerstyle):cssText(rowArgs.rowcellstyle):wikitext(fixChildBoxes(rowArgs.header,'th'))elseifrowArgs.datathenlocalrow=root:tag('tr')row:addClass(rowArgs.rowclass)row:cssText(rowArgs.rowstyle)row:attr('id',rowArgs.rowid)ifrowArgs.labelthenrow:tag('th'):attr('scope','row'):attr('id',rowArgs.labelid):cssText(args.labelstyle):cssText(rowArgs.rowcellstyle):wikitext(rowArgs.label):done()endlocaldataCell=row:tag('td')ifnotrowArgs.labelthendataCell:attr('colspan',2):css('text-align','center')enddataCell:attr('id',rowArgs.dataid):addClass(rowArgs.class):cssText(rowArgs.datastyle):cssText(rowArgs.rowcellstyle):newline():wikitext(fixChildBoxes(rowArgs.data,'td'))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(fixChildBoxes(args.above,'th'))endlocalfunctionrenderBelowRow()ifnotargs.belowthenreturnendroot:tag('tr'):tag('td'):attr('colspan','2'):addClass(args.belowclass):css('text-align','center'):cssText(args.belowstyle):newline():wikitext(fixChildBoxes(args.below,'td'))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=mw.html.create():wikitext(args['image'..tostring(num)])ifcaptionthendata: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)],label=args['label'..tostring(num)],data=args['data'..tostring(num)],datastyle=args.datastyle,class=args['class'..tostring(num)],rowclass=args['rowclass'..tostring(num)],rowstyle=args['rowstyle'..tostring(num)],rowcellstyle=args['rowcellstyle'..tostring(num)],dataid=args['dataid'..tostring(num)],labelid=args['labelid'..tostring(num)],headerid=args['headerid'..tostring(num)],rowid=args['rowid'..tostring(num)]})endendlocalfunctionrenderNavBar()ifnotargs.namethenreturnendroot:tag('tr'):tag('td'):attr('colspan','2'):css('text-align','right'):wikitext(navbar{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('[[زمرہ:بغیر ڈیٹا رو کے خانہ معلومات سانچے استعمال کرنے والے مضامین]]')endifargs.child=='yes'andargs.titlethenroot:wikitext('[[زمرہ:بغیر ڈیٹا رو کے خانہ معلومات سانچے استعمال کرنے والے مضامین]]')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=mw.html.create('table')root:addClass((args.subbox~='yes')and'infobox'ornil):addClass(args.bodyclass)ifargs.subbox=='yes'thenroot:css('padding','0'):css('border','none'):css('margin','-3px'):css('width','auto'):css('min-width','100%'):css('font-size','100%'):css('clear','none'):css('float','none'):css('background-color','transparent')elseroot:css('width','22em')endroot:cssText(args.bodystyle)renderTitle()renderAboveRow()elseroot=mw.html.create()root:wikitext(args.title)endrenderSubheaders()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+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('title')preprocessSingleArg('titleclass')preprocessSingleArg('titlestyle')preprocessSingleArg('above')preprocessSingleArg('aboveclass')preprocessSingleArg('abovestyle')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='rowstyle'},{prefix='rowcellstyle'},{prefix='class'},{prefix='dataid'},{prefix='labelid'},{prefix='headerid'},{prefix='rowid'}},50)preprocessSingleArg('headerclass')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