Jump to content
 







Main menu
   


Navigation  



Main page
Contents
Current events
Random article
About Wikipedia
Contact us
Donate
 




Contribute  



Help
Learn to edit
Community portal
Recent changes
Upload file
 








Search  

































Create account

Log in
 









Create account
 Log in
 




Pages for logged out editors learn more  



Contributions
Talk
 



















Contents

   



(Top)
 


1 Usage  














Module:Clade/transclude






Tiếng Vit

 

Edit links
 









Module
Talk
 

















Read
Edit
View history
 








Tools
   


Actions  



Read
Edit
View history
 




General  



What links here
Related changes
Upload file
Special pages
Permanent link
Page information
Get shortened URL
Download QR code
Wikidata item
 




Print/export  



Download as PDF
Printable version
 
















Appearance
   

 






From Wikipedia, the free encyclopedia
 

< Module:Clade


Module for template {{Clade transclude}} with functions for partial transclusion of cladograms made with the {{Clade}} template.

Usage[edit]

{{#invoke:Clade|main}}

Parameters described at {{Clade transclude}}.

Testcases:

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 "&nbsp;"  -- 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("<small>.-</small>", "")
 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 = "{{clade " .. styleString .. " |label1=" .. p.firstToUpper(label1) .. "|1=" .. modifiedTree .. " }}" -- 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, 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, 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) == section then
    mode        = "subtree"
    targetType  = "target(%u)"               -- targets of form targetX (X=uppercase letter)
    cladePrefix = "subclade(%u)"             -- subclades of form subcladeX (captures X)
     end
        
        --[=[ the pattern to capture is one of two forms: labelN=Name |N={...} 
                                                         targetX=NAME |subcladeX={...} 
                    labelN      =  [[        name        ]]        |N           =    {...}
             or    targetX      =  [[        name        ]]        |subcladeX   =    {...}
        ]=]
        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 index1, index2, selectedTree = string.match( content , pattern )
        -- note index1 and index2 should match (X=X or N=N)

        if selectedTree then 
            --[[ the tree can contain markers for subtrees like {FABIDS} 
                    when the form is |N={FABIDS} we want to substitute the subtree
                    but not when the form is |targetX={FABIDS}
            ]]
            
            local pattern2 = "({%u-})"   -- this captures both |N={FABIDS} and |targetX={FABIDS}
                                         -- 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={bracedMarker} ... |subcladeX=s  then
                    local pattern3 = "target(%u)=[%s]*"..bracedMarker

                    --?? if selectedTree == bracedMarker
           if not string.find(selectedTree, pattern3 ) then
                     
                 local subtree = p._label (frame, content, bracedMarker) 
               if subtree then

                 --[[ method 1: the subtree code is substituted into main tree
                         this substitutes the subtree within the clade structure before processing
                         thus there will be a problem with large trees exceeding the expansion depth
                         however, they can be pruned before processing
                   ]]
--disable method 1                 selectedTree = string.gsub(selectedTree, bracedMarker, subtree, 1)

                 --[[method 2: add the subtree code before the final double brace
                     substitute "|targetX={FABIDS} |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 == bracedMarker then
                     selectedTree = subtree
                 else 
                       selectedTree = selectedTree:sub(1,-3)  -- trim final double brace
                           .. "\n|target" .. X .. "=" .. bracedMarker 
                           .. "\n|subclade" .. X .. "=" .. subtree .. ""
                           .. "\n }}"
                 end 
               end
              end --substitution of subtree
             end
            end

         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 '<span class="error">Section for label not found</span>' 
    end
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, 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) == 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)
  
    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) == section then 
      message = "; subtree may have been substituted, try label"
        end
     output = output .. p.warningMsg ("Failed to capture subclade for exclusion with label "..section..message)
    end



    if output ~= "" then 
  return  output .. '<span class="error">Nothing pruned</span>' 
  --return frame:preprocess(fullOutput)
 else 
  return '<span class="error">Section for label not found</span>' -- shouldn't get here 
    end
end 

--======================================== SECTION ==================================
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,content,...)
 local args = { ... }
 local output = ""

 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
    if pargs['norefs'] or pargs['noref'] then                                                -- strip out references
    --output =   mw.text.killMarkers( output ) 
    if output:find("<ref")  then                       
   output = output:gsub('<ref[%w%p%s]-%/>', "") 
   output = output:gsub("<ref.-<%/ref>", "")                                      -- %C works, %w%p%s%c doesn't
    end
 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 
p.warningMsg = function (message)
 return '<span class="warning" style="color:#ac6600;font-size:larger;">' .. message .. '</span>'
end 
return p

Retrieved from "https://en.wikipedia.org/w/index.php?title=Module:Clade/transclude&oldid=1117548559"

Category: 
Modules in alpha
 



This page was last edited on 22 October 2022, at 09:10 (UTC).

Text is available under the Creative Commons Attribution-ShareAlike License 4.0; additional terms may apply. By using this site, you agree to the Terms of Use and Privacy Policy. Wikipedia® is a registered trademark of the Wikimedia Foundation, Inc., a non-profit organization.



Privacy policy

About Wikipedia

Disclaimers

Contact Wikipedia

Code of Conduct

Developers

Statistics

Cookie statement

Mobile view



Wikimedia Foundation
Powered by MediaWiki