Modul:FormatTemplate
Seba na module şıma şenê yû pela dokumani vırazê Modul:FormatTemplate/dok
---- 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><span style="color:'..c..';">'..chars..'</span><nowiki>'
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,"</nowiki><br /><nowiki>"..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 ---></nowiki><br />'''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,"<br />''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,"<br />''To continue this run, preview or enter <nowiki>{{#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>(.-)</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,"<nowiki>(.-)</nowiki>","<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>","<nowiki>"..nowikisafehouse[nw].."</now</nowiki>iki>",1)
end
-- preprocess as nowiki-bounded text
return frame:preprocess("<nowiki>"..text.."</nowiki>")
end
function p.format(frame)
return p.main(frame,"format")
end
return p