Module:Clade/transclude
Appearance
![]() | This module is rated as alpha. It is ready for third-party input, and may be used on a few pages to see if problems arise, but should be watched. Suggestions for new features or changes in their input and output mechanisms are welcome. |
Module for template {{Clade transclude}} with functions for partial transclusion of cladograms made with the {{Clade}} template.
Usage
{{#invoke:Clade|main}}
Parameters described at {{Clade transclude}}.
Testcases:
- {{Clade transclude/testcases}} (examples using nested subtrees)
- {{Clade transclude/testcases2}} (examples with all trees at basal clade)
require('Module:No globals')
local p ={}
local pargs ={}
p.main = function(frame) -- called from template
pargs = frame:getParent().args
local output
local page = pargs['page']
if not page then p.errormsg("Target page not found") end -- TODO check for page existence here
local section = pargs['section'] or pargs['section1'] or pargs[1]
if section then
output = p._section(frame, page, section)
end
local label = pargs['label'] or pargs['label1'] or pargs[1]
if label then
output = p._label(frame, page, label)
end
local subtree = pargs['subtree'] or pargs['subtree1'] or pargs[1]
if subtree then
output = p._label(frame, page, subtree)
end
local wrap = pargs['wrap']
if wrap and (label or subtree) then
local label1 = label or string.lower(subtree)
if wrap ~= "" then label1 = wrap end
output = "{{clade |label1=" .. p.firstToUpper(label1) .. "|1=" .. output .. "}}"
end
if output then
return frame:preprocess(output)
end
return p.errormsg("No valid option for transclusion")
end
p.test = function(frame)
--mw.title.makeTitle( namespace, title, fragment, interwiki )
--mw.title.new( text, namespace )
local page = "User:Jts1882/sandbox/test/Passeriformes" --"Atelopus andinus"
local section = "Passeriformes"
local ns = 1
if page:find("^User") then ns = 2 end
if page:find("^Template") then ns = 10 end -- TODO check number
--mw.site.namespaces.User.id -- returns 2
--TEST PAGE = User:Jts1882/sandbox
return p._section(frame,page, "Passeroidea ", "Corvida", "Tyranni")
end
p.test_working_prototype = function(frame)
--mw.title.makeTitle( namespace, title, fragment, interwiki )
--mw.title.new( text, namespace )
local page = "User:Jts1882/sandbox/test/Passeriformes" --"Atelopus andinus"
local ns = 1
if page:find("^User") then ns = 2 end
if page:find("^Template") then ns = 10 end -- TODO check number
--mw.site.namespaces.User.id -- returns 2
--TEST PAGE = User:Jts1882/sandbox
local title = mw.title.new( page) -- , ns)
if title then
local content = title:getContent()
local pattern = "<section begin=Passeriformes />(.+)<section end=Passeriformes />"
pattern = "{{#tag:section||begin=Test}}(.+){{#tag:section||end=Test}}"
local value = string.match( content , pattern )
if value then
return frame:preprocess(value)
--return value
else
return "no match found"
end
return content
end
return "Hello"
end
--================================== exclude LABEL ================================================
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])
end
p._xlabel = function (frame, page, target, ...)
-- 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 fullOutput = p._label(frame, page, target)
--local fullOutput = p._section(frame, page, target)
output=fullOutput
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 and title.exists then
local content = title:getContent()
for k,v in pairs(args) do
local section = mw.text.trim(v)
local targetType = "label%d"
local cladePrefix = "%d"
if string.upper( section) == section then
targetType = "target%u" -- by convention subtrees must be uppercase
cladePrefix = "subclade%u"
end
-- 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)
--for value in string.gmatch( fullOutput , pattern ) do
local value = string.match( fullOutput , pattern )
if value then
local trimmedTree, matches = string.gsub(fullOutput, pattern, "%1".."replacement string")--replaces pattern with capture %1
--output = output .. trimmedTree
--output = output .. "<pre>" .. trimmedTree .. "</pre>"
fullOutput = trimmedTree
else
output = output .. p.errormsg ("Failed to capture subclade with label "..section)
end
end
else
return '<span class="error">No page title found</span>'
end
if output ~= "" then
return frame:preprocess(fullOutput)
else
return '<span class="error">Section for label not found</span>'
end
end
--=============================== extract LABELS or SUBTREES=======================================
p.label = 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']
local wrap = frame.args['wrap']
local output = p._label (frame, page, frame.args[2], frame.args[3], frame.args[4], frame.args[5] )
if wrap then
local label1 = string.lower(frame.args[2])
if wrap ~= "" then label1 = wrap end
output = "{{clade |label1=" .. p.firstToUpper(label1) .. "|1=" .. output .. "}}"
end
return frame:preprocess(output)
end
p._label = function (frame, page, ... )
-- 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 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 and title.exists then
local content = title:getContent()
local targetType = "label%d"
local cladePrefix = "%d"
for k,v in pairs(args) do
local section = mw.text.trim(v)
if string.upper( section) == section then
targetType = "target%u" -- by convention subtrees must be uppercase
cladePrefix = "subclade%u"
end
-- label = [[ name ]] |n= {...}
--local pattern = "label%d=[%s%p]*"..section .. "[%s%p]*%d=(%b{})"
-- the .- skips section tags before clade
--local pattern = "label%d=[%s%p]*"..section .. "[%s%p]*%d=.-(%b{})"
-- this .- skips |sublabel and styling following the label (but can return wrong clade when a subtree)
--local pattern = "label%d=[%s%p]*"..section .. ".-%d=.-(%b{})"
local pattern = targetType.."=[%s%p]*"..section .. "[%s%p]*.-"..cladePrefix.."=.-(%b{})"
-- for subtrees (how to capture right )
--local pattern = "[%u]=[%s%p]*"..section .. ".-%d=.-(%b{})"
local value = string.match( content , pattern )
if value then
-- what if we have something like {FABIDS} "{%u}"
local pattern = "({%u-})"
if string.find(value, pattern ) then -- if a subtree that hasn't been substituted.
--local i,j,target = string.find(value, pattern) -- only one subtree
for target in string.gmatch( value , pattern ) do
local subtree = p._label (frame, page, target)
if subtree then
value = string.gsub(value, target, subtree)
end
--return value
--value = value .. " (subtree needs transcluding)"
end
end
--if (1==1) then return "Captured pattern=" .. (value or "no match") end
section = string.lower(section)
output = output .. value
--output = output .. "{{clade |label1=" .. p.firstToUpper(section) .. "|1=" .. value .. "}}"
else
output = output .. p.errormsg ("Failed to capture subclade with label "..section)
end
end
else
return '<span class="error">No page title found</span>'
end
if output ~= "" then
--return frame:preprocess(output)
return output -- preprocess in entry function
else
return '<span class="error">Section for label not found</span>'
end
end
p.section = function (frame)
-------------------------target page ---- sections
return frame:preprocess(p._section(frame, mw.text.trim(frame.args[1]),frame.args[2],frame.args[3],frame.args[4],frame.args[5]))
end
p._section = function (frame,page,...)
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()
for k,v in pairs(args) do
local section = mw.text.trim(v)
--[[ note: using the non-greedy - in (.-) to allow capture of several sections
this allows internal clade structures to be closed without capturing sisters clades
e.g. see section Tyranni in User:Jts1882/sandbox/test/Passeriformes
]]
local pattern = "<section begin="..section.."[ ]*/>(.-)<section end="..section.."[ ]*/>"
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 == "" then label1 = section end
value = "{{clade |label1=" .. label1 .. "|1=" .. value .. "}}"
end
output = output .. value
end
end
end
else
return '<span class="error">No page title found</span>'
end
if output ~= "" then
--return frame:preprocess(output)
return output -- leave preprocessing for entry function
else
return '<span class="error">Section not found</span>'
end
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)
--[[ note: using the non-greedy - in (.-) to allow capture of several sections
this allows internal clade structures to be closed without capturing sisters clades
e.g. see section Tyranni in User:Jts1882/sandbox/test/Passeriformes
]]
local pattern = "(<section begin="..section.."[ ]*/>)(.-)(<section end="..section.."[ ]*/>)"
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 .. "<pre>" .. trimmedTree .. "</pre>"
fullOutput = trimmedTree
else
output = output .. p.errormsg ("Failed to capture subclade with label "..section)
end
end
else
return '<span class="error">No page title found</span>'
end
if output ~= "" then
--return frame:preprocess(output)
return output -- leave preprocessing for entry function
else
return '<span class="error">Section not found</span>'
end
end
function p.firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
p.errormsg = function (message)
return '<span class="error">' .. message .. '</span>'
end
return p