| Modul ini dinilai siap digunakan secara umum. Modul ini sudah matang dan diperkirakan bebas dari bug dan siap digunakan pada tempat yang tepat di manapun. Modul ini siap disinggung di halaman-halaman bantuan dan sumber informasi Wikipedia lainnya sebagai pilihan untuk dipelajari para pengguna baru. Untuk mengurangi beban server dan output yang tidak diharapkan, modul ini harus diperlengkapi dengan halaman bak pasir dan kasus uji daripada harus melakukan suntingan coba-dan-salah berulang-ulang. |
Modul ini dipergunakan untuk templat {{Routemap}}, {{BSsplit}}, {{BSto}}, {{BScvt}}, {{BSsrws}}, {{RoutemapRoute}}, dan {{RoutemapRouteIcon}}. Untuk kegunaan templat tersebut silakan lihat pada templatnya.
Silakan melakukan uji coba modul pada Template:Routemap/testcases dan Template:BSsplit/testcases.
Dokumentasi di atas ditransklusikan dari Modul:Routemap/doc. (sunting | riwayat)
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
locali18n={ errors={ ["parameter-missing"]="Kehilangan parameter!", ["collapsible-block-not-closed"]="Bagian yang dapat diciutkan tidak ditutup dengan benar!", ["collapsible-block-not-open"]="Tidak ada markah start-Collapsible!", ["collapsible-block-empty"]="Bagian yang dapat diciutkan tidak boleh kosong!", ["collapsible-block-no-first-row"]="Baris pertama bagian yang dapat diciutkan tidak valid", ["collapsible-block-no-replacement"]="Baris pengganti yang dapat diciutkan tidak valid!", ["colspan-less-rows-than-set"]="Set colspan tidak valid!", }, ["error-categories"]={ default='[[Category:Halaman yang menggunakan Routemap dengan galat]]', ["text-images"]='[[Category:Halaman yang menggunakan Routemap dengan gambar teks]]', ["separate-navbar"]='[[Category:Halaman yang menggunakan Routemap dengan templat navbar terpisah]]', ["missing-text-values"]='[[Kategori:Halaman yang menggunakan BSto atau BSsrws tanpa nilai teks]]', ["br-tags"]='[[Category:Halaman yang menggunakan BSto, BSsplit, BSsrws, atau BScvt dengan tag br]]', ["srws"]='[[Category:Halaman yang menggunakan BSsplit alih-alih BSsrws]]', ["rmr-error"]='[[Category:Halaman dengan nilai buruk untuk templat RoutemapRoute]]' }, text={ navbar_mini=false,-- for navbar pos 2 only navbar_text='Diagram ini:',-- for navbar pos 2 only legend_text='Legenda', legend={ default='[[Template:Legenda jalur rel', track='[[Template:Legenda tata letak stasiun', bus='[[Template:Legenda rute bus', canal='[[Template:Legenda transportasi air', water='[[Template:Legenda transportasi air', waterway='[[Template:Legenda transportasi air', foot='[[Template:Trails legend', footpath='[[Template:Trails legend', walkway='[[Template:Trails legend' } }, html={ ["cell-icon-fmt"]='<div style="%s">[[File:BSicon_%s.svg|x20px|link=%s|alt=|%s]]%s</div>', ["cell-overlapicon-fmt"]='<div class="RMic" style="%s">[[File:BSicon_%s.svg|x20px|link=%s|alt=|%s]]</div>', ["cell-icon-fmt-with-overlap"]='<div style="%s"><div class="RMov">%s</div><div%s>[[File:BSicon_%s.svg|x20px|link=|alt=|%s]]%s</div></div>', ["cell-text-fmt"]='<div class="RMtx RM%s" style="%s"><div%s style="%s" title="%s">%s%s%s%s%s%s</div></div>', ["cell-overlaptext-fmt"]='<div class="RMtx RM%s" style="%s"><div%s style="%s" title="%s">%s%s%s%s%s</div></div>', ["cell-text-fmt-with-overlap"]='<div class="RM%s" style="%s"><div class="RMov">%s</div><div class="RMtx RM%s" style="%s"><div%s style="%s" title="%s">%s%s%s%s%s%s</div></div></div>', ["cell-empty-fmt"]='<div class="RM%s" style="%s">%s</div>', ["cell-empty-fmt-with-overlap"]='<div style="%s"><div class="RMov">%s</div><div class="RMsp RM%s" style="%s">%s</div></div>', ["cell-filler-fmt"]='<div class="RMf_" style="%s"><div class="RMfm" style="background:%s"></div></div>', ["cell-filler-empty-fmt"]='<div class="RMf_ RM%s" style="%s"></div>', ["row-linfo4-fmt"]='\ |class="RMl4" style="%s"|<div class="RMsi">%s</div>',-- parameters:linfo4-width, linfo4 ["row-linfo3-fmt"]='<div class="RMsi">%s</div> ', ["row-rinfo3-fmt"]=' <div class="RMsi">%s</div>', ["row-rinfo4-fmt"]='\ |class="RMr4" style="%s"|<div class="RMsi">%s</div>',-- parameters:rinfo4-width, rinfo4 ["row-general-fmt"]='\ |- %s\ |class="RMl" colspan="%s" style="%s"|%s\ |%s style="%s"|<div class="RMsi">%s</div>\ |class="RMir" style="%s"|%s\ |%s style="%s"|<div class="RMsi">%s</div>\ |class="RMr" colspan="%s" style="%s"|%s%s',-- parameters: linfo4-fmt, colspan-left, linfo3+2-width, linfo3+2, linfo1-pad, linfo1-width, linfo1, bg, cells, rinfo1-pad, rinfo1-width, rinfo1, colspan-right, rinfo2+3-width, rinfo2+3, rinfo4-fmt ["row-collapsible-begin-fmt"]='\ |- style="line-height:1"\ |colspan="7" style="padding:0 !important;background:%s"|\ {|class="RMcollapse %s%s" style="%s"',-- parameters: bg, "collapsible "/"mw-collapsible mw-", collapse-state, "float:right" / "" ["row-collapsible-end-fmt"]='\n|}', ["row-collapsible-left-button-width"]='45px',-- 50px is the minimal width for [показать] / [скрыть] button. Use 40px for [show] / [hide] ["row-collapsible-left-button-fmt"]='\n! style="padding-right:3px;min-width:%s;%s" |',--parameters: left-button-width, linfo4-width ["row-collapsible-left-linfo4+3+2-fmt"]='\ {|cellspacing="0" cellpadding="0" style="line-height:1;width:100%%;padding:0 !important;margin:0 !important"\ |style="padding:0 3px 0 1px;text-align:left"|<div class="RMsi">%s</div>\ |style="text-align:right"| %s\ |}',-- parameters: linfo4, linfo3+2 ["row-collapsible-right-button-width"]='45px',-- 72px is the minimal width for [развернуть] / [свернуть] button at 90%. Use 58px for [expand] / [collapse] ["row-collapsible-right-rinfo2+3+4-fmt"]='\ {|cellspacing="0" cellpadding="0" style="line-height:1;width:100%%;padding:0 !important;margin:0 !important"\ |style="text-align:left"| %s\ |style="padding:0 1px 0 3px;text-align:right"|<div class="RMsi">%s</div>\ |}',-- parameters: rinfo2+3, linfo4 ["row-collapsible-right-button-fmt"]='\n| style="padding-left:3px;font-size:90%%;min-width:%s;%s" |',--parameters: right-button-width, rinfo4-width ["row-collapsible-replace-begin-fmt"]='\ |- style="line-height:1"\ |colspan="7" style="padding:0 %s"|<div style="position:relative">\ {| class="RMreplace" style="%sbackground:%s"',-- parameters: "right-button-width 0 0" / "0 0 left-button-width", "right:0px" / "", bg ["row-collapsible-replace-end-fmt"]='\n|}</div>', ["colspan-fmt"]='%s\n|-\n| colspan="7" style="background:%s;text-align:%s;%s"|\n%s', ["empty-row-fmt"]='\n|-\n|style="padding:0 3px 0 0;%s"|\n|style="%s"|\n|%s style="%s"|\n|\n|%s style="%s"|\n|style="%s"|\n|style="padding:0 0 0 3px;%s"|' } } localp,q={},{} localgetArgs=require('Module:Arguments').getArgs localfunctionmakeInvokeFunction(funcName) -- makes a function that can be returned from #invoke, using -- [[Module:Arguments]]. returnfunction(frame) localargs=getArgs(frame,{parentOnly=true}) returnp[funcName](args) end end localfunctionformaterror(key,param) localresult=string.format(i18n.html['colspan-fmt'],'','','','','<span class="error">'..string.format(i18n.errors[key]or(tostring(key)..' %s'), tostring(paramor''))..'</span>') ifmw.site.namespaces[mw.title.getCurrentTitle().namespace].isContentthenresult=result..(i18n['error-categories'][key]ori18n['error-categories'].defaultor'')end returnresult end localfunctionRGBbyCode(code)-- RGB codes for BSicon sets at Commons:Category:Icons for railway descriptions/other colors localcolors={-- Any changes should be discussed at Commons:Talk:BSicon/Colors bahn='BE2D2C',ex='D77F7E', u='003399',uex='6281C0', f='008000',fex='64B164', g='2CA05A',gex='7EC49A', azure='3399FF',ex_azure='99CCFF', black='000000',ex_black='646464', blue='0078BE',ex_blue='64ACD6', brown='8D5B2D',ex_brown='B89A7F', carrot='ED9121',ex_carrot='F1BA76',excarrot='F1BA76',ex_excarrot='F3D2A9', cerulean='1A8BB9',ex_cerulean='73B7D3', cyan='40E0D0',ex_cyan='8AEAE1', deepsky='00BFFF',ex_deepsky='7FDFFF', denim='00619F',ex_denim='649EC3', fuchsia='B5198D',ex_fuchsia='D173B8', golden='D7C447',ex_golden='E5DA8E', green='2DBE2C',ex_green='7FD67E', grey='999999',ex_grey='C0C0C0', jade='53B147',ex_jade='95CE8E', lavender='9999FF',ex_lavender='C0C0FF', lime='99CC00',ex_lime='D1E681', maroon='800000',ex_maroon='B16464', ochre='CC6600',ex_ochre='DEA164', olive='837902',ex_olive='B2AC64', orange='FF6600',ex_orange='FF9955', pink='F0668D',ex_pink='F4A1B8', purple='8171AC',ex_purple='B1A8CB', red='EF161E',ex_red='F37176', ruby='CC0066',ex_ruby='DE64A1',exruby='DE64A1',ex_exruby='E89FC4', saffron='FFAB2E',ex_saffron='FFC969', sky='069DD3',ex_sky='67C2E3', steel='A1B3D4',ex_steel='C4CFE3', teal='339999',ex_teal='82C0C0',exteal='82C0C0',ex_exteal='B1D6D6', violet='800080',ex_violet='B164B1', yellow='FFD702',ex_yellow='FFEB81', } returncolors[code]orcolors.bahn end p.RGBbyCode=makeInvokeFunction('_RGBbyCode') functionp._RGBbyCode(args) returnRGBbyCode(args[1]) end localfunctionproperties(str) --str is a combination of properties with following syntax: --property name=value,property name1=value1,property name2=value2 and so on localresult={} fori,vinipairs(mw.text.split(str,','))do ifvthen localt=mw.text.split(v,'=') ifstring.find(v,'=')then t[1]=mw.text.trim(t[1])--trim parameter names table.insert(result,t[1]) result[t[1]]=t[2]or''--fill table with pairs "property"="value" elseifresult[result[i-1]]then table.insert(result,result[i-1]) result[result[i]]=result[result[i]]..','..t[1]--if no equals sign then tack t[1] onto the previous result else table.insert(result,'~~') end else table.insert(result,'~~') end end returnresult end localfunctionpositive(x) ifnotxthenreturnnilelsex=string.lower(x)end ifx=='yes'orx=='y'orx=='1'orx=='true'thenreturn1end end localfunctionnegative(x) ifnotxthenreturnnilelsex=string.lower(x)end ifx=='no'orx=='n'orx=='0'orx=='false'thenreturn0end end localfunctionalignment(x,y,z) ifnotxthenreturnnilend localdirections={ ['inherit-left']={'l','left',}, ['inherit-right']={'r','right',}, ['top-inherit']={'a','t','top',}, ['bottom-inherit']={'e','b','bottom',}, ['top-left']={'la','tl','c4','nw','top-left','topleft',}, ['top-right']={'ra','tr','c1','ne','top-right','topright',}, ['bottom-left']={'le','bl','c3','sw','bottom-left','bottomleft',}, ['bottom-right']={'re','br','c2','se','bottom-right','bottomright',}, ['inherit-center']={'c','center','centre',}, ['middle-inherit']={'m','middle',}, ['top-center']={'ma','tc','top-center','top-centre','topcenter','topcentre',}, ['bottom-center']={'me','bc','bottom-center','bottom-centre','bottomcenter','bottomcentre',}, ['middle-left']={'lm','ml','middle-left','middleleft',}, ['middle-right']={'rm','mr','middle-right','middleright',}, ['middle-center']={'cm','mc','middle-center','middle-centre','middlecenter','middlecentre',}, } fork,vinpairs(directions)do for_,nameinipairs(v)do ifx:lower()==namethen localvalues=mw.text.split(k,'-') ifvalues[1]=='inherit'thenvalues[1]=yend ifvalues[2]=='inherit'thenvalues[2]=zend returnvalues end end end return{y,z} end localfunctioncell(icon,overlapIcons,rowProps)--[[ Icon handling. Each icon is defined as in the following example: icon ID!~overlap icon ID!@image link target Values for an icon ID containing "*" are treated as text, with the letter(s) before "*" as width prefix(es). No limit on overlapping icons or text; just separate them by "!~". Parameters can be added after every object, separated to the left by "!_". This, if there is a link, must be after the link. Parameters for individual objects in an overlapping stack can also be added, separated to the left by "__". Unless a link is provided, each cell will have mouseover text indicating its contents. ]] localtmp,tmp2,cellProps,iconProps,overlapProps,tmp_sep,link,tracking,icontext,iconpre={},{},{},{},{},'','','' if#overlapIcons>0then tmp=mw.text.split(overlapIcons[#overlapIcons],'!_') if#tmp>1thenoverlapIcons[#overlapIcons],cellProps=tmp[1],properties(tmp[2])end tmp=mw.text.split(overlapIcons[#overlapIcons],'!@') overlapIcons[#overlapIcons]=tmp[1] if#tmp>1thenlink=tmp[2]end tmp=mw.text.split(icon,'__') icon=tmp[1] if#tmp>1theniconProps=properties(tmp[2])end fori,vinipairs(overlapIcons)do tmp=mw.text.split(v,'__') overlapIcons[i]=mw.text.trim(tmp[1]) if#tmp>1thenoverlapProps[i]=properties(tmp[2])elseoverlapProps[i]={}end end else tmp=mw.text.split(icon,'[!_]_') if#tmp>1thenicon,cellProps=tmp[1],properties(tmp[2])end tmp=mw.text.split(icon,'!@') icon=mw.text.trim(tmp[1]) if#tmp>1thenlink=tmp[2]end end if#overlapIcons>0andicon~=''thentmp_sep='; 'end localicontip=mw.text.nowiki(mw.text.unstripNoWiki(icon..tmp_sep..table.concat(overlapIcons,'; '))) localtextspl=string.find(icon,'%*') iftextsplthen icontext=mw.text.trim(mw.ustring.sub(icon,textspl+1)) iftextspl~=1theniconpre=mw.text.trim(mw.ustring.sub(icon,1,textspl-1))end end cellProps.class='' ifcellProps.stylethencellProps.style=';'..cellProps.styleelsecellProps.style=''end cellProps.bg=cellProps.bgorcellProps.backgroundorcellProps.bgcolor ifcellProps.bgthencellProps.style=cellProps.style..';background:'..cellProps.bgend if#overlapIcons>0oricontextthen cellProps._before,cellProps._after=rowProps._beforeor'',rowProps._afteror'' cellProps.color=cellProps.colororcellProps.colour;cellProps.bold=cellProps.boldorcellProps.b;cellProps.italic=cellProps.italicorcellProps.iorcellProps.it ifcellProps.colorthencellProps.style=cellProps.style..';color:'..cellProps.colorend ifpositive(cellProps.italic)thencellProps.style=cellProps.style..';font-style:italic'end ifpositive(cellProps.bold)thencellProps.style=cellProps.style..';font-weight:bold'end ifnotcellProps.fontsizeorrowProps.fontsizeorcellProps.fontsize=='info'then elseifcellProps.fontsize=='cmt'orcellProps.fontsize=='comment'then cellProps._before,cellProps._after='<div class="RMsi">','</div>' else cellProps.style=cellProps.style..';font-size:'..cellProps.fontsize end ifcellProps.alignorrowProps.alignthen rowProps.align=rowProps.alignor{'middle','center'} cellProps.align=alignment(cellProps.align,rowProps.align[1],rowProps.align[2])orrowProps.align cellProps.style,cellProps.textfmt=cellProps.style..';text-align:'..cellProps.align[2],';vertical-align:'..cellProps.align[1] else cellProps.textfmt='' end end if#overlapIcons>0then tmp={} fori,vinipairs(overlapIcons)do localthislink=link ifi~=#overlapIconsthenthislink=''end ifthislinkandthislink~=''thenicontip=thislinkend ifoverlapProps[i].stylethenoverlapProps.style=';'..overlapProps[i].styleelseoverlapProps.style=''end overlapProps[i].bg=overlapProps[i].bgoroverlapProps[i].backgroundoroverlapProps[i].bgcolor ifoverlapProps[i].bgthenoverlapProps.style=overlapProps.style..';background:'..overlapProps[i].bgend localtmp_textspl=string.find(v,'%*') iftmp_textsplthen overlapProps.class='' localtmp_icontext,tmp_iconpre=mw.text.trim(mw.ustring.sub(v,tmp_textspl+1)),'' iftmp_textspl~=1thentmp_iconpre=mw.text.trim(mw.ustring.sub(v,1,tmp_textspl-1))end overlapProps._before,overlapProps._after=cellProps._before,cellProps._after overlapProps[i].color=overlapProps[i].colororoverlapProps[i].colour;overlapProps[i].bold=overlapProps[i].boldoroverlapProps[i].b;overlapProps[i].italic=overlapProps[i].italicoroverlapProps[i].ioroverlapProps[i].it ifoverlapProps[i].colorthenoverlapProps.style=overlapProps.style..';color:'..overlapProps[i].colorend ifpositive(overlapProps[i].italic)thenoverlapProps.style=overlapProps.style..';font-style:italic'end ifpositive(overlapProps[i].bold)thenoverlapProps.style=overlapProps.style..';font-weight:bold'end ifrowProps.fontsizeorcellProps.fontsizeoroverlapProps[i].fontsize=='info'then elseifnotoverlapProps[i].fontsizethen overlapProps.class=' class="RMts"' elseifoverlapProps[i].fontsize=='cmt'oroverlapProps[i].fontsize=='comment'then overlapProps._before,overlapProps._after='<div class="RMsi">','</div>' else overlapProps.style=overlapProps.style..';font-size:'..overlapProps[i].fontsize end ifoverlapProps[i].alignorcellProps.alignthen cellProps.align=cellProps.alignor{'middle','center'} overlapProps.align=alignment(overlapProps[i].align,cellProps.align[1],cellProps.align[2])orcellProps.align overlapProps.style,overlapProps.textfmt=overlapProps.style..';text-align:'..overlapProps.align[2],';vertical-align:'..overlapProps.align[1] else overlapProps.style,overlapProps.textfmt=overlapProps.style..';text-align:center',';vertical-align:middle' end ifoverlapProps[i].abbrthen overlapProps.tag={'<abbr title="'..string.gsub(overlapProps[i].abbr,'"','"')..'">','</abbr>'} else overlapProps.tag={'',''} end table.insert(tmp,string.format(i18n.html['cell-overlaptext-fmt'],(tmp_iconpreandtmp_iconpre~=''andtmp_iconpreor'_'),overlapProps.style,overlapProps.class,overlapProps.textfmt,icontip,overlapProps.tag[1],overlapProps._before,tmp_icontext,overlapProps._after,overlapProps.tag[2])) else v=mw.text.trim(v) ifstring.find(v,'num')then ifnotstring.find(v,'numN%d+')thentracking=tracking..(i18n['error-categories']['text-images']ori18n['error-categories'].default)end end table.insert(tmp,string.format(i18n.html['cell-overlapicon-fmt'],overlapProps.style,v,thislink,icontip)) end end ificonProps.stylethentmp2[1]=trueelseiconProps.style=''end iconProps.bg=iconProps.bgoriconProps.backgroundoriconProps.bgcolor ificonProps.bgtheniconProps.style=iconProps.style..';background:'..iconProps.bgend ifstring.match(icon,'^[%+_]?o?c?d?b?s?w?$')then iftmp2[1]theniconProps.style=';'..iconProps.styleend returnstring.format(i18n.html['cell-empty-fmt-with-overlap'],cellProps.style,mw.text.trim(table.concat(tmp)),(string.match(icon,'^.+$')or'_'),iconProps.style,tracking) elseificontextthen iconProps.class='' iconProps._before,iconProps._after=cellProps._before,cellProps._after iconProps.color=iconProps.colororiconProps.colour;iconProps.bold=iconProps.boldoriconProps.b;iconProps.italic=iconProps.italicoriconProps.ioriconProps.it ificonProps.colortheniconProps.style=iconProps.style..';color:'..iconProps.colorend ifpositive(iconProps.italic)theniconProps.style=iconProps.style..';font-style:italic'end ifpositive(iconProps.bold)theniconProps.style=iconProps.style..';font-weight:bold'end ifrowProps.fontsizeorcellProps.fontsizeoriconProps.fontsize=='info'then elseifnoticonProps.fontsizethen iconProps.class=' class="RMts"' elseificonProps.fontsize=='cmt'oriconProps.fontsize=='comment'then iconProps._before,iconProps._after='<div class="RMsi">','</div>' else iconProps.style=iconProps.style..';font-size:'..iconProps.fontsize end ificonProps.alignorcellProps.alignthen cellProps.align=cellProps.alignor{'middle','center'} iconProps.align=alignment(iconProps.align,cellProps.align[1],cellProps.align[2])orcellProps.align iconProps.style,iconProps.textfmt=iconProps.style..';text-align:'..iconProps.align[2],';vertical-align:'..iconProps.align[1] else iconProps.style,iconProps.textfmt=iconProps.style..';text-align:center',';vertical-align:middle' end ificonProps.abbrthen iconProps.tag={'<abbr title="'..string.gsub(iconProps.abbr,'"','"')..'">','</abbr>'} else iconProps.tag={'',''} end iftmp2[1]theniconProps.style=';'..iconProps.styleend returnstring.format(i18n.html['cell-text-fmt-with-overlap'],(iconpreandiconpre~=''andiconpreor'_'),cellProps.style,mw.text.trim(table.concat(tmp)),(iconpreandiconpre~=''andiconpreor'_'),iconProps.style,iconProps.class,iconProps.textfmt,icontip,iconProps.tag[1],iconProps._before,icontext,iconProps._after,tracking,iconProps.tag[2]) else ificonProps.style~=''theniconProps.style=string.gsub(' style="'..iconProps.style..'"','";','"',1)end ifstring.find(icon,'num')then ifnotstring.find(icon,'numN%d+')thentracking=tracking..(i18n['error-categories']['text-images']ori18n['error-categories'].default)end end returnstring.format(i18n.html['cell-icon-fmt-with-overlap'],cellProps.style,mw.text.trim(table.concat(tmp)),iconProps.style,icon,icontip,tracking) end end ifstring.match(icon,'^[%+_]?o?c?d?b?s?w?$')then returnstring.format(i18n.html['cell-empty-fmt'],(string.match(icon,'^.+$')or'_'),cellProps.style,tracking) else iflinkandlink~=''thenicontip=linkend ificontextthen ifnotcellProps.fontsizeandnotrowProps.fontsizethencellProps.class=' class="RMts"'end ifcellProps.abbrthen cellProps.tag={'<abbr title="'..string.gsub(cellProps.abbr,'"','">')..'">','</abbr>'} else cellProps.tag={'',''} end returnstring.format(i18n.html['cell-text-fmt'],(iconpreandiconpre~=''andiconpreor'_'),cellProps.style,cellProps.class,cellProps.textfmt,icontip,cellProps.tag[1],cellProps._before,icontext,cellProps._after,tracking,cellProps.tag[2]) else ifstring.find(icon,'num')then ifnotstring.find(icon,'numN%d+')thentracking=tracking..(i18n['error-categories']['text-images']ori18n['error-categories'].default)end end returnstring.format(i18n.html['cell-icon-fmt'],cellProps.style,icon,link,icontip,tracking) end end end localfunctionfillercell(code,height) --Creates a 5px-high row. --Values in icon pattern can only be [blank], d, [BSicon color] or #[hex triplet]. height=mw.text.trim(height) ifheight~=''then iftonumber(height)thenheight=height..'px'end height='height:'..height..';min-height:'..height end ifstring.match(code,'^[%+_]?o?c?d?b?s?w?$')then returnstring.format(i18n.html['cell-filler-empty-fmt'],(string.match(code,'^.+$')or'_'),height) elseifmw.ustring.sub(code,1,1)=='#'then returnstring.format(i18n.html['cell-filler-fmt'],height,code) else returnstring.format(i18n.html['cell-filler-fmt'],height,'#'..RGBbyCode(code)) end end localfunctionrow(pattern,noformatting,filler)--[[ Row handling. Each row looks like the following: row properties~~linfo4~~linfo3~~linfo2~~linfo1! !(icon pattern)~~rinfo1~~rinfo2~~rinfo3~~rinfo4~~row properties ]] localresult={['linfo4']='',['linfo3+2']='',['linfo1']='',rowstyle='',['cells']={},['rinfo1']='',['rinfo2+3']='',['rinfo4']='',['rowProp']={}} locallcolspan,rcolspan,linfo4_fmt,rinfo4_fmt='2','2','','' localleft,right,icons,overlapIcons,tmp={},{},{},{},mw.text.split(pattern,'! !') if#tmp>1then--splitting the pattern by '! !' left=tmp[1];right=tmp[2] else left='';right=tmp[1]or'' end tmp=mw.text.split(left,'~~')--analysing the left part if#tmp>1then--if there are several ~~ result['linfo1']=mw.getCurrentFrame():preprocess(mw.text.trim(tmp[#tmp])) result['linfo3+2']=mw.text.trim(tmp[#tmp-1]) if#tmp>2then tmp[#tmp-2]=mw.text.trim(tmp[#tmp-2]) iftmp[#tmp-2]~=''thenresult['linfo3+2']=string.format(i18n.html['row-linfo3-fmt'],tmp[#tmp-2])..result['linfo3+2']end if#tmp>3then tmp[#tmp-3]=mw.text.trim(tmp[#tmp-3]) iftmp[#tmp-3]~=''then result['linfo4']=mw.getCurrentFrame():preprocess(tmp[#tmp-3]) lcolspan='1' linfo4_fmt=string.format(i18n.html['row-linfo4-fmt'],'',result['linfo4']) end if#tmp>4thenresult.rowProp=properties(mw.text.trim(tmp[#tmp-4]))end end end else--assume only linfo2 was provided. result['linfo3+2']=mw.text.trim(tmp[1]) end result['linfo3+2']=mw.getCurrentFrame():preprocess(result['linfo3+2'])--expand possible templates in info. tmp=mw.text.split(right,'~~')--analysing the right part if#tmp>2then result['rinfo1']=mw.getCurrentFrame():preprocess(mw.text.trim(tmp[2])) result['rinfo2+3']=mw.text.trim(tmp[3]) if#tmp>3then tmp[4]=mw.text.trim(tmp[4]) iftmp[4]~=''thenresult['rinfo2+3']=result['rinfo2+3']..string.format(i18n.html['row-rinfo3-fmt'],tmp[4])end if#tmp>4then tmp[5]=mw.text.trim(tmp[5]) iftmp[5]~=''then result['rinfo4']=mw.getCurrentFrame():preprocess(tmp[5]) rcolspan='1' rinfo4_fmt=string.format(i18n.html['row-rinfo4-fmt'],'',result['rinfo4']) end if#tmp>5thenresult.rowProp=properties(mw.text.trim(tmp[6]))end end end else--assume only rinfo2 was provided. result['rinfo2+3']=mw.text.trim(tmp[2]or'') end result['rinfo2+3']=mw.getCurrentFrame():preprocess(result['rinfo2+3']) -- The below parameter functions are passed through to the cells. ifresult.rowProp.fontsize=='cmt'orresult.rowProp.fontsize=='comment'then result.rowProp._before,result.rowProp._after='<div class="RMsi">','</div>' end ifresult.rowProp.alignthen result.rowProp.align=alignment(result.rowProp.align,'middle','center')or{'middle','center'} end icons=mw.text.split(tmp[1],'\\')--splitting the string of icons first by "\" iftype(filler)=='string'then result.style=';font-size:0px' fori,vinipairs(icons)dotable.insert(result['cells'],fillercell(v,filler))end--no !@ or !~ for filler row else result.style='' fori,vinipairs(icons)do tmp=mw.text.split(v,'!~') icons[i]=tmp[1] table.remove(tmp,1) table.insert(overlapIcons,tmp) end fori,vinipairs(icons)dotable.insert(result['cells'],cell(v,overlapIcons[i],result.rowProp))end end result['cells']=table.concat(result['cells']) ifresult.rowProp.stylethenresult.style=result.style..';'..result.rowProp.styleend result.rowProp.bg=result.rowProp.bgorresult.rowProp.backgroundorresult.rowProp.bgcolor;result.rowProp.color=result.rowProp.colororresult.rowProp.colour;result.rowProp.bold=result.rowProp.boldorresult.rowProp.b;result.rowProp.italic=result.rowProp.italicorresult.rowProp.iorresult.rowProp.it ifresult.rowProp.bgthenresult.style=result.style..';background:'..result.rowProp.bgend ifresult.rowProp.colorthenresult.style=result.style..';color:'..result.rowProp.colorend ifpositive(result.rowProp.italic)thenresult.style=result.style..';font-style:italic'end ifpositive(result.rowProp.bold)thenresult.style=result.style..';font-weight:bold'end ifresult.rowProp.fontsizeandresult.rowProp._after==''andresult.rowProp.fontsize~='info'then result.style=result.style..';font-size:'..result.rowProp.fontsize end ifnoformattingthen returnresult else returnstring.format(i18n.html['row-general-fmt'],linfo4_fmt,lcolspan,'',result['linfo3+2'],q.linfo1_pad,'',result['linfo1'],result.style, result['cells'],q.rinfo1_pad,'',result['rinfo1'],rcolspan,'',result['rinfo2+3'],rinfo4_fmt) end end --↓ This table handles diagram rows beginning with a hyphen ("-"). q={collapsibles=-1,text_width={'','','','','',''},linfo1_pad='class="RMl1"',rinfo1_pad='class="RMr1"',bg='#F9F9F9'} q.isKeyword=function(pattern,i,rows,justTest) ifmw.ustring.sub(pattern,1,1)~='-'thenifjustTestthenreturnfalseelsereturnnilendend--not a valid keyword localtmp=mw.text.split(string.sub(pattern,2),'%-') iftype(q[tmp[1]])=="function"andtmp[1]~='isKeyword'then ifjustTestthenreturntmp[1]elsereturnq[tmp[1]](tmp,i,rows)end--valid keyword else ifjustTestthenreturnfalseelsereturnnilend end end q['startCollapsible']=function(params,i,rows) table.remove(rows,i) localtmp=q.isKeyword(rows[i],i,rows,true) iftmpthen iftmp=='endCollapsible'thenreturnformaterror('collapsible-block-empty') elsereturnformaterror('collapsible-block-no-first-row')..q.isKeyword(rows[i],i,rows)--no valid keywords that can follow "startCollapsible" end end ifq.collapsibles==-1thenq.collapsibles=1elseq.collapsibles=q.collapsibles+1end--q.collapsibles == -1 means there are no collapsibles at all; 0 - all closed; >0 - some not closed localcollapsed,replace,props=params[2],params[3]or'',properties(table.concat(params,'-',4))--params[1] is the keyword name so all indices are shifted by one. ifcollapsed==nilorcollapsed==''thencollapsed='collapsed'end ifprops.bg==nilorprops.bg==''thenprops.bg='transparent';props['bg-replace']=q.bgelseprops['bg-replace']=props.bgend localmode,float,result ifq.rinfo1_pad==''thenmode='collapsible ';float='float:right;' elsemode='mw-collapsible mw-';float='' end result=string.format(i18n.html["row-collapsible-begin-fmt"],props.bg,mode,collapsed,float) tmp=row(rows[i],true,nil) locallinfo4_3_2_fmt,rinfo2_3_4_fmt='','' ifq.rinfo1_pad==''then iftmp['linfo4']~=''ortmp['linfo3+2']~=''thenlinfo4_3_2_fmt=string.format(i18n.html['row-collapsible-left-linfo4+3+2-fmt'],tmp['linfo4'],tmp['linfo3+2'])end result=result..string.format(i18n.html['row-general-fmt'],string.format(i18n.html['row-collapsible-left-button-fmt'],i18n.html['row-collapsible-left-button-width'],q.text_width[1]), '1',q.text_width[2],linfo4_3_2_fmt,q.linfo1_pad,q.text_width[3],tmp['linfo1'],tmp.style,tmp['cells'],'','','','1','','',string.format(i18n.html['row-rinfo4-fmt'],'','')) else iftmp['rinfo4']~=''ortmp['rinfo2+3']~=''thenrinfo2_3_4_fmt=string.format(i18n.html['row-collapsible-right-rinfo2+3+4-fmt'],tmp['rinfo2+3'],tmp['rinfo4'])end result=result..string.format(i18n.html['row-general-fmt'],string.format(i18n.html['row-linfo4-fmt'],q.text_width[1],tmp['linfo4']), '1',q.text_width[2],tmp['linfo3+2'],q.linfo1_pad,q.text_width[3],tmp['linfo1'],tmp.style,tmp['cells'],q.rinfo1_pad,q.text_width[4],tmp['rinfo1'], '1',q.text_width[5],rinfo2_3_4_fmt,string.format(i18n.html['row-collapsible-right-button-fmt'],i18n.html['row-collapsible-right-button-width'],q.text_width[6])) end ifreplace~=''then ifq.isKeyword(rows[i+1],i,rows,true)thenreturnresult..formaterror('collapsible-block-no-replacement')end--a plain row needed for replacement table.remove(rows,i) tmp=row(rows[i],true,nil) localpadding,right=i18n.html['row-collapsible-right-button-width']..' 0 0','' ifq.rinfo1_pad==''thenpadding='0 0 '..i18n.html['row-collapsible-left-button-width'];right='right:0px;'end result=result..string.format(i18n.html['row-collapsible-replace-begin-fmt'],padding,right,props['bg-replace']) linfo4_3_2_fmt='';rinfo2_3_4_fmt='' ifq.rinfo1_pad==''then iftmp['linfo4']~=''ortmp['linfo3+2']~=''thenlinfo4_3_2_fmt=string.format(i18n.html['row-collapsible-left-linfo4+3+2-fmt'],tmp['linfo4'],tmp['linfo3+2'])end result=result..string.format(i18n.html['row-general-fmt'],string.format(i18n.html['row-linfo4-fmt'],'',''),'1',q.text_width[2],linfo4_3_2_fmt, q.linfo1_pad,q.text_width[3],tmp['linfo1'],tmp.style,tmp['cells'],'','','','1','','',string.format(i18n.html['row-rinfo4-fmt'],'','')) else iftmp['rinfo4']~=''ortmp['rinfo2+3']~=''thenrinfo2_3_4_fmt=string.format(i18n.html['row-collapsible-right-rinfo2+3+4-fmt'],tmp['rinfo2+3'],tmp['rinfo4'])end result=result..string.format(i18n.html['row-general-fmt'],string.format(i18n.html['row-linfo4-fmt'],q.text_width[1],tmp['linfo4']),'1',q.text_width[2], tmp['linfo3+2'],q.linfo1_pad,q.text_width[3],tmp['linfo1'],tmp.style,tmp['cells'],q.rinfo1_pad,q.text_width[4],tmp['rinfo1'],'1',q.text_width[5], rinfo2_3_4_fmt,string.format(i18n.html['row-rinfo4-fmt'],'','')) end result=result..i18n.html['row-collapsible-replace-end-fmt'] end returnresult end q['endCollapsible']=function(params,i,rows) ifq.collapsibles>0then q.collapsibles=q.collapsibles-1 returni18n.html['row-collapsible-end-fmt'] else returnformaterror('collapsible-block-not-open') end end q['colspan']=function(params,i,rows) ifparams[2]=='end'thenreturn''end localtmp,j,nrows,props={},0,tonumber(params[2]),properties(table.concat(params,'-',3)) ifnrows~=0thentable.remove(rows,i)end ifnrows==nilthennrows=#rows-i+1end whilej<nrowsandi<=#rowsdo j=j+1 ifrows[i]=='-colspan-end'then j=nrows else table.insert(tmp,rows[i]) end ifnrows~=jori==#rowsthentable.remove(rows,i)end end ifj<nrowsthenj=formaterror('colspan-less-rows-than-set',j)elsej=''end returnstring.format(i18n.html['colspan-fmt'],j,props.bgor'',props.alignor'',props['style']or'',mw.getCurrentFrame():preprocess(table.concat(tmp,'\n'))) end q['filler']=function(params,i,rows) localtmp,height=table.concat(params,'-',3),(params[2]or'') if#params<3ortmp==''thenreturnformaterror('parameter-missing')end--TODO: specify the name of the parameter ifparams[2]~=''thenheight=params[2]end returnrow(tmp,nil,height) end functionp.RGBbyCode(frame) returnRGBbyCode(mw.text.trim(frame.args[1]or'')) end localfunctionlocalroute(pattern,ptw,pbg,process) localtmp={} ifmw.text.trim(pbg)~=''thenq.bg=pbgend tmp=mw.text.split(mw.text.trim(ptw),'%s*,%s*') if#tmp==6then fori=1,6do iftmp[i]~=''then iftonumber(string.sub(tmp[i],-1))then q.text_width[i]='width:'..tmp[i]..'px;min-width:'..tmp[i]..'px;' else q.text_width[i]='width:'..tmp[i]..';min-width:'..tmp[i]..';' end end end iftmp[4]==''andtmp[5]==''andtmp[6]==''then q.rinfo1_pad=''--padding for rinfo1 column = 0, not 3px elseiftmp[1]==''andtmp[2]==''andtmp[3]==''then q.linfo1_pad='' end--padding for linfo1 column = 0, not 3px elseif#tmp==3then fori=1,3do iftmp[i]~=''then iftonumber(string.sub(tmp[i],-1))then q.text_width[i+3]='width:'..tmp[i]..'px;min-width:'..tmp[i]..'px;' else q.text_width[i+3]='width:'..tmp[i]..';min-width:'..tmp[i]..';' end end end q.linfo1_pad='' elseif#tmp==1andtmp[1]~=''then iftonumber(string.sub(tmp[1],-1))then q.text_width[5]='width:'..tmp[1]..'px;min-width:'..tmp[1]..'px;' else q.text_width[5]='width:'..tmp[1]..';min-width:'..tmp[1]..';' end q.linfo1_pad='' end fori=1,6do tmp=tonumber(mw.ustring.match(q.text_width[i],':([0-9]+%.?[0-9]*)px;')) iftmpthen tmp=tmp*3/40 q.text_width[i]='width:'..tmp..'em;min-width:'..tmp..'em;' end end tmp={} localindex=0 localrows={} ifnotprocessorprocess==''ornegative(process)then pattern=mw.ustring.gsub(pattern,'\n(#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])','%1') end foriteminpattern:gmatch('([^\n]*)\n?')do item=mw.text.trim(item) ifitem~=''then index=index+1 rows[index]=item end end ifindex==0thenreturnformaterror('parameter-missing')end fori,vinipairs(rows)do localkeyword=q.isKeyword(v,i,rows) iftype(keyword)~="string"then table.insert(tmp,row(v,nil,nil)) else table.insert(tmp,keyword) end end ifq.collapsibles>0thentable.insert(tmp,formaterror('collapsible-block-not-closed')..q['endCollapsible']())end ifq.collapsibles~=-1then ifq.rinfo1_pad==''then q.text_width[1]=q.text_width[1]..'min-width:'..i18n.html['row-collapsible-left-button-width']..';' else q.text_width[6]=q.text_width[6]..'min-width:'..i18n.html['row-collapsible-right-button-width']..';' end end -- ↓ empty row to set column widths; ↑ if q.collapsibles ≠ -1 and there are collapsible sections, leftmost or rightmost column should be wide enough to accomodate the button table.insert(tmp,string.format(i18n.html['empty-row-fmt'],q.text_width[1],q.text_width[2],q.linfo1_pad,q.text_width[3],q.rinfo1_pad,q.text_width[4],q.text_width[5],q.text_width[6])) returnmw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(table.concat(tmp),'style=";* *','style="'),'\n| *style="" *|','\n|'),' ?style=""',''),' ?colspan="1"',''),'<div class="RMsi"></div>',''),'class="RM%+','class="RM_'),'(class="[^"]* RM)%+','%1_') end localfunctiongetArgNums(prefix,args) -- Copied from Module:Infobox on enwiki. -- Returns a table containing the numbers of the arguments that exist -- for the specified prefix. For example, if the prefix were 'data', and -- 'data1', 'data2', and 'data5' existed, this would return {1, 2, 5}. localnums={} fork,vinpairs(args)do localnum=tostring(k):match('^'..prefix..'([1-9]%d*)$') ifnumthentable.insert(nums,tonumber(num))end end table.sort(nums) returnnums end localgreatercontrast=require('Module:Color contrast')._greatercontrast localrgb_black='#252525'-- class .mw-body in Mediawiki:Common.css p.infobox=makeInvokeFunction('_infobox') functionp._infobox(args)-- Creates a pretty box. args.map1,args.tw,args['map1-title'],args['map1-collapsible'],args['map1-collapse']=args.map1orargs.map,args.tworargs['text-width']orargs['text width'],args['map1-title']orargs['map-title'],args['map1-collapsible']orargs['map-collapsible'],args['map1-collapse']orargs['map1-collapsed']orargs['map-collapse']orargs['map-collapsed'] localfunctionmap_prefix(x)return'map'..xend localmapnums,prefix={} ifargs[1]andargs[1]~=''then prefix=tonumber fork,vinpairs(args)do iftype(k)=='number'thentable.insert(mapnums,k)end end else prefix=map_prefix mapnums=getArgNums('map',args) table.sort(mapnums) end localclasses={} args['title bg color']=args['title bg color']orargs['title bg']orargs['title-bg']or'#27404E' args['title color']=args['title color']orargs['title-color']orgreatercontrast{args['title bg color'],'#FFF',rgb_black} args.legend=args.legendor'' localnavbar=require('Module:Navbar').navbar localnavtable={} ifargs.navbarthen navtable={args.navbar,mini=i18n.text.navbar_mini,text=i18n.text.navbar_text} args.navbar=navbar(navtable) else args.navbar='' end localresult='' ifargs.inlinethenresult=result..' \n'end result=result..'{|' args.collapse=args.collapseorargs.collapsed ifargs.inlineornegative(args.collapsible)then args.collapsible='0' else table.insert(classes,'collapsible') ifargs.collapsethentable.insert(classes,'collapsed')end end args.float=args.floator'right' ifargs.float=='right'then args.margin='margin-left:1em;' elseifargs.float=='left'then args.margin='margin-right:1em;' else args.margin='' end args.fontsize2=10000/88 ifargs.inlinethen table.insert(classes,'RMinline') args.fontsize=100 else table.insert(classes,'RMbox') args.fontsize=88-- as above: CSS rule for .infobox in % end args.bg=args.bgor'#F9F9F9' args.style=args.styleor'' result=result..'class="'..table.concat(classes,' ')..'" cellspacing="0" cellpadding="0" style="float:'..args.float..';clear:'..args.float..';margin-top:0;margin-bottom:1em;'..args.margin..'empty-cells:show;border-collapse:collapse;font-size:'..args.fontsize..'%;background:'..args.bg..';'..args.style..'"' args.title=args.titleor'' ifargs.inlineorargs.title=='no'orargs.title=='0'then else result=result..'\n! style="color:'..args['title color']..';background:'..args['title bg color']..';text-align:center;padding:5px"|' ifargs['navbar pos']then result=result..'<div>' else ifargs.navbar~=''then navtable.mini=true navtable.brackets=true navtable.style='float:left;margin-right:5px;white-space:nowrap' navtable.fontstyle='font-size:'..args.fontsize2..'%;color:'..args['title color'] args.navbar=navbar(navtable)..'<div style="margin-left:55px">' else args.navbar='<div>' end result=result..args.navbar end result=result..'<div style="white-space:nowrap;' ifargs.collapsible=='0'and(args['navbar pos']orargs.navbar=='<div>')then else result=result..'margin-right:55px;' ifargs['navbar pos']orargs.navbar=='<div>'then result=result..'margin-left:55px;' end end result=result..'font-size:'..args.fontsize2..'%">'..args.title..'</div></div>' end args.top=args.toporargs['on top'] ifargs.topthen result=result..'\n|-\n|style="padding:0px 5px;text-align:center;'..(args.topstyleor'')..'"|'..args.top end result=result..'\n|-\n|style="line-height:normal;padding:4px 5px"|' ifargs.navbar~=''andargs['navbar pos']=='1'then ifnotpositive(args['navbar long'])andnotnegative(args['navbar mini'])thennavtable.mini=true;args.navbar=navbar(navtable)end result=result..'<div style="float:left;padding-right:5px">'..args.navbar..'</div>' end args.legend2=mw.ustring.lower(args.legend) ifargs.legend2~='no'andargs.legend2~='0'then args.legend=i18n.text.legend[args.legend2]or((args.legend2~='')and('[['..args.legend)ori18n.text.legend.default) args.legend=args.legend..'|'..(args['legend alt']ori18n.text.legend_text)..']]' result=result..'<div class="selfreference noprint" style="text-align:right;font-size:97%">'..args.legend..'</div>' end ifargs.inlinethenargs.padding2='0px'elseargs.padding2='0px 6px'end fork,vinipairs(mapnums)do ifnotmapnums[k+1]then ifnotargs.inlinethenargs.padding2='0px 6px 6px'end end args.ending='' ifargs['map'..v..'-title']then args.header_margin='0' ifk==1thenargs.border_header='border-bottom: 5px solid '..args.bg..';'elseargs.border_header='border-top: 5px solid '..args.bg..';border-bottom: 5px solid '..args.bg..';'end ifpositive(args['map'..v..'-collapsible'])then args.header_margin='0 55px' args.ending='\n|}' ifpositive(args['map'..v..'-collapse'])orpositive(args['map'..v..'-collapsed'])thenargs.map_collapsed=' mw-collapsed autocollapse'elseargs.map_collapsed=''end result=result..'\n|-\n|\n{|class="mw-collapsible'..args.map_collapsed..'" cellpadding="0" cellspacing="0" style="display:table;min-width:100%;margin:0 auto"' end ifargs.inlinethenargs.header_style2=' style="line-height:normal"'elseargs.header_style2=''end result=result..'\n|-'..args.header_style2..'\n!style="'..args.border_header..'padding:3px 5px;text-align:center;vertical-align:middle;color:'..rgb_black..';background:#EEEEEE" | <div style="margin:'..args.header_margin..';font-size:'..10000/args.fontsize..'%">'..args['map'..v..'-title']..'</div>' args.border_top='' else ifk==1thenargs.border_top=''elseargs.border_top='border-top: 5px solid '..args.bg..';'end end result=result..'\n|-\n|style="'..args.border_top..'padding:'..args.padding2..'"|\n{|class="nogrid routemap" style="font-size:'..(args.fontsize2*.95)..'%"\n'..localroute(args[prefix(v)],(args['tw'..v]orargs['text-width'..v]orargs['text width'..v]orargs.twor''),args.bg,args.process)..'\n|}'..args.ending end args.bottom=args.bottomorargs.footnote ifargs.bottomthen ifargs.inlinethenargs.padding2='6px'elseargs.padding2='0px'end result=result..'\n|-\n|style="line-height:normal;text-align:right;padding:'..args.padding2..' 5px 5px;'..(args.bottomstyleorargs.footnotestyleor'')..'"|'..args.bottom ifstring.find(args.bottom,'&action=edit')thenresult=result..(i18n['error-categories']['separate-navbar']ori18n['error-categories'].default)end end ifargs.navbar~=''andargs['navbar pos']=='2'then ifnegative(args['navbar long'])orpositive(args['navbar mini'])thennavtable.mini=true;args.navbar=navbar(navtable)end ifargs.inlineandnotargs.bottomthenargs.padding2='6px'elseargs.padding2='0px'end result=result..'\n|-\n|style="line-height:normal;padding:'..args.padding2..' 5px 3px;text-align:center"|'..args.navbar end returnresult..'\n|}' end localfunctionbase(t1,t2,link,stn,italic,it,it2,bold,align,style,bg1,bg2,line,fs1,fs2,lh,v1,swap,inp,bs) --Creates an inline table with two rows of text. Can be used in any Routemap text cell. --Implemented in the BSsplit, BSto, BSsrws and BScvt templates. ifnotalignthen ifbs=='cvt'then align='right' else align='inherit' end end style=styleor'' localresult=' <table cellspacing="0" cellpadding="0" class="RMsplit" style="text-align:'..align ifitalicorit=='all'thenresult=result..';font-style:italic'end ifboldthenresult=result..';font-weight:bold'end localrowstart='<tr><td style="text-align:inherit;padding:0;line-height:' result=result..';'..style..'">'..rowstart..lh iflinethenresult=result..';border-bottom:1px solid gray'end localbgpad=';padding-left:.5em;padding-right:.5em' localfunctionbgtext(v) return';color:'..greatercontrast{v,'#FFF',rgb_black} end ifbg1then result=result..bgpad..bgtext(bg1)..';background:'..bg1 elseifbg2then result=result..bgpad end iffs1thenresult=result..';font-size:'..fs1end result=result..'">' ifnott1orstring.find(t1,'^%s*$')then ifnott2thent2=''end ifstring.find(t2,'<br ?/?>')==nilthent1=' 'end end ifnott2orstring.find(t2,'^%s*$')then ifnott1thent1=''end ifstring.find(t1,'<br ?/?>')==nilthent2=' 'end end ifbs=='srws'then ifstnthen link=stn..' '..t1..' '..t2 else link='Stasiun '..t1..' '..t2 end elseifbs=='cvt'then localsplit,floor,outp,v2,mult=mw.text.split,math.floor localfunctiontrim(x) returnstring.gsub(x,'%s','') end localcvt={-- conversion values ['mi']=1.609344, ['ch']=20.1168, ['mi;ch']=80, ['m']=1/.9144, ['yd']=.9144, ['ft']=.3048, } localsf={-- 10 ^ floor(log10(cvt[inp]) + .5); or 10 ^ floor(log10(cvt[inps[1]] * cvt[inp]) + .5) for dual-unit inputs. this corrects the accuracy of result so that it usually has same significant figures ['mi']=1, ['ch']=10, ['mi;ch']=.01, ['m']=1, ['yd']=1, ['ft']=.1, } ifnotinptheninp='mi'end inp=string.lower(trim(inp)) ifinp=='ch'orinp=='yd'orinp=='ft'then-- output unit outp='m' elseifinp=='m'then outp='yd' else ifinp~='mi;ch'theninp='mi'end outp='km' end localpos=string.find(v1,'%.') ifnotposthen mult=1 else mult=10^(string.len(v1)-pos) end localinps=string.find(inp,';') ifinpsthen inps=split(inp,';') ifswapthen t1=v1..' '..outp v1=tonumber(v1) t2=floor(v1/cvt[inps[1]])..' '..inps[1]..' '..floor(v1%cvt[inps[1]]/cvt[inps[1]]*cvt[inp]*mult*sf[inp]+.5)/mult/sf[inp]..' '..inps[2] else v1=split(trim(v1),';') t1=v1[1]..' '..inps[1]..' '..v1[2]..' '..inps[2] t2=floor((tonumber(v1[1])*cvt[inps[1]]+tonumber(v1[2])*cvt[inps[1]]/cvt[inp])*mult/sf[inp]+.5)/mult*sf[inp]..' '..outp end else ifswapthen v2=floor(tonumber(v1)/cvt[inp]*mult*sf[inp]+.5)/mult/sf[inp] inp,outp=outp,inp else v2=floor(tonumber(v1)*cvt[inp]*mult/sf[inp]+.5)/mult*sf[inp] end t1=v1..' '..inp t2=v2..' '..outp end end ift1then iflinkthen result=result..'[['..link..'|'..t1..']]' else result=result..t1 end end localrowend='</td></tr>' result=result..rowend..rowstart..lh ifbg2then result=result..bgpad..bgtext(bg2)..';background:'..bg2 elseifbg1then result=result..bgpad end iffs2thenresult=result..';font-size:'..fs2end if(it~='off'andbs=='to')orit2=='italic'then result=result..';font-style:italic' elseifit=='off'then result=result..';font-style:normal' end result=result..'">' ift2then iflinkthen result=result..'[['..link..'|'..t2..']]' else result=result..t2 end end result=result..rowend..'</table> ' ifbs=='to'orbs=='srws'then ift1==' 'ort2==' 'thenresult=result..(i18n['error-categories']['missing-text-values']ori18n['error-categories'].default)end end ifstring.find(t1,'<br ?/?>')~=nilorstring.find(t2,'<br ?/?>')~=nilthenresult=result..(i18n['error-categories']['br-tags']ori18n['error-categories'].default)end ifbs=='split'then iflinkandt1andt2then ifstring.find(link,'^'..t1..' '..t2..' ')thenresult=result..(i18n['error-categories']['srws']ori18n['error-categories'].default)end end end returnresult end p.BSto=makeInvokeFunction('_BSto') functionp._BSto(args) args[3]=args[3]orargs.L args[4]=args[4]orargs.itorargs.i args[5]=args[5]orargs.b returnbase(args[1],args[2],args[3],nil,nil,args[4],nil,args[5],args.align,args.style,args.bg1,args.bg2,args.line,'105%','inherit','.9',nil,nil,nil,'to') end p.BSsplit=makeInvokeFunction('_BSsplit') functionp._BSsplit(args) args[3]=args[3]orargs.L args[4]=args[4]orargs.itorargs.i args[5]=args[5]orargs.b returnbase(args[1],args[2],args[3],nil,args[4],nil,nil,args[5],args.align,args.style,args.bg1,args.bg2,args.line,'inherit','inherit','.9',nil,nil,nil,'split') end p.BSsrws=makeInvokeFunction('_BSsrws') functionp._BSsrws(args) args[3]=args[3]orargs.S args[4]=args[4]orargs.itorargs.i args[5]=args[5]orargs.b returnbase(args[1],args[2],nil,args[3],args[4],nil,nil,args[5],args.align,args.style,args.bg1,args.bg2,args.line,'inherit','inherit','.9',nil,nil,nil,'srws') end p.BScvt=makeInvokeFunction('_BScvt') functionp._BScvt(args) returnbase(nil,nil,nil,nil,nil,nil,args.alt,nil,args.align,args.style,args.bg1,args.bg2,args.line,'inherit','inherit','.9',args[1],args[2],args['in'],'cvt') end p.rmri=makeInvokeFunction('_rmri') functionp._rmri(args)--[[ Displays a blue arrow pointing in one of eight directions. Implemented in the RoutemapRouteIcon template. ]] localdirections,result={ ['Up']={'u','up'}, ['Down']={'d','dn','down'}, ['Left']={'l','left'}, ['Right']={'r','right'}, ['UpperRight']={'ur','ne','c1','upperright'}, ['LowerRight']={'lr','se','c2','lowerright'}, ['LowerLeft']={'ll','sw','c3','lowerleft'}, ['UpperLeft']={'ul','nw','c4','upperleft'}, } locald,link,size=args[1],args[2],args[3] ifnotdthen ifargs[4]~=' 'thend,link,size=args[2],args[3],'s'end end fork,vinpairs(directions)do for_,nameinipairs(v)do ifd:lower()==namethen ifsize=='s'then size='7' elseifnotsizethen size='10' end ifnotlinkthenlink=''end result='[[File:Arrow Blue '..k..' 001.svg|'..size..'px|alt='..k..' arrow|link='..link..']]' end end end ifnotresultthen return'<span style="color:#f00">Invalid [[Template:RoutemapRoute]] arrow value "<span style="font-style:italic">'..d..'</span>".</span>'..(i18n['error-categories']['rmr-error']ori18n['error-categories'].default) else returnresult end end p.rmr=makeInvokeFunction('_rmr') functionp._rmr(args)--[[ Displays text between two blue arrows (or to the left/right side of one). Text can be split with an en dash if entered in both first and second numbered parameters. Implemented in the RoutemapRoute template. ]] args.l=args.lorargs.Liconorargs.liconorargs.L args.r=args.rorargs.Riconorargs.riconorargs.R ifargs.lthenargs.l=p._rmri{args.l,args.llink,(args.lsizeorargs.size),' '}..' 'elseargs.l=''end ifargs.rthenargs.r=' '..p._rmri{args.r,args.rlink,(args.rsizeorargs.size),' '}elseargs.r=''end ifargs[1]then ifargs[2]thenargs[1]=args[1]..' – '..args[2]end else args[1]=args[2]or'' end ifargs[1]==''orargs.enclosed=='no'then args.b1,args.b2='','' else args.b1,args.b2='(',')' end returnargs.b1..args.l..args[1]..args.r..args.b2 end functionp.BSrow(frame) localargs=getArgs(frame,{ parentOnly=true, removeBlanks=false, }) returnp._BSrow(args) end functionp._BSrow(args)--[[ Creates Routemap syntax for a diagram row based on parameters. Implemented in the RDTr template. ]] args.n=tonumber(args.nor'') ifnotargs.nthen localicontotal=getArgNums('',args) table.sort(icontotal) args.n=icontotal[#icontotal]or1 end localcount,icons,overlaps,overlapCalc=tonumber(args['$count'])or1,{},{},math.log10(args.n) localtext=(args.textand'*')or'' ifoverlapCalc==math.floor(overlapCalc)thenoverlapCalc=10^(overlapCalc)elseoverlapCalc=10^(math.floor(overlapCalc)+1)end whilecount<=args.ndo localcellparams,overlapn={},(string.match(count/overlapCalc,'%.(0+)')or'')..count table.insert(icons,(text..(args[count]or''))) ifargs['O'..overlapn]then localiconparams,overlapparams,overlapt={},{},{} fork,vinpairs({bg=(args['O'..overlapn..'0-bg']orargs['O'..overlapn..'0-background']orargs['O'..overlapn..'0-bgcolor']),color=(args['O'..overlapn..'0-color']orargs['O'..overlapn..'0-colour']),b=(args['O'..overlapn..'0-b']orargs['O'..overlapn..'0-bold']),i=(args['O'..overlapn..'0-i']orargs['O'..overlapn..'0-it']orargs['O'..overlapn..'0-italic']),align=args['O'..overlapn..'0-align'],fontsize=args['O'..overlapn..'0-fontsize'],abbr=args['O'..overlapn..'0-abbr'],style=args['O'..overlapn..'0-style']})do ifvthentable.insert(iconparams,k..'='..v)end end ificonparams[1]thenicons[count]=icons[count]..'__'..table.concat(iconparams,',')end fork,vinpairs({bg=(args['O'..overlapn..'-bg']orargs['O'..overlapn..'-background']orargs['O'..overlapn..'-bgcolor']),color=(args['O'..overlapn..'-color']orargs['O'..overlapn..'-colour']),b=(args['O'..overlapn..'-b']orargs['O'..overlapn..'-bold']),i=(args['O'..overlapn..'-i']orargs['O'..overlapn..'-it']orargs['O'..overlapn..'-italic']),align=args['O'..overlapn..'-align'],fontsize=args['O'..overlapn..'-fontsize'],abbr=args['O'..overlapn..'-abbr'],style=args['O'..overlapn..'-style']})do ifvthentable.insert(overlapparams,k..'='..v)end end ifoverlapparams[1]thenargs['O'..overlapn]=args['O'..overlapn]..'__'..table.concat(overlapparams,',')end overlaps=getArgNums('O'..overlapn,args)or{} table.sort(overlaps) ifoverlaps[1]then fori,vinipairs(overlaps)do overlapparams={} fork,v2inpairs({bg=(args['O'..overlapn..v..'-bg']orargs['O'..overlapn..v..'-background']orargs['O'..overlapn..v..'-bgcolor']),color=(args['O'..overlapn..v..'-color']orargs['O'..overlapn..v..'-colour']),b=(args['O'..overlapn..v..'-b']orargs['O'..overlapn..v..'-bold']),i=(args['O'..overlapn..v..'-i']orargs['O'..overlapn..v..'-it']orargs['O'..overlapn..v..'-italic']),align=args['O'..overlapn..v..'-align'],fontsize=args['O'..overlapn..v..'-fontsize'],abbr=args['O'..overlapn..v..'-abbr'],style=args['O'..overlapn..v..'-style']})do ifv2thentable.insert(overlapparams,k..'='..v2)end end ifoverlapparams[1]thenargs['O'..overlapn..v]=args['O'..overlapn..v]..'__'..table.concat(overlapparams,',')end table.insert(overlapt,text..args['O'..overlapn..v]) end overlaps='!~'..text..args['O'..overlapn]..'!~'..table.concat(overlapt,'!~') else overlaps='!~'..text..args['O'..overlapn] end icons[count]=icons[count]..overlaps else ifargs[count..'-abbr']thentable.insert(cellparams,'abbr='..args[count..'-abbr'])end end ifargs[count..'-link']thenicons[count]=icons[count]..'!@'..args[count..'-link']end fork,vinpairs({bg=(args[count..'-bg']orargs[count..'-background']orargs[count..'-bgcolor']),color=(args[count..'-color']orargs[count..'-colour']),b=(args[count..'-b']orargs[count..'-bold']),i=(args[count..'-i']orargs[count..'-it']orargs[count..'-italic']),align=args[count..'-align'],fontsize=args[count..'-fontsize'],style=args[count..'-style']})do ifvthentable.insert(cellparams,k..'='..v)end end ifcellparams[1]thenicons[count]=icons[count]..'!_'..table.concat(cellparams,',')end count=count+1 end localrow,rowparams,left,right=table.concat(icons,'\\'),{} fork,vinpairs({bg=(args.bgorargs.backgroundorargs.bgcolor),color=(args.colororargs.colour),b=(args.borargs.bold),i=(args.iorargs.itorargs.italic),align=args.align,fontsize=args.fontsize,style=args.style})do ifvthentable.insert(rowparams,k..'='..v)end end ifrowparams[1]thenargs.R5=table.concat(rowparams,',')end fori,vinipairs({'R1','R2','R3','R4','R5','L1','L2','L3','L4'})do ifnotargs[v]orstring.find(args[v],'^%s*$')thenargs[v]=nilend end ifargs.R5then right={(args.R1or' '),(args.R2or' '),(args.R3or' '),(args.R4or' '),args.R5} elseifargs.R4then right={(args.R1or' '),(args.R2or' '),(args.R3or' '),args.R4} elseifargs.R3then right={(args.R1or' '),(args.R2or' '),args.R3} elseifargs.R1then right={args.R1,(args.R2or'')} elseifargs.R2then right={args.R2} end ifrightthenrow=row..'~~'..table.concat(right,'~~')end ifargs.L4then left={args.L4,(args.L3or' '),(args.L2or' '),(args.L1or'')} elseifargs.L3then left={args.L3,(args.L2or' '),(args.L1or'')} elseifargs.L1then left={(args.L2or''),args.L1} elseifargs.L2then left={args.L2} end ifleftthenrow=table.concat(left,'~~')..'! !'..rowend returnrow end functionp.BSrow_lite(frame) localargs=getArgs(frame,{ removeBlanks=false, }) returnp._BSrow_lite(args) end functionp._BSrow_lite(args)--[[ Creates Routemap syntax for a diagram row based on parameters. Intended to be used to substitute legacy templates. Note that for compatibility the link and sidebar parameter names are different. ]] args.n=tonumber(args.nor'') ifnotargs.nthen localicontotal=getArgNums('',args) table.sort(icontotal) args.n=icontotal[#icontotal]or1 end localcount,icons,overlaps,overlapCalc=tonumber(args['$count'])or1,{},{},math.log10(args.n) localtext=(args.textand'*')or'' ifoverlapCalc==math.floor(overlapCalc)thenoverlapCalc=10^(overlapCalc)elseoverlapCalc=10^(math.floor(overlapCalc)+1)end whilecount<=args.ndo localcellparams,overlapn={},(string.match(count/overlapCalc,'%.(0+)')or'')..count table.insert(icons,(text..(args[count]or''))) ifargs['O'..overlapn]then localoverlapt={} overlaps=getArgNums('O'..overlapn,args)or{} table.sort(overlaps) ifoverlaps[1]then fori,vinipairs(overlaps)dotable.insert(overlapt,text..args['O'..overlapn..v])end overlaps='!~'..text..args['O'..overlapn]..'!~'..table.concat(overlapt,'!~') else overlaps='!~'..text..args['O'..overlapn] end icons[count]=icons[count]..overlaps end ifargs['L'..count]thenicons[count]=icons[count]..'!@'..args['L'..count]end count=count+1 end localrow,rowparams,left,right=table.concat(icons,'\\'),{} fork,vinpairs({bg=(args.bgorargs.backgroundorargs.bgcolor),style=args.style})do ifvthentable.insert(rowparams,k..'='..v)end end ifrowparams[1]thenargs.r5=table.concat(rowparams,',')end fori,vinipairs({'r1','r2','r3','r4','r5','l1','l2','l3','l4'})do ifnotargs[v]orstring.find(args[v],'^%s*$')thenargs[v]=nilend end ifargs.r5then right={(args.r1or' '),(args.r2or' '),(args.r3or' '),(args.r4or' '),args.r5} elseifargs.r4then right={(args.r1or' '),(args.r2or' '),(args.r3or' '),args.r4} elseifargs.r3then right={(args.r1or' '),(args.r2or' '),args.r3} elseifargs.r1then right={args.r1,(args.r2or'')} elseifargs.r2then right={args.r2} end ifrightthenrow=row..'~~'..table.concat(right,'~~')end ifargs.l4then left={args.l4,(args.l3or' '),(args.l2or' '),(args.l1or'')} elseifargs.l3then left={args.l3,(args.l2or' '),(args.l1or'')} elseifargs.l1then left={(args.l2or''),args.l1} elseifargs.l2then left={args.l2} end ifleftthenrow=table.concat(left,'~~')..'! !'..rowend returnrow end localfunctionpre_block(text) -- Pre tags returned by a module do not act like wikitext <pre>...</pre>. return'<pre>'.. mw.text.nowiki(text).. (text:sub(-1)=='\n'and''or'\n').. '</pre>\n' end functionp.convertbs(frame)--[[ Converts a legacy route diagram into Routemap format. Code to be used is displayed in preview mode or after saving the page, above the original code. {{#invoke:Routemap|convertbs|<nowiki> (Original diagram) </nowiki>}} ]] localorg=mw.text.unstripNoWiki(frame.args[1]or'Paste legacy RDT markup between nowiki tags') localres=org res=string.gsub(res,'{{[Bb][Ss]%-?map','{{Routemap')-- "%-" is an escape for hyphen which is used as "between" in pattern. res=string.gsub(res,'{|%s?{{[Rr]ailway line header}}','{{Routemap') res=string.gsub(res,'{{[Bb][Ss]%-header%d?|','{{safesubst:BS-header|')-- "%d?" means optional digit in case use of variant template like BS-header3. res=string.gsub(res,'{{[Bb][Ss]%-table%d?}}','|map =') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)|','{{safesubst:BS%1%2|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%-replace|','!replace{{safesubst:BS%1%2|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%-startCollapsible|','-startCollapsible-collapsed\n{{safesubst:BS%1%2|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%-sc|','-startCollapsible-collapsed\n{{safesubst:BS%1%2|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%text|','{{safesubst:BS%1%2text|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%-2|','{{safesubst:BS%1%2-2|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%-2replace|','!replace{{safesubst:BS%1%2-2|') res=string.gsub(res,'{{[Bb][Ss](%d?)(%d?)%-2sc|','-startCollapsible-collapsed\n{{safesubst:BS%1%2-2|') res=string.gsub(res,'{{!}}}','-endCollapsible-') res=string.gsub(res,'{{[Ee]nd}}','-endCollapsible-') res=string.gsub(res,'|}\n?|}','}}')-- Replace ending of Railway line header map setup. res=string.gsub(res,'{{[Bb][Ss]%-colspan}}\n{{safesubst','{{safesubst')-- BS-colspan is unnecessary and would cause error in Routemap. res=string.gsub(res,'{{[Bb][Ss]%-colspan}}\n%-%-%-%-','-colspan-2\n----') res=string.gsub(res,'<','<') res=string.gsub(res,'>','>') ifstring.find(res,'!replace')orstring.find(res,'|%s*bg%s*=')then localrestable=mw.text.split(res,'\n') fori,vinipairs(restable)do ifstring.find(v,'!replace')then restable[i]=string.gsub(restable[i],'!replace','') restable[i-2]=string.gsub(restable[i-2],'collapsed','collapsed-replace') end if(string.find(v,'|%s*bg%s*=%s*#?[a-zA-Z0-9]+')orstring.find(v,'|%s*bg%s*=%s*#?{{[^{}]+}}%s*|')orstring.find(v,'|%s*bg%s*=%s*#?{{[^{}]+}}%s*}}'))andstring.find(restable[i-1],'^-startCollapsible')then localbg=string.match(v,'|%s*bg%s*=%s*(#?[a-zA-Z0-9]+)')orstring.find(v,'|%s*bg%s*=%s*(#?{{[^{}]+}})%s*|')orstring.find(v,'|%s*bg%s*=%s*(#?{{[^{}]+}})%s*}}') restable[i]=string.gsub(restable[i],'|%s*bg%s*=%s*'..bg,'') restable[i-1]=string.gsub(restable[i-1],'%-?$','--bg=')..bg ifstring.find(restable[i+1],'!replace')then restable[i+1]=string.gsub(restable[i+1],'!replace','') restable[i-1]=string.gsub(restable[i-1],'collapsed%-','collapsed-replace') if(string.find(restable[i+1],'|%s*bg%s*=%s*#?[a-zA-Z0-9]+')orstring.find(restable[i+1],'|%s*bg%s*=%s*#?{{[^{}]+}}%s*|')orstring.find(restable[i+1],'|%s*bg%s*=%s*#?{{[^{}]+}}%s*}}'))then localbg2=string.match(restable[i+1],'|%s*bg%s*=%s*(#?[a-zA-Z0-9]+)')orstring.find(restable[i+1],'|%s*bg%s*=%s*(#?{{[^{}]+}})%s*|')orstring.find(restable[i+1],'|%s*bg%s*=%s*(#?{{[^{}]+}})%s*}}') ifbg2==bgthenrestable[i+1]=string.gsub(restable[i],'|%s*bg%s*=%s*'..bg2,'')end end end end end res=table.concat(restable,'\n') end return"\n'''Safe substitution''':\n"..pre_block(res).."'''''Original''''':\n"..pre_block(org) end returnp