Module:FormatTemplate
Jump to navigation
Jump to search
This module is intended to format templates to make them readable.
It should work by recognizing every beginning that should not be intermingled: [[, {{, {{#, {{{
It will count how many levels deep you've gone.
It will add 4 times that many spaces before each pipe | in a non-[[ element, removing any now present
It will label the beginning and end with a color specific to the type of element even when it can't indent
It will return everything in a nowiki wrapper (excluding the color formatting)
local p={}
function getContent(template)
local title -- holds the result of the mw.title.xxx call if not(template) then title=mw.title.getCurrentTitle() if not(title) then return "error: failed to getCurrentTitle()" end local tdedoc=mw.ustring.match(title.fullText,"Template:(.-)/doc") if tdedoc then title=mw.title.new("Template:"..tdedoc) end -- SPECIAL CASE: Invoke in the template documentation processes the template instead else title=mw.title.new(page) if not (title) then return "error: failed to mw.title.new(" .. template .. ")" end end -- if not(template) return title.getContent(title) or ""
end
local color={}
color["{{"]="red"
color["{{#"]="blue"
color["{{{"]="orange"
color["[["]="green"
function color.ize(model,chars)
if not(chars) then return "" end local c=color[model] or "black" return '</nowiki>'..chars..'' end function formatTemplate(text,stack,posn,template) -- note template is just for the error message local debug="" local char="" local output="" local outputtable={} local wrapper=true local holding="" local nowiki posn=tonumber(posn) or 0 if posn>0 then text=mw.ustring.sub(text,posn,-1) end --- need to chop off the preceding text so it doesn't gmatch to it local getchar=mw.ustring.gmatch(text,".") local stopposn=posn+50000 stack=stack or {} local stackposn=#stack template=template or "" local spaces=0 repeat posn=posn+1 char=getchar() if not char then break end if spaces>0 and char~=" " and char~="|" then table.insert(outputtable,mw.ustring.rep(" ",spaces)) spaces=0 end -- cases based on what holding value is presently if holding=="{{" then -- cases based on the next char after "{{" if char=="#" then stackposn=stackposn+1 stack[stackposn]="{{#" holding="" char="" table.insert(outputtable,color.ize("{{#","{{#")) elseif char=="{" then stackposn=stackposn+1 stack[stackposn]="{{{" holding="" char="" table.insert(outputtable,color.ize("{{{","{{{")) else stackposn=stackposn+1 stack[stackposn]="{{" holding="" table.insert(outputtable,color.ize("{{","{{")) end elseif holding=="[" then -- cases based on the next char after "[" if char=="[" then stackposn=stackposn+1 stack[stackposn]="[[" holding="" char="" table.insert(outputtable,color.ize("[[","[[")) else table.insert(outputtable,holding) holding="" end elseif holding=="{" then -- cases based on the next char after "{" if char=="{" then holding="{{" char="" end elseif holding=="}}" then -- cases based on the POP once "{{" is found (something has to pop...) local pop=stack[stackposn] stack[stackposn]=nil stackposn=stackposn-1 if pop=="{{" or pop=="{{#" then holding="" table.insert(outputtable,color.ize(pop,"}}")) elseif pop=="{{{" then if char=="}" then char="" holding="" table.insert(outputtable,color.ize(pop,"}}}")) else table.insert(outputtable,color.ize(pop,"}}").."<--- error?") holding="" end elseif pop=="[[" then table.insert(outputtable,color.ize(pop,"}}").."<--- error?") holding="" end elseif holding=="]" then if char=="]" then local pop=stack[stackposn] stack[stackposn]=nil stackposn=stackposn-1 table.insert(outputtable,color.ize(pop,"]]")) if pop~="[[" then table.insert(outputtable,"<--- error?") end char="" holding="" else table.insert(outputtable,holding) holding="" end elseif holding=="}" then if char=="}" then holding="}}" char="" else table.insert(outputtable,holding) holding="" end end -- OK! No more cases based on holding; these are body chars if char==" " then char="" spaces=spaces+1 elseif char=="|" and stack[stackposn]~="{{{" and stack[stackposn]~="[[" then if mw.ustring.sub(holding,1,1)==" " then holding="" end table.insert(outputtable,holding) holding="" table.insert(outputtable,"
"..mw.ustring.rep(" ",4*stackposn).."|") elseif holding=="" then if char=="{" or char=="[" or char=="]" or char=="}" then holding=char char="" else table.insert(outputtable,char) char="" end end until posn>stopposn if stackposn>0 then table.insert(outputtable,"<--- end of run --->
run incomplete.") local stackcrypt=table.concat(stack,",") stackcrypt=mw.ustring.gsub(stackcrypt,"{","<") stackcrypt=mw.ustring.gsub(stackcrypt,"%[","(") stackcrypt=mw.ustring.gsub(stackcrypt,"}",">") stackcrypt=mw.ustring.gsub(stackcrypt,"%]",")") if posn>50000 then table.insert(outputtable,"
Note: due to restrictions on Lua time usage, runs are truncated at 50000 characters") posn=posn+1-mw.ustring.len(holding)-spaces
table.insert(outputtable,"
To continue this run, preview or enter {{#invoke:FormatTemplate|format|page="..template.."|stack="..stackcrypt.."|position="..posn.."}}") else table.insert(outputtable,"<br />''If you have an additional segment of template to process, preview or enter <nowiki>{{#invoke:FormatTemplate|format|page="..template.."|stack="..stackcrypt.."|position=0}}") end end output=table.concat(outputtable) return output end function p.main(frame,fcn) local args=frame.args local parent=frame.getParent(frame) if parent then pargs=parent.args else pargs={} end page=args.page or pargs.page local text=getContent(page) local stackcrypt=args.stack or pargs.stack or "" stackcrypt=mw.ustring.gsub(stackcrypt,"<","{") stackcrypt=mw.ustring.gsub(stackcrypt,"%(","[") stackcrypt=mw.ustring.gsub(stackcrypt,">","}") stackcrypt=mw.ustring.gsub(stackcrypt,"%)","]") local stack={} local posn=args.position or pargs.position or 0 local prowl=mw.ustring.gmatch(stackcrypt,"[^,%s]+") repeat local x=prowl() if x then table.insert(stack,x) end until not x fcn=fcn or args["function"] or pargs["function"] or "" fcn=mw.ustring.match(fcn,"%S+") -- text=text or args.text or pargs.text or args[1] or pargs[1] or "" -- doesn't work - gets interpreted or passed as "UNIQ..QINU", either way unusuable! local nowikisafehouse={} local nowikielementnumber=0 local prowl=mw.ustring.gmatch(text,"<nowiki>(.-)") repeat local nowikimatch=prowl() if not(nowikimatch) then break end nowikielementnumber=nowikielementnumber+1 table.insert(nowikisafehouse,nowikimatch) until false text=mw.ustring.gsub(text,"(.-)","<Module:FormatTemplate internal nowiki token>") -- this is the meat of the formatting if fcn=="format" then text=formatTemplate(text,stack,posn,page) end -- unprotect the nowikis from the template itself - but inactivate them on first display! for nw = 1,nowikielementnumber do text=mw.ustring.gsub(text,"<Module:FormatTemplate internal nowiki token>",""..nowikisafehouse[nw].."</nowiki>",1) end -- preprocess as nowiki-bounded text return frame:preprocess(""..text.."")
end
function p.format(frame)
return p.main(frame,"format")
end
return p