Modul:etymon/tree
Penampilan
- Laman modul ini kekurangan sublaman pendokumenan. Sila cipta laman pendokumenan tersebut.
- Pautan berguna: akar laman • sublaman akar laman • pautan • transklusi • kes ujian • kotak pasir
local export = {}
local html_create = mw.html.create
local max = math.max
function export.render(dataTree, config, keywords, make_link_func)
local function render_recursive(nodeData, isToplevelNode, isUncertain, label, isGroupChild)
local treeWidth, treeHeight = 0, 0
local subtrees = {}
local isGroup = false
if nodeData.children and #nodeData.children > 0 then
local firstChild = nodeData.children[1]
if firstChild and keywords[firstChild.derType] and keywords[firstChild.derType].is_group then
isGroup = true
end
end
for _, child in ipairs(nodeData.children or {}) do
if not (child.derType == "root") then
local subtree, subHeight, subWidth = render_recursive(child, false, child.is_uncertain, child.derType,
isGroup)
table.insert(subtrees, subtree)
treeHeight = max(treeHeight, subHeight)
treeWidth = treeWidth + subWidth
end
end
local linkParams = { lang = nodeData.lang }
if isToplevelNode then
linkParams.alt = "'''" .. (nodeData.alt or nodeData.title) .. "'''"
else
linkParams.term = nodeData.title
linkParams.id = nodeData.id
linkParams.tr = nodeData.tr
linkParams.ts = nodeData.ts
linkParams.alt = nodeData.alt
end
local linkContent = html_create()
linkContent
:tag('span')
:addClass('etyl')
:wikitext(nodeData.lang:getCanonicalName())
:done()
:wikitext(' ')
:tag('span')
:css('display', 'inline-block')
:wikitext(make_link_func(linkParams))
:done()
local termBlock = html_create('div'):addClass("etytree-block"):node(linkContent)
local keywordInfo = keywords[label]
if (label and keywordInfo and keywordInfo.abbrev and not isGroupChild) or isUncertain then
local labelSpan = termBlock:tag('span'):css({
['z-index'] = '1',
position = 'absolute',
transform = 'translate(-50%)',
top = 'calc(100% + 5px)',
left = '50%',
['border-radius'] = '2px',
background = config.colors.CYAN,
['font-size'] = '12px',
height = '10px',
['line-height'] = '10px'
})
if label and keywordInfo and keywordInfo.abbrev and not isGroupChild then
local glossary_title = keywordInfo.glossary and keywordInfo.glossary:gsub("_", " ") or keywordInfo
.abbrev
local abbr = html_create('abbr'):attr('title', glossary_title):css({
color = config.colors.BLACK,
['font-style'] = 'italic',
['text-decoration'] = 'none'
}):wikitext(keywordInfo.abbrev)
if keywordInfo.glossary then
labelSpan:wikitext('[[Lampiran:Glosari#' .. keywordInfo.glossary .. '|'):node(abbr):wikitext(']]')
else
labelSpan:node(abbr)
end
if isUncertain then
labelSpan:tag('abbr'):attr('title', 'uncertain'):css({
position = 'absolute',
top = '50%',
transform = 'translate(0,-48%)',
left = 'calc(100% + 2px)',
['font-size'] = '10px',
['border-radius'] = '2px',
background = config.colors.PINK,
padding = '1px 2px',
['font-weight'] = 'bold',
['text-decoration'] = 'none'
}):wikitext('?')
end
elseif isUncertain then
labelSpan:css('background', 'transparent'):tag('abbr'):attr('title', 'uncertain'):css({
position = 'absolute',
top = '50%',
left = '50%',
transform = 'translate(calc(-50% - 1px),-50%)',
['font-size'] = '10px',
['border-radius'] = '2px',
background = config.colors.PINK,
padding = '1px 2px',
['font-weight'] = 'bold',
['text-decoration'] = 'none'
}):wikitext('?')
end
end
local currentTree = html_create()
if #subtrees == 1 then
currentTree:node(subtrees[1]):tag('span'):css({
position = 'relative',
height = '20px',
['border-right'] = '2px solid ' .. config.colors.GREY
}):done():node(termBlock)
elseif #subtrees >= 2 then
local subtreeContainer = html_create('div'):css({
position = 'relative',
display = 'flex',
['column-gap'] = '0.5em',
['align-items'] = 'end'
})
for i, v in ipairs(subtrees) do
local column = html_create('div'):css({
display = 'flex',
['flex-direction'] = 'column',
['align-items'] = 'center'
}):node(v)
if i == 1 then
column:tag('span'):css({
['align-self'] = 'start',
left = '50%',
width = 'calc(50% + 0.25em)',
height = '10px',
position = 'relative',
['border-bottom'] = '2px solid ' .. config.colors.GREY,
['border-left'] = '2px solid ' .. config.colors.GREY,
['border-bottom-left-radius'] = '4px'
})
elseif i == #subtrees then
column:tag('span'):css({
['align-self'] = 'end',
right = '50%',
width = 'calc(50% + 0.25em)',
height = '10px',
position = 'relative',
['border-bottom'] = '2px solid ' .. config.colors.GREY,
['border-right'] = '2px solid ' .. config.colors.GREY,
['border-bottom-right-radius'] = '4px'
})
else
column:tag('span'):css({
position = 'relative',
height = '10px',
['border-right'] = '2px solid ' .. config.colors.GREY
})
column:tag('span'):css({
position = 'relative',
width = 'calc(100% + 0.5em)',
['border-bottom'] = '2px solid ' .. config.colors.GREY
})
end
subtreeContainer:node(column)
end
local connectingLine = html_create('span'):css({
position = 'relative',
height = '20px',
['border-right'] = '2px solid ' .. config.colors.GREY
})
if isGroup and nodeData.children and #nodeData.children > 0 then
local firstChild = nodeData.children[1]
local groupKeywordInfo = keywords[firstChild.derType]
if groupKeywordInfo and groupKeywordInfo.abbrev then
connectingLine:tag('span'):css({
position = 'absolute',
left = '50%',
top = '50%',
transform = 'translate(-50%, -50%)',
background = config.colors.CYAN,
['font-size'] = '12px',
['border-radius'] = '2px',
['z-index'] = '2',
height = '10px',
['line-height'] = '10px'
}):tag('abbr'):attr('title',
groupKeywordInfo.glossary and groupKeywordInfo.glossary:gsub("_", " ") or groupKeywordInfo
.abbrev):css({
color = config.colors.BLACK,
['font-style'] = 'italic',
['text-decoration'] = 'none'
}):wikitext(groupKeywordInfo.abbrev)
end
end
currentTree:node(subtreeContainer):node(connectingLine):node(termBlock)
else
currentTree:node(termBlock)
treeWidth = treeWidth + 1
end
return currentTree, treeHeight + 1, treeWidth
end
local finalTree, finalHeight, finalWidth = render_recursive(dataTree, true)
local container = html_create('div'):addClass('etytree-body'):node(finalTree)
return tostring(html_create('div'):addClass('etytree NavFrame')
:attr('data-etytree-height', finalHeight)
:attr('data-etytree-width', finalWidth)
:tag('div'):addClass('NavHead')
:css('background', 'var(--wikt-palette-lightergrey)')
:tag('div'):css('width', '25em'):wikitext('Pokok etimologi'):done()
:done()
:tag('div'):addClass('NavContent')
:css('overflow', 'auto')
:node(container)
:done())
end
return export