Jump to content
Wikipedia The Free Encyclopedia

Module:Clade/transclude

From Wikipedia, the free encyclopedia
Module documentation[view] [edit] [history] [purge]
This module is rated as alpha. It is ready for limited use and third-party feedback. It may be used on a small number of pages, but should be monitored closely. Suggestions for new features or adjustments to input and output are welcome.


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:

The above documentation is transcluded from Module:Clade/transclude/doc. (edit | history)
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Subpages of this module.

 require('strict')

 localDEBUG=false
 --DEBUG=true -- comment out or not runtime or debug

 localp={}
 localpargs={}

 p.main=function(frame)-- called from template
 pargs=frame:getParent().args
 localoutput
 localselectedTree-- subtree extracted from page content
 localmodifiedTree-- subtree after pruning and grafting

 -- (1) get page
 localpage=pargs['page']orframe.args['page']
 ifnotpagethen
 returnp.errorMsg("Target page not provided")
 end

 -- (2) get content of page (move from _section(), _label, etc)
 localcontent
 localtitle=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
 iftitlethen
 iftitle.existsthen
 content=title:getContent()
 ifnotcontentthenreturnp.errorMsg("Content of "..page.." not loaded.")end
 else
 returnp.errorMsg('Page with title "'..page..'" not found.')
 end
 end
 -- (3) select from content

 localsection=pargs['section']orpargs['section1']orpargs[1]
 ifsectionthen
 selectedTree=p._section(frame,content,section)
 end

 locallabel=pargs['label']orpargs['label1']orpargs[1]
 iflabelthen
 selectedTree=p._label(frame,content,label)
 end
 --TODO does this need to be separate from label?
 localsubtree=pargs['subtree']orpargs['subtree1']orpargs[1]
 ifsubtreethen
 selectedTree=p._label(frame,content,subtree)
 end

 ifnotselectedTreethen-- if none of options retrieve anything
 p.errorMsg("Nothing retrieved for selection option "..(labelorsubtreeorsectionor"none"))
 end

 ifDEBUGthenreturnselectedTreeend--- returns the code captured without processing

 --(4) modify content (excise and replace; prune and graft)
 localexclude=pargs['exclude']orpargs['exclude1']
 ifexcludethen
 ifpargs['exclude']thenpargs['exclude1']=pargs['exclude']end
 ifpargs['replace']thenpargs['replace1']=pargs['replace']end

 modifiedTree=selectedTree

 locali=1
 whilepargs['exclude'..i]do
 localexclude=pargs['exclude'..i]
 localreplace=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
 ifpargs['nohidden']then
 modifiedTree=modifiedTree:gsub("lade hidden","lade")
 end
 ----- suppress authorities (or anything in small tags)
 ifpargs['noauthority']then
 modifiedTree=modifiedTree:gsub("<small>.-</small>","")
 end
 ----- suppress images
 ifpargs['noimages']then
 modifiedTree=modifiedTree:gsub("%[%[File:.-%]%]","")
 end
 ----- wrap in outer clade 
 localwrap=pargs['wrap']
 ifwrapand(labelorsubtree)then
 locallabel1=labelorstring.lower(subtree)
 localstyleString=""
 ifpargs['style']thenstyleString='|style='..pargs['style']end

 ifwrap~=""thenlabel1=wrapend
 output="{{clade "..styleString.." |label1="..p.firstToUpper(label1).."|1="..modifiedTree.." }}"-- last space before double brace important
 else
 output=modifiedTree
 end

 --(6) return final tree
 ifoutputthen
 ifpargs['raw']then
 returnoutput
 else
 returnframe:preprocess(output)
 end
 end

 returnp.errorMsg("No valid option for transclusion")
 end


 --=============================== extract LABELS or SUBTREES=======================================
 p.label=function(frame,page,...)
 localpage=frame.args[1]--"User:Jts1882/sandbox/test/Passeriformes"
 locallabel=frame.args[1]orframe.args['label']orframe.args['label1']
 localwrap=frame.args['wrap']

 localoutput=p._label(frame,page,frame.args[2],frame.args[3],frame.args[4],frame.args[5])
 ifwrapthen
 locallabel1=string.lower(frame.args[2])
 ifwrap~=""thenlabel1=wrapend
 output="{{clade |label1="..p.firstToUpper(label1).."|1="..output.."}}"
 end
 returnframe:preprocess(output)
 end

 p._label=function(frame,content,...)
 --	local page = "User:Jts1882/sandbox/test/Passeriformes"
 --	local label = frame.args[1] or frame.args['label']
 localargs={...}
 localoutput=""

 ifnotargs[1]thenreturnp.errorMsg("Label name not provided")end

 localmode="label"
 localtargetType="label(%d)"-- standard label of form |labelN= (captures N)
 localcladePrefix="(%d)"-- standard node of form |N= (captures N)
 fork,vinpairs(args)do
 localsection=mw.text.trim(v)
 ifstring.upper(section)==sectionthen
 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 = {...}
  ]=]
 localpattern=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)

 localindex1,index2,selectedTree=string.match(content,pattern)
 -- note index1 and index2 should match (X=X or N=N)

 ifselectedTreethen
 --[[ 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}
  ]]

 localpattern2="({%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

 ifstring.find(selectedTree,pattern2)then-- if a subtree that hasn't been substituted.
 --local i,j,target = string.find(value, pattern2) -- only one subtree
 locali=0
 forbracedMarkerinstring.gmatch(selectedTree,pattern2)do
 i=i+1

 -- bracedMarker is either a marker in the tree or part of following
 -- targetX={bracedMarker} ... |subcladeX=s then
 localpattern3="target(%u)=[%s]*"..bracedMarker

 --?? if selectedTree == bracedMarker
 ifnotstring.find(selectedTree,pattern3)then

 localsubtree=p._label(frame,content,bracedMarker)
 ifsubtreethen

 --[[ 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
 		 	 	 ]]
 locali,j,X=string.find(content,pattern3)

 ifselectedTree==bracedMarkerthen
 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

 ifoutput~=""then
 returnoutput-- 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,...)
 localpage=frame.args[1]--"User:Jts1882/sandbox/test/Passeriformes"
 locallabel=frame.args[1]orframe.args['label']orframe.args['label1']
 -- page , target tree, subtrees to exclude ...



 -- page, include clade, multiple clades to exclude |
 returnp._xlabel(frame,page,frame.args[2],frame.args[3],frame.args[4],frame.args[5])



 end
 p._xlabel=function(frame,targetTree,exclude,replace)


 localfullOutput=targetTree
 --local fullOutput = p._section(frame, page, target) 

 localoutput=targetTree-- return unmodified tree if nothing happens
 localsection=exclude

 localtargetType="label%d"
 localcladePrefix="%d"
 ifstring.upper(section)==sectionthen
 targetType="target%u"-- by convention subtrees must be uppercase
 cladePrefix="subclade%u"
 end

 -- label = [[ name ]] |n= {...}
 localpattern="("..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)

 localvalue=string.match(fullOutput,pattern)
 ifvaluethen
 localtrimmedTree,matches=string.gsub(fullOutput,pattern,"%1"..replace)--replaces pattern with capture %1
 returntrimmedTree
 else
 localmessage=""
 ifstring.upper(section)==sectionthen
 message="; subtree may have been substituted, try label"
 end
 output=output..p.warningMsg("Failed to capture subclade for exclusion with label "..section..message)
 end



 ifoutput~=""then
 returnoutput..'<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
 returnframe: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,...)
 localargs={...}
 localoutput=""

 fork,vinpairs(args)do
 localsection=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
 		]]
 localpattern="<section begin="..section.."[ ]*/>(.-)<section end="..section.."[ ]*/>"

 forvalueinstring.gmatch(content,pattern)do
 ifvaluethen
 ifframe.args.wraporframe:getParent().args.wrapthen
 locallabel1=frame.args.wraporframe:getParent().args.wrap
 iflabel1==""thenlabel1=sectionend
 value="{{clade |label1="..label1.."|1="..value.."}}"
 end
 output=output..value
 end

 end
 end
 ifpargs['norefs']orpargs['noref']then-- strip out references
 --output = mw.text.killMarkers( output ) 
 ifoutput: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

 ifoutput~=""then
 --return frame:preprocess(output)
 returnoutput-- leave preprocessing for entry function
 else
 return'<span class="error">Section not found</span>'
 end

 end

 p.xsection=function(frame)
 localpage=frame.args[1]--"User:Jts1882/sandbox/test/Passeriformes"
 locallabel=frame.args[1]orframe.args['label']orframe.args['label1']
 -- page , target tree, sections to exclude ...	
 returnframe:preprocess(p._xsection(frame,page,frame.args[2],frame.args[3],frame.args[4],frame.args[5]))
 end

 p._xsection=function(frame,page,target,...)
 localargs={...}
 localoutput=""
 localtitle=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




 iftitleandtitle.existsthen
 localcontent=title:getContent()
 localfullOutput=p._section(frame,page,target)
 output=fullOutput


 fork,vinpairs(args)do
 localsection=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
 			]]
 localpattern="(<section begin="..section.."[ ]*/>)(.-)(<section end="..section.."[ ]*/>)"

 localvalue=string.match(fullOutput,pattern)


 ifvaluethen
 localtrimmedTree,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

 ifoutput~=""then
 --return frame:preprocess(output)
 returnoutput-- leave preprocessing for entry function
 else
 return'<span class="error">Section not found</span>'
 end

 end

 functionp.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
 returnp

AltStyle によって変換されたページ (->オリジナル) /