require('strict')
local DEBUG=false--DEBUG=true -- comment out or not runtime or debug
local p =local pargs =
p.main = function(frame) -- called from template pargs = frame:getParent.args local output local selectedTree -- subtree extracted from page content local modifiedTree -- subtree after pruning and grafting -- (1) get page local page = pargs['page'] or frame.args['page'] if not page then return p.errorMsg("Target page not provided") end -- (2) get content of page (move from _section, _label, etc) local content local title = mw.title.new(mw.text.trim(page)) --, ns) -- creates object if page doesn't exist (and valid page name) --TODO: could use mw.title.makeTitle, but that needs ns if title then if title.exists then content = title:getContent if not content then return p.errorMsg("Content of " .. page .. " not loaded.") end else return p.errorMsg('Page with title "' .. page .. '" not found.') end end -- (3) select from content local section = pargs['section'] or pargs['section1'] or pargs[1] if section then selectedTree = p._section(frame, content, section) end local label = pargs['label'] or pargs['label1'] or pargs[1] if label then selectedTree = p._label(frame, content, label) end --TODO does this need to be separate from label? local subtree = pargs['subtree'] or pargs['subtree1'] or pargs[1] if subtree then selectedTree = p._label(frame, content, subtree) end if not selectedTree then -- if none of options retrieve anything p.errorMsg("Nothing retrieved for selection option " .. (label or subtree or section or "none")) end
if DEBUG then return selectedTree end --- returns the code captured without processing --(4) modify content (excise and replace; prune and graft) local exclude = pargs['exclude'] or pargs['exclude1'] if exclude then if pargs['exclude'] then pargs['exclude1'] = pargs['exclude'] end if pargs['replace'] then pargs['replace1'] = pargs['replace'] end modifiedTree = selectedTree local i = 1 while pargs['exclude'..i] do local exclude = pargs['exclude'..i] local replace = pargs['replace'..i] or " " -- must be something modifiedTree = p._xlabel(frame, modifiedTree, exclude, replace) i=i+1 end else modifiedTree = selectedTree end --(5) other options ----- suppress hidden elements if pargs['nohidden'] then modifiedTree = modifiedTree:gsub("lade hidden", "lade") end ----- suppress authorities (or anything in small tags) if pargs['noauthority'] then modifiedTree = modifiedTree:gsub(".-", "") end ----- suppress images if pargs['noimages'] then modifiedTree = modifiedTree:gsub("%[%[File:.-%]%]", "") end ----- wrap in outer clade local wrap = pargs['wrap'] if wrap and (label or subtree) then local label1 = label or string.lower(subtree) local styleString = "" if pargs['style'] then styleString = '|style=' .. pargs['style'] end if wrap ~= "" then label1 = wrap end output = "" -- last space before double brace important else output = modifiedTree end --(6) return final tree if output then if pargs['raw'] then return output else return frame:preprocess(output) end end return p.errorMsg("No valid option for transclusion")end
--
= extract LABELS or SUBTREES
p._label = function (frame, content, ...)-- local page = "User:Jts1882/sandbox/test/Passeriformes"-- local label = frame.args[1] or frame.args['label'] local args = local output = "" if not args[1] then return p.errorMsg ("Label name not provided") end local mode = "label" local targetType = "label(%d)" -- standard label of form |labelN= (captures N) local cladePrefix = "(%d)" -- standard node of form |N= (captures N) for k,v in pairs(args) do local section = mw.text.trim(v) if string.upper(section)
local index1, index2, selectedTree = string.match(content, pattern) -- note index1 and index2 should match (X=X or N=N)
if selectedTree then --N= we want to substitute the subtree but not when the form is |targetX= local pattern2 = "" -- this captures both |N= and |targetX= -- we only want to substitute a subtree in the first kind -- will exclude second with pattern3 test below if string.find(selectedTree, pattern2) then -- if a subtree that hasn't been substituted. --local i,j,target = string.find(value, pattern2) -- only one subtree local i=0 for bracedMarker in string.gmatch(selectedTree, pattern2) do i=i+1
-- bracedMarker is either a marker in the tree or part of following -- targetX= ... |subcladeX=s then local pattern3 = "target(%u)=[%s]*"..bracedMarker
--?? if selectedTree
----disable method 1 selectedTree = string.gsub(selectedTree, bracedMarker, subtree, 1)
--targetX= |subcladeX=subtree" before last double brace of selectedTree use capture in pattern3 to find X local i,j,X = string.find(content, pattern3) if selectedTree
output = output .. selectedTree else output = output .. p.errorMsg ("Failed to capture subclade with " .. mode .. " " ..section) end
end if output ~= "" then return output -- preprocess moved to entry function else return '
Section for label not found' endend--
p.xlabel = function (frame, page, ...) local page = frame.args[1] --"User:Jts1882/sandbox/test/Passeriformes" local label = frame.args[1] or frame.args['label'] or frame.args['label1'] -- page, target tree, subtrees to exclude ... -- page, include clade, multple clades to exclude | return p._xlabel (frame, page, frame.args[2], frame.args[3], frame.args[4], frame.args[5])
endp._xlabel = function (frame, targetTree, exclude, replace)
local fullOutput = targetTree --local fullOutput = p._section(frame, page, target)
local output=targetTree -- return unmodified tree if nothing happens local section = exclude local targetType = "label%d" local cladePrefix = "%d" if string.upper(section)
-- label = name |n= local pattern = "("..targetType.."=[%s%p]*"..section .. "[%s%p]*.-"..cladePrefix.."=.-)(%b)" -- ^^ this .- skips section tags before clade -- ^^this .- skips |sublabel and styling following the label (but can return wrong clade when a subtree) local value = string.match(fullOutput, pattern) if value then local trimmedTree, matches = string.gsub(fullOutput, pattern, "%1"..replace)--replaces pattern with capture %1 return trimmedTree else local message = "" if string.upper(section)
if output ~= "" then return output .. '
Nothing pruned' --return frame:preprocess(fullOutput) else return 'Section for label not found' -- shouldn't get here endend--
SECTION
for k,v in pairs(args) do local section = mw.text.trim(v) -- local pattern = "(.-)"
for value in string.gmatch(content, pattern) do if value then if frame.args.wrap or frame:getParent.args.wrap then local label1 = frame.args.wrap or frame:getParent.args.wrap if label1
end end if pargs['norefs'] or pargs['noref'] then -- strip out references --output = mw.text.killMarkers(output) if output:find("', "") output = output:gsub("[1]
end
p.xsection = function (frame) local page = frame.args[1] --"User:Jts1882/sandbox/test/Passeriformes" local label = frame.args[1] or frame.args['label'] or frame.args['label1'] -- page, target tree, sections to exclude ... return frame:preprocess(p._xsection(frame, page,frame.args[2],frame.args[3],frame.args[4],frame.args[5]))end
p._xsection = function (frame,page, target, ...) local args = local output = "" local title = mw.title.new(page) --, ns) -- creates object if page doesn't exist (and valid page name) --TODO: could use mw.title.makeTitle, but that needs ns if title and title.exists then local content = title:getContent local fullOutput = p._section(frame, page, target) output=fullOutput for k,v in pairs(args) do local section = mw.text.trim(v) -- local pattern = "()(.-)()"
local value = string.match(fullOutput, pattern)
if value then local trimmedTree, matches = string.gsub(fullOutput, pattern, "replacement string")--replaces pattern with capture %1 output = output .. trimmedTree output = output .. "
" .. trimmedTree .. "" fullOutput = trimmedTree else output = output .. p.errorMsg ("Failed to capture subclade with label "..section) end
end
else return '
No page title found' end if output ~= "" then --return frame:preprocess(output) return output -- leave preprocessing for entry function else return 'Section not found' endend
function p.firstToUpper(str) return (str:gsub("^%l", string.upper))endp.errorMsg = function (message) return '
' .. message .. '' end p.warningMsg = function (message) return '' .. message .. ''end return p