请输入您要查询的百科知识:

 

词条 Module:FormatTemplate/sandbox
释义 ---- This module is meant to produce a first pass translation from a template to a module.---- It scans character by character, one time ONLY, using getletter().---- It works by recognizing every beginning that the following features should not be intermingled: [[, {{, {{#, {{{---- It works through which of these features is present by character-by-character scanning---- As a result, a new stack[] table entry is created, according to how many levels deep in we are.---- At each meaningful : or |, separating fields in these features, it accumulates existing text to stack[n].text---- Within a field, stack.append() is used to attach text to stack[n].out (text to be quoted) or stack[n].code (accumulated with quotes, or statements)---- For functions that are understood by it (stack.annotate) it translates the features to Lua code.---- variables get their own little var[] array. At the moment parameters are unique but parser functions may be reduplicated.---- The beginnings and ends of features are labeled with colored spans, but most text is in nowiki tags.---- The result is generally any text to output to the new module with a need to wiki (br /'s) should go ... ---- The output should be postprocessed with another function, not yet written, to remove futile concatenations, lines marked for deletion, etc.---- The output should be formatted with another function, not yet written, to impose proper indentation.local p={}-- constantslocal MAXPOSN = 100000 -- usually 50000 was 3 seconds .. not right now though ..local HOLDABLE = {["{"] = true, ["["] = true, ["}"] = true, ["]"] = true}local ACTABLE = {["{"] = true, ["["] = true, ["}"] = true, ["]"] = true, ["|"] = true, [":"] = true}local MARKER = {["{{{"] = "|", ["{{"] = "|", ["{{#"] = ":", ["[["] = "|"}local MATCH = {["{{{"] = "}}}", ["{{#"] = "}}", ["{{"] = "}}", ["[["] = "]]"}local ENDQUOTE = {['"'] = '"', ["'"] = "'", ["[=["] = "]=]", ["[==["] = "]==]", ["[===["] = "]===]", ["[====["] = "]====]", ["[=====["] = "]=====]", ["[======["] = "]======]", ["[=======["] = "]=======]", ["[========["] = "]========]", ["[=========["] = "]=========]", ["[==========["] = "]==========]", ["[===========["] = "]===========]", ["[============["] = "]============]", ["[=============["] = "]=============]"}local DUPLICATECASES = 3 -- number of times to duplicate code setting a variable inside "then xxxx" cases rather than calculate it for all cases.local text = ""local debuglog = ""local getletter -- this module is designed around reading ONCE, tracking state; getletter() gets each letter in text oncelocal flag = false -- true marks the end of the getletter() streamfunction 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 ""endlocal function scanabort() flag = true return ":" -- an "actable" to prevent loopingendlocal function escape(text) text = string.gsub(text,"%A%D","_") return textendlocal function quote(text) text = (not string.match(text,'"')) and ('"' .. text .. '"') or (not string.match(text,"'")) and ("'" .. text .. "'") or (not string.match(text,'%[=%[') and '[=[' .. text .. ']=]') or (not string.match(text,'%[==%[') and '[==[' .. text .. ']==]') or (not string.match(text,'%[===%[') and '[===[' .. text .. ']===]') or (not string.match(text,'%[====%[') and '[====[' .. text .. ']====]') return textendfunction translateModule(text,importstack,posn,template) -- note template is just for the error message local letter="" local output="" local outtable, vartable = {}, {} posn=tonumber(posn) or 0 if posn>0 then text=string.sub(text,posn,-1) end --- need to chop off the preceding text so it doesn't gmatch to it local stopposn = (string.find(text, "[^{}%[%]|:]", MAXPOSN)) if stopposn then text= string.sub(text, 1, stopposn) end -- vars holds all the parameters vars = {top = 0, list = {}} vars.declare = function(id, name) if vars.list[name] then return vars.list[name] else vars.list[name] = id return id end end -- pars is like vars, for parser functions. The entire stack entry has to be generated, and on pop, see if, minus its -- p_nnn name, it exactly matches a previous entry; if so, "drop" the old p_nnn to the last layer and add no new statement at all. -- this should work because otherwise nothing goes in and redefines p_nnn once it's set. pars = {list = {}} pars.declare = function(id, text) text = string.gsub(text, id, "t_") local pl = pars.list[text] if pl then return pl, false else pars.list[text] = id return id, true end end -- stack is the main structure for holding the data. Each time a feature is found you go up a level. -- When you go down you create a statement or append text into the stack a level lower (or both). stack = {top = #importstack, counter = 0} for i = 0, stack.top do stack[i] = {} stack[i].feature = importstack[i] stack[i].text = {} stack[i].seg = 1 -- this is NOT ACCURATE, would need to be saved in the transition end -- this table defines the code to deal with specific parser functions like {{#ifeq: Also some functions for other features. stack.annotate = { -- name is the first field of the feature ('if' or the parameter name); id is the counter number -- text for the THESE STATEMENTS (stack top we're writing to) -- %1=if %2 then %3 else %4 end ['param1'] = {function(last, text, varid) return '(' .. varid .. ' or ' .. '"{{{' .. string.sub(varid, 3, -1) .. '}}}")' end, etc = function(last, text) return " .. " .. quote("|" .. text) end, -- shouldn't happen...... last = function(last, text) return text end}, ['param2'] = {function(last, text, varid) return "(" .. varid .. (last and "" or " or ") end, function(last, text) return quote(text) end, -- returned as _code_ etc = function(last) return " .. " .. quote("|" .. text) end, -- shouldn't happen...... last = function(last, text) return text .. ")" end}, ['if'] = {function(last) return "if mw.text.trim(" end, function(last, text, varid) if text == "" then text = '""' end text = text .. ') ~= "" then
    ' if last then -- {{#if:%1}} will return empty string in any case. This is a dumb way to do it, transitional... text = text .. varid .. ' = ""
else
    ' .. varid .. ' = ""' else text = text .. varid .. ' = ' end return text end, function(last, text, varid) if text == "" then text = '""' end if last then -- {{#if:%1|%2}} will return empty string if %1 is false text = text .. '
else
    ' .. varid .. ' = ""' else text = text .. '
else
    ' .. varid .. ' = ' end return text end, function(last, text, varid) if text == "" then -- this is %3 in {{#if:%1|%2|%3}} return '""' else return text end end, -- this is stupid, but quotes are suppressed on null out string, so... etc = function(last, text) return "
-- " .. text .. ': ignored' -- you can have {{#if:%1|%2|%3|%4}}, but %4 isn't displayed at all, even when %3 is end, last = function(last, text) return text .. "
end" end}, -- weirdly, having function(last) there caused "Not enough memory" error, not nil truncation error ['ifeq'] = {function(last) return "if mw.text.trim(" end, function(last, text, varid) return text .. ') == mw.text.trim(' end, function(last, text, varid) if text == "" then text = '""' end text = text .. ') then
' if last then text = text .. varid .. ' = ""' else text = text .. varid .. ' = ' end return text -- returned as _code_ end, function(last, text, varid) if text == "" then text = '""' end if last then text = text .. '
else ' .. varid .. ' = ""' else text = text .. '
else ' .. varid .. ' = ' end return text end, function(last, text, varid) if text == "" then text = '""' end return text end, etc = function(last, text) return "
-- " .. text .. ": ignored" end, last = function(last, text) return text .. "
end" end}, ['switch'] = { function(last, text, varid) return varid .. '_in = mw.text.trim(' end, function(last, text, varid) return text .. ")
if " .. varid .. "_in == mw.text.trim(" end, etc = function(last, text, varid) -- debuglog = debuglog .. "text=" .. text local text1 = string.match(text, "^([^=]*)")-- I don't know if I'll ever figure out what variable type string.match returns local text2 = string.match(text, "=(.*)") if text2 then local quotetype = string.sub(text1, 1, 1) -- text is received as a quoted string. Need to split at the "=". if (quotetype == "[") then quotetype = string.match(text1, "%[=*%[") end text1 = text1 .. ENDQUOTE[quotetype] text2 = quotetype .. text2 end if last then if not text2 then return "'[TOKEN: DELETE LINE]') then
else " .. varid .. " = " .. text1 .. "
" elseif (string.match(text1, "#default")) then -- this isn't technically foolproof, but compared to the potential bugs in unquoting, whitespace, unicode, etc... return "'[TOKEN: DELETE LINE]') then
else " .. varid .. " = " .. text2 .. "
" else -- debuglog = debuglog .. "DB" .. mw.text.trim(text1) .. "BD" return "'[TOKEN: DELETE LINE]') then
elseif " .. varid .. " == " .. text2 .. " then
    " .. varid .. " = " .. text1 .. "
" end else if not text2 then return text1 .. " or " else -- debuglog = debuglog .. "text1=" .. text1 .. "text2=" .. text2 return text1 .. ") then
" .. varid .. " = mw.text.trim(" .. text2 .. ((not last) and (")
elseif " .. varid .. "_in == mw.text.trim(") or ")") end end end, last = function(last, text) return text .. " end" end}, ['parser'] = { function (last, text, varid) return '"{{#" .. ' .. text end, -- '"{{#" .. ' .. text end, function(last, text, varid) return ' .. ":" .. ' .. text end, -- unknown parser functions are {{%1:%2|%3|etc.}} etc = function(last, text, varid) return ' .. "|" .. ' .. text end, last = function(last, text, varid) return text .. ' .. "}}"' end}, -- ' .. "}}"' end}, ['template'] = { function (last, text, varid) return '"{{" .. ' .. text end, -- '"{{" .. ' .. text end, function (last, text, varid) if varid == ':' then return ' .. "' .. varid .. '" .. ' .. text else return ' .. "|" .. ' .. text end end, etc = function(last, text, varid) return ' .. "|" .. ' .. text end, last = function(last, text, varid) return text .. ' .. "}}"' end}, -- ' .. "}}"' end}, ['wikilink'] = { function (last, text, varid) return '"[[" .. ' .. text end, -- '"" .. ' .. text end, etc = function(last, text, varid) return ' .. "">" .. ' .. text end, last = function(last, text, varid) return text .. ' .. "]]"' end} } -- ' .. ""' end} } stack.append = function(text, codeflag) -- code is true if text doesn't need to be quoted -- stack[stack.top] shall contain two buffers of text, to which text can be added at the end by concatenation: .text, .code -- stack[stack.top].text is fully archived from previous fields -- stack[stack.top].code is ready to add to the Lua source, but is in the present field -- stack[stack.top].out is new text mode additions from the template. It gets quoted and transferred to code whenever code is added. if text ~= "" then stack[stack.top].dropped = nil end if codeflag then if (not stack[stack.top].code) then stack[stack.top].code = text stack[stack.top].start = true return end if stack[stack.top].out ~= "" then if stack[stack.top].code ~= "" then stack[stack.top].code = stack[stack.top].code .. " .. " end if text ~= "" then text = " .. " .. text end stack[stack.top].code = stack[stack.top].code .. quote(stack[stack.top].out) .. text else stack[stack.top].code = stack[stack.top].code .. text end stack[stack.top].out = "" else if (not stack[stack.top].out) then stack[stack.top].out = text return end stack[stack.top].out = stack[stack.top].out .. text end end -- this is done at the end of a field (like at a "|" in a switch statement. -- fcn is some annotation function chosen per the stack's record of the name of the parser function for that stack level. stack.codify = function(fcn, id, name, last) stack.append("", true) stack[stack.top].dropped = nil stack[stack.top].code = fcn(last, stack[stack.top].code, id, name) or stack[stack.top].code end -- this is done when a new feature is found; move up to the next level. -- Note stack[n] is a new table each time, so all its fields are nil by default. stack.push = function(feature) stack.top = stack.top + 1 stack[stack.top] = {} if feature == "{{{" then stack[stack.top].text = {} else stack[stack.top].text = {"
"} end stack[stack.top].seg = 1 -- which field we're in (IF 1 = 2 THEN 3 ELSE 4) delimited by | or : stack[stack.top].feature = feature -- actual text to open the sequence i.e. {{# end -- the end of a feature is found; now collapse its contents, or some memo, to the preceding level, or make a new statement about it. -- Note that in Wikitext the lower stack levels get input data _only_ from higher stack levels, and those are closed first, -- so in theory a variable should always be set _before_ they're accessed. stack.pop = function(feature) stack.field("", true) local spillover = "" local pop = stack[stack.top].feature if (MATCH[pop] ~= feature and feature == "}}}") then feature = "}}" spillover = "}" end if (MATCH[pop] ~= feature) then stack.append("<--- error? ") end stack.write() local feature = stack[stack.top].feature local name = stack[stack.top].name local id = stack[stack.top].id local text = table.concat(stack[stack.top].text) stack[stack.top] = nil stack.top = stack.top - 1 if feature == "{{" or (feature == "{{#" and name == "parser") then -- wikitext if stack[stack.top].dropped then text = " .. " .. text end stack.append(text, true) -- this is not lua code anymore here stack[stack.top].dropped = true elseif feature == "{{#" then -- parsed parser function, new line local novel id, novel = pars.declare(id, text) if novel then table.insert(outtable, text) end if stack[stack.top].dropped then id = " .. " .. id end stack.append(id, true) stack[stack.top].dropped = true elseif feature == "[[" then -- ordinary wikitext for display if stack[stack.top].dropped then text = " .. " .. text end stack.append(text, true) -- links are just quoted text, but for some reason "true" mode works and text mode doesn't.... stack[stack.top].dropped = true elseif feature == "{{{" then if stack[stack.top].dropped then text = " .. " .. text end stack.append(text, true) -- this is lua variable name for the parameter stack[stack.top].dropped = true end return spillover end -- hit ":" or "|", the former used only in parser functions on the first field, or as a stand-in for the end of data stack.field = function (letter, last) local ss = stack[stack.top] -- first make sure this is really a field boundary if (last or (ss.seg == 1 and (letter == MARKER[ss.feature] or (ss.feature == "{{" and letter == ":"))) or (ss.feature ~= "[[" and ss.feature ~= "{{" and letter=="|")) then -- if we don't know, we need to know the name of this segment (unless we're just moving it through as text) if (ss.seg == 1) then local name = mw.text.trim(stack[stack.top].out) -- this misses a parser error if "#if :" is called. Sue me. if (ss.feature == '{{#') then ss.name = stack.annotate[name] and name or "parser" ss.id = "p_" .. tostring(stack.counter) stack.counter = stack.counter + 1 -- now if the feature is {{{ then we register a variable name ( elseif (ss.feature == '{{{') then ss.name = name ss.id = vars.declare("t_" .. escape(name), name) -- will be an old id if it exists if last then ss.name = "param1" else ss.name = "param2" end elseif (ss.feature == '[[') then ss.name = "wikilink" ss.id = "_link_" else ss.name = "template" ss.id = letter -- i.e. in unimplemented function {{urlencode:, make the terminating character the id to distinguish end end stack.append("", true) -- now we know the name, I think. local fcn = stack.annotate[(not ss.id and "template") or ss.name] if fcn[ss.seg] then stack.codify(fcn[ss.seg],ss.id, ss.name, last) else stack.codify(fcn["etc"],ss.id, ss.name, last) -- this is pretty muddy - using last both as a flag for preceding sections and as a function tack-on. Should convert all uses of the second to the first. end if last then stack.codify(fcn["last"],ss.id, ss.name) end ss.seg = ss.seg + 1 stack.write() else -- NOT a new field, so don't do anything stack.append(letter) end end -- first uses append of "" as code to close out stack[n].code (this field's text contents) -- then inserts that in stack[n].text (simple concatenation only, stored until the stack is closed) stack.write = function() stack.append("", true) -- blank code addition forces quotation of remaining text table.insert(stack[stack.top].text, stack[stack.top].code) stack[stack.top].code = "" end -- this is the main loop to read character by character from the source text template=template or "" getletter = string.gmatch(text,".") stack[stack.top].out, stack[stack.top].code = "", "" repeat local holding = "" repeat letter = letter or "" while not ACTABLE[letter] do stack.append( letter) letter = getletter() or scanabort() end if HOLDABLE[letter] then holding = letter else stack.field(letter) end letter = "" until holding ~= "" or flag if #stack[stack.top].out>7500 then stack.write() end letter=getletter() or scanabort() -- add the letter to the next feature being parsed if possible if (holding == "[") then -- either [[ or just ignore -- cases based on the next letter after "[" if (letter == "[") then stack.push("[[") letter = "" else stack.append( holding) -- single [, treat normally end elseif (holding == "{") then -- cases based on the next letter after "{" if (letter == "{") then letter = getletter() or scanabort() if (letter == "#") then stack.push("{{#") letter = "" elseif (letter == "{") then stack.push("{{{") letter = "" else stack.push("{{") end end elseif (holding == "]") then if (letter == "]") then -- we have a ]] stack.pop("]]") letter = "" else stack.append(holding) end elseif (holding == "}") then if (letter == "}") then letter = getletter() if letter == "}" then letter = stack.pop("}}}") else stack.pop("}}") end else stack.append(holding) -- lone } is nothing end end until flag -- a colon is used to indicate EOF to avoid checking for "flag" in the scan loop itself; this removes it stack[stack.top].out = string.sub(stack[stack.top].out, 1, -2) table.insert(vartable, " ---- beginning of module ----
local p = {}

getArgs = require('Module:Arguments').getArgs

p.main = function(frame)
args = getArgs(frame)

") table.insert(vartable, " -- begin variable table
") for k, v in pairs(vars.list) do if (tonumber(k) == nil) or (tonumber(k) < 1) or (tonumber(k) % 1 ~= 0) then -- quote all non positive integers, others are numbers table.insert(vartable, "local " .. tostring(v) .. " = args['" .. k .. "'] and mw.text.trim(args['" .. k .. "'])
") else table.insert(vartable, "local " .. tostring(v) .. " = args[" .. k .. "] and mw.text.trim(args[" .. k .. "])
") end end local pdeclare local pdeclareused local parssort = {} for k, v in pairs(pars.list) do table.insert(parssort, tonumber(string.sub(v, 3, -1))) pdeclareused = true end if parssort[1] then table.sort(parssort) pdeclare = "local p_" .. table.concat(parssort, ", p_") .. "
" else pdeclare = "" end table.insert(vartable, pdeclare) table.insert(vartable, " -- end variable table

 -- begin parser function translations") if stack.top>0 then stack[stack.top].out = string.sub(stack[stack.top].out, 1, -2) .. "<--- end of run ---><br />run incomplete."
        stack.write()        -- this code hasn't been updated - it doesn't contain all the information needed to resume a run!        local stackcrypt = ""        for i = stack.top, 1, -1 do        	table.insert(outtable, table.concat(stack[i].text))                stackcrypt = stackcrypt .. stack[i].feature                stack[i] = {}        end        stack.top = 0        stackcrypt=string.gsub(stackcrypt,"{","<")        stackcrypt=string.gsub(stackcrypt,"%[","(")        stackcrypt=string.gsub(stackcrypt,"}",">")        stackcrypt=string.gsub(stackcrypt,"%]",")")        if string.len(text) >= MAXPOSN then -- didn't complete the run, making false promises to the user now:            stack[stack.top].out = stack[stack.top].out .. "
''Note: due to restrictions on Lua time usage, runs are truncated at MAXPOSN characters''"
            stack[stack.top].out = stack[stack.top].out .. "
''To continue this run, preview or enter {{#invoke:FormatTemplate|toModule|page="..template.."|stack="..stackcrypt.."|position="..#text.."}}" else stack[stack.top].out = stack[stack.top].out .. "<br />''If you have an additional segment of template to process, preview or enter <nowiki>{{#invoke:FormatTemplate|toModule|page="..template.."|stack="..stackcrypt.."|position=0}}" end end stack.write() -- var table is the variable declarations; outtable is the statements (if t_1 == "" then t_1 = "stuff"); stack[0] is the return statement output=table.concat(vartable) .. table.concat(outtable, "
") .. "
 -- end parser function translations

return frame:preprocess(" .. table.concat(stack[0].text, "
") .. ")
end
return p
 ---- end of module ----
" return outputendfunction p._toModule(stackcrypt, posn) -- none of this stack/posn stuff actually works any more, it's tremendously out of date! stackcrypt=mw.ustring.gsub(stackcrypt,"<","{") stackcrypt=mw.ustring.gsub(stackcrypt,"%(","[") stackcrypt=mw.ustring.gsub(stackcrypt,">","}") stackcrypt=mw.ustring.gsub(stackcrypt,"%)","]") local stack={} local prowl=mw.ustring.gmatch(stackcrypt,"[^,%s]+") repeat local x=prowl() if x then table.insert(stack,x) end until not x local nowikisafehouse={} local nowikielementnumber=0 local prowl=mw.ustring.gmatch(text,"(<nowiki>.-<%/nowiki>)") repeat local nowikimatch=prowl() if not(nowikimatch) then break end nowikimatch = mw.ustring.gsub(nowikimatch, "<", "<") -- I want these inactive on display nowikielementnumber=nowikielementnumber+1 table.insert(nowikisafehouse,nowikimatch) until false local nowikicount text, nowikicount = mw.ustring.gsub(text,"(<nowiki>.-<%/nowiki>)","<Module:FormatTemplate internal nowiki token>") debuglog = debuglog .. "-- " .. tostring(nowikicount) .. " nowiki segments treated as plain text" text = mw.ustring.gsub(text, "\", '\\\') -- trying preserving ALL newlines -- this is the meat of the formatting text=translateModule(text,stack,posn,page) -- 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], 1) end text = "<nowiki>" .. text .. "" -- returns global changes in text, debuglog

end

function nextquote(posn)

-- starting from a position that we know is not in a string, comment, etc.!

local quotes = {['(")'] = function() return '"' end,

["(')"] = function() return "'" end,

["(%[=+%[)"] = function(q) return "]" .. string.sub(q, 2, -2) .. "]" end}

    local startquoteposn = #text    local loc, xxx, startquotetype, endquotetype, endquoteposn

for k,v in pairs(quotes) do

loc, xxx, startquotetype = string.find(text, k, posn)

if (loc and loc < startquoteposn) then

startquoteposn = loc

endquotetype = v(startquotetype)

end

    end    if (startquoteposn == #text) then return nil end -- no more quotes!    xxx, endquoteposn = string.find(text, endquotetype, startquoteposn + 1)    return startquoteposn, endquoteposn, endquotetype

end

function p._fixIfs()

-- receives global 'text'

-- if a parser variable will only be used within "a few" if statements, only calculate it there.

-- (in theory this applies to params, but it's nicer to have a full table up front)

text = string.gsub(text, "\[^\]-%[TOKEN: DELETE LINE%][^\]-\", "\") -- finally clear up those delete line tokens. Might move to earlier pass...

local pdec = string.match(text, "local (p_.-)\")

assert(pdec, "failed to find 'local p_nnn...' variable list")

pdec = mw.text.split(pdec, ", ") -- pdec is now a sequence of all the p_nnn variables in the order they are first mentioned in the first pass code

local xxx, parssegstart, parssegend -- xxx = throwaway value. This function only messes with the scope of parser function evaluations.

xxx, parssegstart = string.find(text, "\%s%-%- begin parser function translations\")

parssegend = string.find(text, "\%s%-%- end parser function translations\", parssegstart)

debuglog = debuglog .. tostring(parssegstart) .. "FFF" .. tostring(parssegend)

local parsseg = string.sub(text, parssegstart, parssegend)

local parsarray = mw.text.split(parsseg, "\\")

-- parsarray is now made up of individual popped stack entries from the first pass. #if, #ifeq, #switch, for example.

local parsusages = {} -- which variables appear in one parsseg (dictionary)

local varusages = {} -- which parssegs a variable appears in (sequence)

for i = 1, #pdec do

varusages[pdec[i]] = {}

end

for i = 1, #parsarray do

local getvar = string.gmatch(parsarray[i], "(p_%d*)")

parsusages[i] = {}

repeat

var = getvar()

if not var then break end

debuglog = debuglog .. "-" .. var

parsusages[i][var] = true

table.insert(varusages[var], i)

until false

end

-- Now we go through the variables last to first. If a p_variable is used only in DUPLICATECASES or fewer "then XXX" statements, insert the code setting it after 'then'

for i = #pdec, 1, -1 do

local var = pdec[i]

if #varusages[var] <= DUPLICATECASES then

-- OK, now each variable ought to be assigned only the first time it is mentioned, used all the others

-- first, for now we're not trying to do anything with variables called in the decision making logic (the if, or assignment of p_nnn_in

local predicate = false

for c = 2, #varusages[var] do

                local xxx, predend = string.find(parsarray[i], "then\")                if not predend or string.find(string.sub(parsarray[i], 1, predend), var) then                	predicate = true                -- now figure out where/which line to substitute, but don't do it until all pass the test            end            if not predicate then            	-- substitute these segments, blank out the entries for the moved segment            end

end

end

end

text = mw.text.nowiki(text) -- just to mark for now

    debuglog = "\Debug data:\" .. mw.text.nowiki(debuglog)    -- returns global 'text', 'debuglog'

end

function p._fixConcats()

-- receives global 'text'

-- tokenize comments to avoid getting fouled

local outarray = {}

posn = 1

quote1 = {nextquote(1)}

repeat

quote2 = {nextquote(quote1[2]+1)}

if not quote2[1] then break end

-- do something with the concat if it's just a concat

if (mw.text.trim(string.sub(text, quote1[2] + 1, quote2[1] - 1)) == "..") then

if (quote1[3] == quote2[3]) then

table.insert(outarray, string.sub(text, posn, quote1[2] - 1))

posn = quote2[1] + 1

end

end

quote1 = quote2

until false

table.insert(outarray, string.sub(text, posn, -1))

text = "

" .. mw.text.nowiki(table.concat(outarray)) .. "
"

end

-- this function also (mis)handles the pre-processing to get rid of nowikis and comments (only it doesn't do the comments yet, etc...)

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    text = getContent(page)    local stackcrypt=args.stack or pargs.stack or ""    local posn=args.position or pargs.position or 0     -- decide on a function    fcn=fcn or args["function"] or pargs["function"] or ""    fcn=mw.ustring.match(fcn,"%S+")    if (fcn == "toModule") then    	p._toModule(stackcrypt, posn) -- passing text, debuglog globally    elseif (fcn == "fixConcats") then    	p._fixConcats()    elseif (fcn == "fixIfs") then    	p._fixIfs()    end     -- preprocess as nowiki-bounded text    return frame:preprocess(text .. "\" .. debuglog)

end

function p.toModule(frame)

end

return p

随便看

 

开放百科全书收录14589846条英语、德语、日语等多语种百科知识,基本涵盖了大多数领域的百科知识,是一部内容自由、开放的电子版国际百科全书。

 

Copyright © 2023 OENC.NET All Rights Reserved
京ICP备2021023879号 更新时间:2024/9/25 16:27:33