Module:Haplogroup
Module used at Wikidata:WikiProject Haplogroups. A derivative version of Template:Tree.
Tree structure is generated by tracking "followed by (P156)" from the first item. By setting direction = parent
, tracking is done through "follows (P155)" toward ancestral direction.
If item page has link to Wikipedia (of your setting language), Wikimedia Commons, or haplogroup.org, it is shown next to each haplogroup name. (Do not use haplogroup.org as source but use it to find original sources.)
If there are other data (for example, "date of birth (P569)", "place of birth (P19)", or "locator map image (P242)"), it is shown by clicking [Show detail] button at the top-left of the tree.
Example
edit- Input
{{ #invoke:Haplogroup | main | firstItemId = Q3491260| maxdepth = 10 | highlight = Q1584156}}
- Output
- R0 (enwiki, commons, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- R0a'b (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- R0a (haplogroup.org)
- R0b (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- HV (enwiki, commons, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H (enwiki, commons, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H1 (haplogroup.org)
- H2 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H2a (haplogroup.org)
- H2a2 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H2a2a (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H2a2a1 (haplogroup.org) rCRSReference tree: http://www.phylotree.org/tree/R0.htm
Full DNA sequence: NC_012920
Possessor: revised Cambridge Reference Sequence, Cambridge Reference Sequence
- H2a2a1 (haplogroup.org) rCRS
- H2a2a (haplogroup.org)
- H2a2 (haplogroup.org)
- H2a (haplogroup.org)
- H5'36 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H5 (enwiki, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- H5 (enwiki, haplogroup.org)
- HV0 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- HV0a (haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- V (enwiki, commons, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- V (enwiki, commons, haplogroup.org)
- HV0a (haplogroup.org)
- H (enwiki, commons, haplogroup.org)
- R0a'b (haplogroup.org)
- Input
{{ #invoke:Haplogroup | main | firstItemId = Q3491260| maxdepth = 10 | highlight = Q45070466| direction = parent }}
- Output
- mitochondrial Eve (enwiki, commons)
- L1'2'3'4'5'6 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/L3.htm
- L2'3'4'5'6 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/L3.htm
- L2'3'4'6 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/L3.htm
- L3'4'6 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/L3.htm
- L3'4 (haplogroup.org)Reference tree: http://www.phylotree.org/tree/L3.htm
- L3 (enwiki, commons, haplogroup.org)
- N (enwiki, commons, haplogroup.org)
- R (enwiki, commons, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R.htm
- R0 (enwiki, commons, haplogroup.org)Reference tree: http://www.phylotree.org/tree/R0.htm
- R0 (enwiki, commons, haplogroup.org)
- R (enwiki, commons, haplogroup.org)
- N (enwiki, commons, haplogroup.org)
- L3 (enwiki, commons, haplogroup.org)
- L3'4 (haplogroup.org)
- L3'4'6 (haplogroup.org)
- L2'3'4'6 (haplogroup.org)
- L2'3'4'5'6 (haplogroup.org)
- L1'2'3'4'5'6 (haplogroup.org)
See also
editTemplate:Tree, original of this module.
Code
-- This is derivative version of [[Module:Tree]]. See https://www.wikidata.org/wiki/Template:Tree
--
-- Usage example
--
-- {{#invoke:Haplogroup|main|firstItemId= Q221674|maxdepth=25}}
--
-- firstItemId: First item ID. This item become the root of the tree.
-- maxdepth: Maximum depth of the tree.
local p = {}
datas = {}
-- These setdata() and getdata() functions are used to access (read and write) to "datas" table
function p.setdata(n, key, val)
if datas[n] == nil then
datas[n] = {}
end
datas[n][key] = val
end
function p.getdata(n, key, defval)
if datas[n] == nil or datas[n][key] == nil then
return defval
else
return datas[n][key]
end
end
function p.children(itemId, property, direction, maxdepth, lang1, lang2 )
--------------------------------------------------------------------------------
-- children function which listing all childrens that certain item has.
-- Not listing grand childrens, or grand-grand childrens. Listing only childrens.
-- Final returning value "childrens" is like {Q123123, Q3984198237, Q1874138746}
--------------------------------------------------------------------------------
local childrens = {}
local entity = mw.wikibase.getEntity( itemId )
local claims = nil
local x = 1
local tmpValue = {}
---------------------------------------------------------------
-- Start collecting data from the retrieved entity, and save that into the datas[] table.
-- Because getEntity() function is EXPENSIVE, so here, collecting all data at once.
-- https://en.wikipedia.org/wiki/WP:EXPENSIVE
-- https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua#mw.wikibase.getEntity
----------------------------------------------------------------
local globalSiteId_1 = lang1 .. 'wiki'
local globalSiteId_2
if lang2 and lang2 ~= '' then
globalSiteId_2 = lang2 .. 'wiki'
else
globalSiteId_2 = nil
end
p.setdata(itemId, "sitelink_1", entity:getSitelink( globalSiteId_1 ))
p.setdata(itemId, "label_1", entity:getLabelWithLang( lang1 ))
local claimShort = entity['claims']['P1813'] -- variable for P1813 (Short name)
if claimShort and claimShort ~= '' then
p.setdata(itemId, "short", claimShort[1].mainsnak.datavalue.value.text) --
end
local claimDate = entity['claims']['P569'] -- variable for P569 (Date of birth)
if claimDate and claimDate ~= '' then
p.setdata(itemId, "date", claimDate[1].mainsnak.datavalue.value) --
end
local claimsPlace = entity['claims']['P19'] -- variable for P19 (Place of birth)
local tmpPlcae = nil
if claimsPlace and claimsPlace ~= '' then
for _,claim in pairs( claimsPlace ) do --Various place can be registered in this property. So marging these all places.
if tmpPlcae and tmpPlcae ~= '' then
tmpPlcae = tmpPlcae .. ', ' .. mw.getCurrentFrame():expandTemplate{ title = 'LinkedLabel', args = { claim.mainsnak.datavalue.value.id } }
else
tmpPlcae = mw.getCurrentFrame():expandTemplate{ title = 'LinkedLabel', args = { claim.mainsnak.datavalue.value.id } }
end
end
p.setdata(itemId, "place", tmpPlcae)
end
local claimsPossessor = entity['claims']['P127'] -- variable for P127 (Owned by)
local tmpPossessor = nil
if claimsPossessor and claimsPossessor ~= '' then
for _,claim in pairs( claimsPossessor ) do --Various place can be registered in this property. So marging these all places.
if tmpPossessor and tmpPossessor ~= '' then
tmpPossessor = tmpPossessor .. ', ' .. mw.getCurrentFrame():expandTemplate{ title = 'LinkedLabel', args = { claim.mainsnak.datavalue.value.id } }
else
tmpPossessor = mw.getCurrentFrame():expandTemplate{ title = 'LinkedLabel', args = { claim.mainsnak.datavalue.value.id } }
end
end
p.setdata(itemId, "possessor", tmpPossessor)
end
local claimsRefSeq = entity['claims']['P2249'] -- variable for P2249 (Refseq Genome ID)
local tmpRefSeq = nil
if claimsRefSeq and claimsRefSeq ~= '' then
for _,claim in pairs( claimsRefSeq ) do --Various place can be registered in this property. So marging these all places.
if tmpRefSeq and tmpRefSeq ~= '' then
tmpRefSeq = tmpRefSeq .. ', ' .. '[https://www.ncbi.nlm.nih.gov/nuccore/' .. claim.mainsnak.datavalue.value .. '?report=fasta ' .. claim.mainsnak.datavalue.value .. ']'
else
tmpRefSeq = '[https://www.ncbi.nlm.nih.gov/nuccore/' .. claim.mainsnak.datavalue.value .. '?report=fasta ' .. claim.mainsnak.datavalue.value .. ']'
end
tmpRefSeq = '<span class="plainlinks">' .. tmpRefSeq .. '</span>'
end
p.setdata(itemId, "refseq", tmpRefSeq)
end
local claimMapIamge = entity['claims']['P242'] -- variable for P242 (locator map image)
if claimMapIamge and claimMapIamge ~= '' then
p.setdata(itemId, "mapimage", claimMapIamge[1].mainsnak.datavalue.value) --
end
--{{#invoke: Wikidata|Dump|claims|P155|1|references|1|snaks|P854|1|datavalue|value}}
local claimsPhyloTreeURL = entity['claims']['P155'] -- variable for phylotree.org URL taken from reference data in P155 (follows)
local tmpPhyloTreeURL
if claimsPhyloTreeURL then
for _,claim in pairs( claimsPhyloTreeURL ) do --Various website can be registered in this property. So picking-up only haplogroup.org website.
for _,reference in pairs( claim.references ) do
if reference.snaks['P854'] then
tmpPhyloTreeURL = reference.snaks['P854'][1].datavalue.value
if string.find( tmpPhyloTreeURL, 'phylotree.org') then
p.setdata(itemId, "phylotree.org", tmpPhyloTreeURL)
end
end
end
end
end
local claimsDescribedURL = entity['claims']['P973'] -- variable for haplogroup.org URL in P973 (described at URL)
local tmpDescribedURL
if claimsDescribedURL then
for _,claim in pairs( claimsDescribedURL ) do --Various website can be registered in this property. So picking-up only haplogroup.org website.
tmpDescribedURL = claim.mainsnak.datavalue.value
if string.find( tmpDescribedURL, 'haplogroup.org') then
p.setdata(itemId, "haplogroup.org", tmpDescribedURL)
end
if string.find( tmpDescribedURL, 'yfull.com') then
p.setdata(itemId, "yfull.com", tmpDescribedURL)
end
end
end
local claimCommons = entity['sitelinks'] -- variable for Wikimedia Commons
if claimCommons and claimCommons ~= '' then
if claimCommons.commonswiki and claimCommons.commonswiki ~= '' then
p.setdata(itemId, "commons", claimCommons['commonswiki'].title) --
end
end
if lang2 and lang2 ~= '' then
p.setdata(itemId, "sitelink_2", entity:getSitelink( globalSiteId_2 ))
p.setdata(itemId, "label_2", entity:getLabelWithLang( lang2 ))
end
---------------------------------------------------------------
-- End collecting data
---------------------------------------------------------------
---------------------------------------------------------------
-- Start collecting childrens
---------------------------------------------------------------
claims = entity['claims'][property]
if not claims then
return {}
end
for _,claim in pairs( claims ) do
local value = claim.mainsnak.datavalue.value
local nextitem = 'Q' .. value['numeric-id']
childrens[x] = nextitem
x = x + 1
end
return childrens
---------------------------------------------------------------
-- End collecting childrens
---------------------------------------------------------------
end
-- generator, see http://lua-users.org/wiki/LuaCoroutinesVersusPythonGenerators for lua doc
-- definition a function that when called several times will generate a sequence of strings
-- gensymbols = create_gensymbols("ABC")
-- gensymbols() == "A"
-- gensymbols() == "B" g
-- gensymbols() == "C"
-- gensymbols() == "AA" '
-- gensymbols() == "BABBA"
-- ...
function p.gensymbols(chars)
local i = 0
local charset = chars
local generator = function ()
local symbol = ""
local rest
rest = i
repeat
local j
j = rest % string.len(charset)
rest = math.floor(rest / string.len(charset))
symbol = symbol .. string.sub(charset, j+1, j+1)
until rest <= 0
i = i + 1
return symbol
end
return generator
end
-------------------------------------------------------------------------------------------
-- Start definition of itemOutput function which returns text like '[[' .. link .. '|' .. label .. ']]'
-------------------------------------------------------------------------------------------
function p.itemOutput(item, lang1, lang2, datas, setdata, getdata, highlightItemID)
local globalSiteId_1 = lang1 .. 'wiki'
local globalSiteId_2 = lang2 .. 'wiki'
local highlightItem = highlightItemID
local currentLabel
local currentLabel_temp
local wpLinkText = nil
local commonsLinkText = nil
local mapImageName = nil
local currentPage = tostring(mw.title.getCurrentTitle().text)
local content
currentLabel = p.getdata(item, "short", nil )
if currentLabel == nil or currentLabel == '' then
currentLabel = p.getdata(item, "label_1", nil )
if currentLabel == nil or currentLabel == '' then
currentLabel = p.getdata(item, "sitelink_1", nil )
if currentLabel == nil or currentLabel == '' then
currentLabel = p.getdata(item, "label_2", nil )
if currentLabel == nil or currentLabel == '' then
currentLabel = p.getdata(item, "sitelink_2", nil )
if currentLabel == nil or currentLabel == '' then
currentLabel = item
end
end
end
end
end
content = '[[' .. item .. '|' .. currentLabel .. ']]'
wpLinkText = p.getdata(item, "sitelink_1", nil )
commonsLinkText = p.getdata(item, "commons", nil )
haplogroupDotOrgText = p.getdata(item, "haplogroup.org", nil )
phylotreeDotOrgText = p.getdata(item, "phylotree.org", nil )
yfullDotComText = p.getdata(item, "yfull.com", nil )
dateText = p.getdata(item, "date", nil )
placeText = p.getdata(item, "place", nil )
possessorText = p.getdata(item, "possessor", nil )
refseqText = p.getdata(item, "refseq", nil )
mapImageName = p.getdata(item, "mapimage", nil )
if wpLinkText or commonsLinkText or haplogroupDotOrgText or yfullDotComText then
content = content .. ' ('
end
--content = content .. '[[Talk:'.. item .. '|talk]]'
if wpLinkText and wpLinkText ~= '' then
--content = content .. ', '
if highlightItem == item then
content = content .. '[[:w:'.. lang1 ..':' .. wpLinkText .. '|' .. lang1 ..'wiki]]'
else
content = content .. '<span style="background-color: yellow;">[[:w:'.. lang1 ..':' .. wpLinkText .. '|' .. lang1 ..'wiki]]</span>'
end
end
if commonsLinkText and commonsLinkText ~= '' then
if wpLinkText then
content = content .. ', '
end
if highlightItem == item then
content = content .. '[[:commons:' .. commonsLinkText .. '|commons]]'
else
content = content .. '<span style="background-color: #dcdcf5;">[[:commons:' .. commonsLinkText .. '|commons]]</span>'
end
end
if haplogroupDotOrgText and haplogroupDotOrgText ~= '' then
if wpLinkText or commonsLinkText then
content = content .. ', '
end
content = content .. '<span class="plainlinks">[' .. haplogroupDotOrgText .. ' haplogroup.org]</span>'
--content = content .. haplogroupDotOrgText -- When checking bare URL
end
if yfullDotComText and yfullDotComText ~= '' then
if wpLinkText or commonsLinkText or haplogroupDotOrgText then
content = content .. ', '
end
content = content .. '<span class="plainlinks">[' .. yfullDotComText .. ' yfull.com]</span>'
--content = content .. yfullDotComText -- When checking bare URL
end
if wpLinkText or commonsLinkText or haplogroupDotOrgText or yfullDotComText then
content = content .. ')'
end
--red #FFDFDF|#FF9797
--blue '#D7D1F8', '#A095EE'
if highlightItem == item then
--'<span style="font-weight: bold;">' .. .. '</span>'
content = '<span style="font-weight: bold;">' .. mw.getCurrentFrame():expandTemplate{ title = 'Font & border color', args = {'black','#D7D1F8', '#A095EE', content} } .. '</span>'
end
if item == 'Q46999198' then --Q46999198 is 'Haplogroup H2a2a1' which is haplogroup for CRS (Cambridge Reference Sequence)
content = content .. ' ' .. mw.getCurrentFrame():expandTemplate{ title = 'Font & border color', args = {'black','#FFEAB7', '#FFC848', '[[:w:en:Cambridge Reference Sequence|rCRS]]'} }
end
if phylotreeDotOrgText or dateText or placeText or possessorText or refseqText or mapImageName then
content = content .. '<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-1" style="padding:0px; border:0px;">'
if phylotreeDotOrgText and phylotreeDotOrgText ~= '' then
content = content .. 'Reference tree: ' .. '<span class="plainlinks">' .. phylotreeDotOrgText .. '</span>'
end
if dateText and dateText ~= '' then
if phylotreeDotOrgText then
content = content .. '<br/>'
end
content = content .. 'Age: ' .. dateText.time
--mw.logObject(dateText)
end
if placeText and placeText ~= '' then
if phylotreeDotOrgText or dateText then
content = content .. '<br/>'
end
content = content .. 'Origin: ' .. placeText
end
if refseqText and refseqText ~= '' then
if phylotreeDotOrgText or dateText or placeText then
content = content .. '<br/>'
end
content = content .. 'Full DNA sequence: ' .. refseqText
end
if possessorText and possessorText ~= '' then
if phylotreeDotOrgText or dateText or placeText or refseqText then
content = content .. '<br/>'
end
content = content .. 'Possessor: ' .. possessorText
end
if mapImageName and mapImageName ~= '' then
if phylotreeDotOrgText or dateText or placeText or refseqText or possessorText then
content = content .. '<br/>'
end
content = content .. '[[File:' .. mapImageName .. '|x150px]]'
end
content = content .. '</div>'
end
--if mapImageName and mapImageName ~= '' then
--content = content .. '<div class="mw-customtoggle-' .. item .. '" style="float: left;">▼</div>'
--content = content .. '<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-' .. item .. '" style="padding:0px; border:0px;">'
-- content = content .. '[[File:' .. mapImageName .. '|x150px]]'
--content = content .. '</div>'
--end
return content
end
-------------------------------------------------------------------------------------------
-- End definition of itemOutput function which returns text like '[[' .. link .. '|' .. label .. ']]'
-------------------------------------------------------------------------------------------
function p.outputTree( firstItemId, property, direction, maxdepth, lang1, lang2, highlightItemID)
-------------------------------------------------------------------------------------------
-- Start preparation of functions
-------------------------------------------------------------------------------------------
----- topological sort and meta data of the DAG ( https://en.wikipedia.org/wiki/Topological_sorting )
--This firstPass() function is called only once, at first
local function firstPass( firstItemId, item_repr )
--mw.log("firstItemId is: ")
--mw.logObject(firstItemId)
--mw.log("")
--mw.log("")
local content = p.itemOutput(firstItemId, lang1, lang2, datas, setdata, getdata, highlightItemID)
local opened = 1 -- This means the downstream branch of the item is under processing.
-- If encountering opened item through the processing, it indicates that infinite loop exists.
local closed = 2 -- This means the processing of all downstream branches of the item reached to its end.
-- The downest item is showed with " ? " in tree.
local incomplete = 3 -- This means the processing of all downstream branches of the item reached to its end.
-- If more downstream branches exist but not processed (because of limitation from maxdepth),
-- then the downest item showed with "…" in tree.
local marks = {} --opened(1) or closed(2) or incomplete(3) for each QID (e.g. marks[Q12234234] -> closed)
--local datas = {} --datas[QID]["nparents"], datas[QID]["symbol"], datas[QID]["looped"], datas[QID]["rank"], datas[QID]["status"]
--datas[QID]["nparents"] represents "number of parents" of certain item. This is normally 1.
--If this is 2 or more, it means that the exact same item appears several times in defferent branches of the tree repeatedly.
local childrens = {} -- for example, childrens[Q1234] contains data like {Q123123, Q3984198237, Q1874138746}, three childrens of Q1234
--while there are unmarked nodes do
-- select an unmarked node n
-- visit(n)
--function visit(node n)
-- if n has a temporary mark then stop (not a DAG)
-- if n is not marked (i.e. has not been visited yet) then
-- mark n temporarily
-- for each node m with an edge from n to m do
-- visit(m)
-- mark n permanently
-- add n to head of L
-- this function
-- * visits and builds the tree, DAG or graph,
-- * in the same pass, computes a topological ordering for the DAG
-- * annotates the nodes with informations
function visit(n, depth, rank)
--mw.log("depth is " .. depth .. ">=" .. "maxdepth is " .. maxdepth)
--mw.log(n .. ": mark is " .. tostring(marks[n]))
if marks[n] == opened then
p.setdata(n, "status", "loop")
p.setdata(n, "rank", rank)
return rank
elseif marks[n] ~= closed then
marks[n] = opened
childrens[n] = p.children( n, property, direction, maxdepth, lang1, lang2)
for _, node in ipairs(childrens[n]) do
p.setdata(node, "nparents",
p.getdata(node, "nparents", 0) + 1
)
if depth <= maxdepth then
rank = visit(node, depth + 1, rank + 1)
end
end
if depth <= maxdepth then
if p.getdata(n, "status", "complete") ~= "loop" then
p.setdata(n, "status", "complete")
end
marks[n] = closed
else
p.setdata(n, "status", "incomplete")
marks[n] = incomplete
end
p.setdata(n, "rank", rank)
end
return rank + 1
end
p.setdata(firstItemId, "nparents", 0)
visit(firstItemId, 1, 0)
return datas, childrens
end
local langobj = mw.language.new(lang1)
-- link inside tree
local function formatSymbol(prefix)
return '<span class="Unicode"><small>(' .. prefix .. ")</small></span>"
end
local function genAnchor(id)
return '<span id="' .. firstItemId .. id .. '"></span>'
end
local function anchorLink(id, content)
return "[[#" .. firstItemId .. id .. "|" .. content .. "]]"
end
local function fmtTreeLinks(content)
return mw.text.tag("sup", {}, content)
end
local function renderTree( itemId, datas, children, alreadyOuted, gs )
local content = p.itemOutput( itemId, lang1, lang2, datas, setdata, getdata, highlightItemID)
local state
if datas[itemId]["status"] ~= nil then
state = datas[itemId]["status"]
end
--mw.log(itemId .. ": status is " .. state )
if datas[itemId] ["nparents"] > 1 and datas[itemId]["symbol"] == nil then
p.setdata(itemId, "symbol", gs() )
end
-- prevent infinite loops in non DAGs
if state == "loop" then
if datas[itemId]["looped"] == nil then
datas[itemId]["looped"] = "treated"
content = fmtTreeLinks(" ∞") .. " " .. content .. genAnchor(itemId)
else
return content .. fmtTreeLinks("∞" .. " ↑ " .. anchorLink(itemId, formatSymbol( datas[itemId]["symbol"] )))
end
elseif state == "incomplete" or state == "unvisited" then
content = content .. " " .. fmtTreeLinks("…")
return content
end
-- has no chilren ? display as leaf
if children[itemId] ~= nil and table.getn(children[itemId]) == 0 then
--return " " .. content .. " ? " -- would be great to use "?b, but font problem
return " " .. content
end
datas[itemId] ["nparents"] = datas[itemId]["nparents"] - 1
local parts = {}
-- sort children topologycally
if alreadyOuted[itemId] == nil then
local langobj = mw.language.new(lang1)
local prefix = " "
if datas[itemId] ["nparents"] > 0 then
local arrow = langobj:getArrow()
prefix = fmtTreeLinks(genAnchor(itemId) .. " " .. arrow .. " " .. formatSymbol(datas[itemId]["symbol"]))
end
order = children[itemId]
table.sort(order, function (a, b) return datas[a]["rank"] < datas[b]["rank"] end )
for i, childId in ipairs(order) do
table.insert( parts, renderTree( childId, datas, children, alreadyOuted, gs ) )
end
if direction == "child" or direction == "brother" then
local l = table.maxn( parts )
for i = 1,(l - 1) do
parts[i] = mw.text.tag( 'li', {}, parts[i] )
end
parts[l] = mw.text.tag( 'li', { class = 'lastline' }, parts[l] )
alreadyOuted[itemId] = prefix .. " " .. content .. mw.text.tag( 'ul', {}, table.concat( parts ) )
elseif direction == "parent" then
local texttmp
local matchCount = 0
--mw.log("parts is: ")
--mw.logObject(parts)
texttmp = mw.text.tag( 'ul', {}, mw.text.tag( 'li', { class = 'lastline' }, content ) )
alreadyOuted[itemId], matchCount = string.gsub(table.concat( parts ), "(</li></ul>)", texttmp .. "%1", 1)
--mw.log('matchCount is:')
--mw.log(matchCount)
if matchCount == 0 then
alreadyOuted[itemId] = prefix .. " " .. string.gsub(table.concat( parts ), "$", texttmp, 1)
end
alreadyOuted[itemId] = prefix .. " " .. alreadyOuted[itemId]
--mw.log("alreadyOuted[itemId] is: ")
--mw.logObject(alreadyOuted[itemId])
end
end
if datas[itemId] ["nparents"] <= 0 or state == "loop" then
return alreadyOuted[itemId]
else
return content .. " " .. fmtTreeLinks(anchorLink(itemId, formatSymbol(datas[itemId]["symbol"])) .. " " .. langobj:getArrow(forward))
end
end
-------------------------------------------------------------------------------------------
-- End preparation of functions
-------------------------------------------------------------------------------------------
-------------------------
-- Start creating tree --
-------------------------
-- gen = p.gensymbols("??")
-- gen = p.gensymbols("12")
-- gen = p.gensymbols("★☆?")
-- These symbols are used as link button for "jumping" from certain branch to other branch.
-- "jumping" functionality is used when same item appears multipul times in one tree.
local gen = p.gensymbols("@*#")
local children
datas, children = firstPass( firstItemId, gen)
-- alreadyOuted is the table which contains html code for each QID.
-- For example, like this... alreadyOuted[Q1234] = "<li>[[Human body]]</li>"
-- Actually items which located more nearer to the root (to say, FirstItemId) contain html codes of their branchs within it.
-- For example, like this... alreadyOuted[Q1234] = "<li>[[Human body]] <ul><li>[[Nervous system]]</li></ul></li>"
-- This is done by recursive calling of renderTree() function inside the renderTree() function.
local alreadyOuted = {}
rendering = {} -- What does this do?
return renderTree( firstItemId, datas, children, alreadyOuted, gen)
-----------------------
-- End creating tree --
-----------------------
end
function p.main( frame )
------------------------------------
-- Start adjustments of arguments
------------------------------------
local maxdepth
--local lang1 = mw.language.getContentLanguage().code
local lang1 = mw.getCurrentFrame():preprocess("{{int:lang}}")
local lang2 = 'en'
local firstItemId = frame.args.firstItemId
local direction = frame.args.direction -- tree searching direction. "child", "parent" or "brother
local highlightItemID = frame.args.highlight
local maxdepth = frame.args.maxdepth
if tonumber(firstItemId) then --legacy format
firstItemId = 'Q'.. tostring(firstItemId)
end
if direction == nil or direction =='' then --Default direction is child
direction = 'child'
end
if tonumber(highlightItemID) then --legacy format
highlightItemID = 'Q'.. tostring(highlightItemID)
end
if maxdepth and maxdepth ~= '' then
maxdepth = tonumber( maxdepth )
else
maxdepth = 25
end
----------------------------------
-- End adjustments of arguments
----------------------------------
-------------------------
-- Start creating tree --
-------------------------
local content = ''
local property -- property used to search items. For example "P156" (followed by) or "P155" (follows)
--------------------------------------------------
--Creating tree for child side (downstream side)
--------------------------------------------------
if direction == 'child' then
property = "P156"
elseif direction == 'parent' then
property = "P155"
end
content = mw.text.tag( 'li', { class = 'lastline' }, p.outputTree( firstItemId, property, direction, maxdepth, lang1, lang2, highlightItemID ) )
content = '<div class="mw-customtoggle-1" style="float: left;"><span style="color:#36b;">[Show detail]</span></div><br/><br/>' .. content
--mw.log("content is: ")
--mw.logObject(content)
--------------------------------------------------
-- Final formatting
--------------------------------------------------
res = mw.text.tag( 'div', { class = 'treeview' }, mw.text.tag( 'ul', {}, content ) )
-----------------------
-- End creating tree --
-----------------------
return res
end
return p