Module:FormatTemplate

From Sarkarverse
Revision as of 23:53, 22 October 2013 by T12 (talk | contribs) (1 revision)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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