Jump to content

Module:Infobox

Permanently protected module
From Wikipedia, the free encyclopedia

localp={}localargs={}localorigArgs={}localrootlocalempty_row_categories={}localcategory_in_empty_row_pattern='%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]'localhas_rows=falselocallists={plainlist_t={patterns={'^plainlist$','%splainlist$','^plainlist%s','%splainlist%s'},found=false,styles='Plainlist/styles.css'},hlist_t={patterns={'^hlist$','%shlist$','^hlist%s','%shlist%s'},found=false,styles='Hlist/styles.css'}}localfunctionhas_list_class(args_to_check)for_,listinpairs(lists)doifnotlist.foundthenfor_,arginpairs(args_to_check)dofor_,patterninipairs(list.patterns)doifmw.ustring.find(argor'',pattern)thenlist.found=truebreakendendiflist.foundthenbreakendendendendendlocalfunctionfixChildBoxes(sval,tt)localfunctionnotempty(s)returnsands:match('%S')endifnotempty(sval)thenlocalmarker='<span class=special_infobox_marker>'locals=sval-- start moving templatestyles and categories inside of table rowslocalslast=''whileslast~=sdoslast=ss=mw.ustring.gsub(s,'(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])','%2%1')s=mw.ustring.gsub(s,'(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)','%2%1')end-- end moving templatestyles and categories inside of table rowss=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>'endendendend-- the next two lines add a newline at the end of lists for the PHP parser-- [[Special:Diff/849054481]]-- remove when [[:phab:T191516]] is fixed or OBEs=mw.ustring.gsub(s,'([\r\n][%*#;:][^\r\n]*)$','%1\n')s=mw.ustring.gsub(s,'^([%*#;:][^\r\n]*)$','%1\n')s=mw.ustring.gsub(s,'^([%*#;:])','\n%1')s=mw.ustring.gsub(s,'^(%{%|)','\n%1')returnselsereturnsvalendend-- Cleans empty tableslocalfunctioncleanInfobox()root=tostring(root)ifhas_rows==falsethenroot=mw.ustring.gsub(root,'<table[^<>]*>%s*</table>','')endend-- Returns the union of the values of two tables, as a sequence.localfunctionunion(t1,t2)localvals={}fork,vinpairs(t1)dovals[v]=trueendfork,vinpairs(t2)dovals[v]=trueendlocalret={}fork,vinpairs(vals)dotable.insert(ret,k)endreturnretend-- 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}.localfunctiongetArgNums(prefix)localnums={}fork,vinpairs(args)dolocalnum=tostring(k):match('^'..prefix..'([1-9]%d*)$')ifnumthentable.insert(nums,tonumber(num))endendtable.sort(nums)returnnumsend-- Adds a row to the infobox, with either a header cell-- or a label/data cell combination.localfunctionaddRow(rowArgs)ifrowArgs.headerandrowArgs.header~='_BLANK_'thenhas_rows=truehas_list_class({rowArgs.rowclass,rowArgs.class,args.headerclass})root:tag('tr'):addClass(rowArgs.rowclass):cssText(rowArgs.rowstyle):tag('th'):attr('colspan','2'):addClass('infobox-header'):addClass(rowArgs.class):addClass(args.headerclass)-- @deprecated next; target .infobox-<name> .infobox-header:cssText(args.headerstyle):cssText(rowArgs.rowcellstyle):wikitext(fixChildBoxes(rowArgs.header,'th'))ifrowArgs.datathenroot:wikitext('[[Category:Pages using infobox templates with ignored data cells]]')endelseifrowArgs.dataandrowArgs.data:gsub(category_in_empty_row_pattern,''):match('^%S')thenhas_rows=truehas_list_class({rowArgs.rowclass,rowArgs.class})localrow=root:tag('tr')row:addClass(rowArgs.rowclass)row:cssText(rowArgs.rowstyle)ifrowArgs.labelthenrow:tag('th'):attr('scope','row'):addClass('infobox-label')-- @deprecated next; target .infobox-<name> .infobox-label:cssText(args.labelstyle):cssText(rowArgs.rowcellstyle):wikitext(rowArgs.label):done()endlocaldataCell=row:tag('td')dataCell:attr('colspan',notrowArgs.labeland'2'ornil):addClass(notrowArgs.labeland'infobox-full-data'or'infobox-data'):addClass(rowArgs.class)-- @deprecated next; target .infobox-<name> .infobox(-full)-data:cssText(rowArgs.datastyle):cssText(rowArgs.rowcellstyle):wikitext(fixChildBoxes(rowArgs.data,'td'))elsetable.insert(empty_row_categories,rowArgs.dataor'')endendlocalfunctionrenderTitle()ifnotargs.titlethenreturnendhas_rows=truehas_list_class({args.titleclass})root:tag('caption'):addClass('infobox-title'):addClass(args.titleclass)-- @deprecated next; target .infobox-<name> .infobox-title:cssText(args.titlestyle):wikitext(args.title)endlocalfunctionrenderAboveRow()ifnotargs.abovethenreturnendhas_rows=truehas_list_class({args.aboveclass})root:tag('tr'):tag('th'):attr('colspan','2'):addClass('infobox-above'):addClass(args.aboveclass)-- @deprecated next; target .infobox-<name> .infobox-above:cssText(args.abovestyle):wikitext(fixChildBoxes(args.above,'th'))endlocalfunctionrenderBelowRow()ifnotargs.belowthenreturnendhas_rows=truehas_list_class({args.belowclass})root:tag('tr'):tag('td'):attr('colspan','2'):addClass('infobox-below'):addClass(args.belowclass)-- @deprecated next; target .infobox-<name> .infobox-below:cssText(args.belowstyle):wikitext(fixChildBoxes(args.below,'td'))endlocalfunctionaddSubheaderRow(subheaderArgs)ifsubheaderArgs.dataandsubheaderArgs.data:gsub(category_in_empty_row_pattern,''):match('^%S')thenhas_rows=truehas_list_class({subheaderArgs.rowclass,subheaderArgs.class})localrow=root:tag('tr')row:addClass(subheaderArgs.rowclass)localdataCell=row:tag('td')dataCell:attr('colspan','2'):addClass('infobox-subheader'):addClass(subheaderArgs.class):cssText(subheaderArgs.datastyle):cssText(subheaderArgs.rowcellstyle):wikitext(fixChildBoxes(subheaderArgs.data,'td'))elsetable.insert(empty_row_categories,subheaderArgs.dataor'')endendlocalfunctionrenderSubheaders()ifargs.subheaderthenargs.subheader1=args.subheaderendifargs.subheaderrowclassthenargs.subheaderrowclass1=args.subheaderrowclassendlocalsubheadernums=getArgNums('subheader')fork,numinipairs(subheadernums)doaddSubheaderRow({data=args['subheader'..tostring(num)],-- @deprecated next; target .infobox-<name> .infobox-subheaderdatastyle=args.subheaderstyle,rowcellstyle=args['subheaderstyle'..tostring(num)],class=args.subheaderclass,rowclass=args['subheaderrowclass'..tostring(num)]})endendlocalfunctionaddImageRow(imageArgs)ifimageArgs.dataandimageArgs.data:gsub(category_in_empty_row_pattern,''):match('^%S')thenhas_rows=truehas_list_class({imageArgs.rowclass,imageArgs.class})localrow=root:tag('tr')row:addClass(imageArgs.rowclass)localdataCell=row:tag('td')dataCell:attr('colspan','2'):addClass('infobox-image'):addClass(imageArgs.class):cssText(imageArgs.datastyle):wikitext(fixChildBoxes(imageArgs.data,'td'))elsetable.insert(empty_row_categories,imageArgs.dataor'')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'):addClass('infobox-caption')-- @deprecated next; target .infobox-<name> .infobox-caption:cssText(args.captionstyle):wikitext(caption)endaddImageRow({data=tostring(data),-- @deprecated next; target .infobox-<name> .infobox-imagedatastyle=args.imagestyle,class=args.imageclass,rowclass=args['imagerowclass'..tostring(num)]})endend-- When autoheaders are turned on, preprocesses the rowslocalfunctionpreprocessRows()ifnotargs.autoheadersthenreturnendlocalrownums=union(getArgNums('header'),getArgNums('data'))table.sort(rownums)locallastheaderfork,numinipairs(rownums)doifargs['header'..tostring(num)]theniflastheaderthenargs['header'..tostring(lastheader)]=nilendlastheader=numelseifargs['data'..tostring(num)]andargs['data'..tostring(num)]:gsub(category_in_empty_row_pattern,''):match('^%S')thenlocaldata=args['data'..tostring(num)]ifdata:gsub(category_in_empty_row_pattern,''):match('%S')thenlastheader=nilendendendiflastheaderthenargs['header'..tostring(lastheader)]=nilendend-- Gets the union of the header and data argument numbers,-- and renders them all in orderlocalfunctionrenderRows()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)],-- @deprecated next; target .infobox-<name> rowclassrowstyle=args['rowstyle'..tostring(num)],rowcellstyle=args['rowcellstyle'..tostring(num)]})endendlocalfunctionrenderNavBar()ifnotargs.namethenreturnendhas_rows=trueroot:tag('tr'):tag('td'):attr('colspan','2'):addClass('infobox-navbar'):wikitext(require('Module:Navbar')._navbar{args.name,mini=1,})endlocalfunctionrenderItalicTitle()localitalicTitle=args['italic title']andmw.ustring.lower(args['italic title'])ifitalicTitle==''oritalicTitle=='force'oritalicTitle=='yes'thenroot:wikitext(require('Module:Italic title')._main({}))endend-- Categories in otherwise empty rows are collected in empty_row_categories.-- This function adds them to the module output. It is not affected by-- args.decat because this module should not prevent module-external categories-- from rendering.localfunctionrenderEmptyRowCategories()for_,sinipairs(empty_row_categories)doroot:wikitext(s)endend-- Render tracking categories. args.decat == turns off tracking categories.localfunctionrenderTrackingCategories()ifargs.decat=='yes'thenreturnendifargs.child=='yes'thenifargs.titlethenroot:wikitext('[[Category:Pages using embedded infobox templates with the title parameter]]')endelseif#(getArgNums('data'))==0andmw.title.getCurrentTitle().namespace==0thenroot:wikitext('[[Category:Articles using infobox templates with no data rows]]')endend--[=[Loads the templatestyles for the infobox.TODO: FINISH loading base templatestyles here rather than inMediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).When we do this we should clean up the inline CSS below too.Will have to do some bizarre conversion category like with sidebar.]=]localfunctionloadTemplateStyles()localframe=mw.getCurrentFrame()localhlist_templatestyles=''iflists.hlist_t.foundthenhlist_templatestyles=frame:extensionTag{name='templatestyles',args={src=lists.hlist_t.styles}}endlocalplainlist_templatestyles=''iflists.plainlist_t.foundthenplainlist_templatestyles=frame:extensionTag{name='templatestyles',args={src=lists.plainlist_t.styles}}end-- See function descriptionlocalbase_templatestyles=frame:extensionTag{name='templatestyles',args={src='Module:Infobox/styles.css'}}localtemplatestyles=''ifargs['templatestyles']thentemplatestyles=frame:extensionTag{name='templatestyles',args={src=args['templatestyles']}}endlocalchild_templatestyles=''ifargs['child templatestyles']thenchild_templatestyles=frame:extensionTag{name='templatestyles',args={src=args['child templatestyles']}}endlocalgrandchild_templatestyles=''ifargs['grandchild templatestyles']thengrandchild_templatestyles=frame:extensionTag{name='templatestyles',args={src=args['grandchild templatestyles']}}endreturntable.concat({-- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering.-- this ordering is not a guarantee because the rows of interest invoking-- each class may not be on a specific pagehlist_templatestyles,plainlist_templatestyles,base_templatestyles,templatestyles,child_templatestyles,grandchild_templatestyles})end-- common functions between the child and non child caseslocalfunctionstructure_infobox_common()renderSubheaders()renderImages()preprocessRows()renderRows()renderBelowRow()renderNavBar()renderItalicTitle()renderEmptyRowCategories()renderTrackingCategories()cleanInfobox()end-- Specify the overall layout of the infobox, with special settings if the-- infobox is used as a 'child' inside another infobox.localfunction_infobox()ifargs.child~='yes'thenroot=mw.html.create('table')root:addClass(args.subbox=='yes'and'infobox-subbox'or'infobox'):addClass(args.bodyclass)-- @deprecated next; target .infobox-<name>:cssText(args.bodystyle)has_list_class({args.bodyclass})renderTitle()renderAboveRow()elseroot=mw.html.create()root:wikitext(args.title)endstructure_infobox_common()returnloadTemplateStyles()..rootend-- 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.localfunctionpreprocessSingleArg(argName)iforigArgs[argName]andorigArgs[argName]~=''thenargs[argName]=origArgs[argName]endend-- 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.localfunctionpreprocessArgs(prefixTable,step)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]then-- Do another loop if any arguments are found, even blank ones.moreArgumentsExist=truepreprocessSingleArg(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+stependend-- 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.localfunctionparseDataParameters()preprocessSingleArg('autoheaders')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'}},50)preprocessSingleArg('headerclass')preprocessSingleArg('headerstyle')preprocessSingleArg('labelstyle')preprocessSingleArg('datastyle')preprocessSingleArg('below')preprocessSingleArg('belowclass')preprocessSingleArg('belowstyle')preprocessSingleArg('name')-- different behaviour for italics if blank or absentargs['italic title']=origArgs['italic title']preprocessSingleArg('decat')preprocessSingleArg('templatestyles')preprocessSingleArg('child templatestyles')preprocessSingleArg('grandchild templatestyles')end-- If called via #invoke, use the args passed into the invoking template.-- Otherwise, for testing purposes, assume args are being passed directly in.functionp.infobox(frame)ifframe==mw.getCurrentFrame()thenorigArgs=frame:getParent().argselseorigArgs=frameendparseDataParameters()return_infobox()end-- For calling via #invoke within a templatefunctionp.infoboxTemplate(frame)origArgs={}fork,vinpairs(frame.args)doorigArgs[k]=mw.text.trim(v)endparseDataParameters()return_infobox()endreturnp
close