Ir para o conteúdo

Módulo:Diagrama

De Wikiversidade

A documentação para este módulo pode ser criada na página Módulo:Diagrama/doc

local p = {}

function p.diagrama(frame)
    local args = frame:getParent().args
    local treeType = args.type or "vertical"
    local containerClass = (treeType == "horizontal") and "tree-horizontal" or "family-tree"
    
    local nodes = {}
    local linesStr = args.lines or ""
    local groupStr = args.group or ""

    local grupoRelacao = {}
    local ehParceiro = {}

    for k, v in pairs(args) do
        if type(k) == "number" or tonumber(k) then
            local id = tostring(k)
            nodes[id] = { texto = v, filhos = {} }
        end
    end

    for grupo in string.gmatch(groupStr, "([^;]+)") do
        local lider, parceiro = string.match(grupo, "(%d+)%-(%d+)")
        if lider and parceiro then
            grupoRelacao[lider] = parceiro
            ehParceiro[parceiro] = true
        end
    end

    for grupo in string.gmatch(linesStr, "([^;]+)") do
        local paiId, filhosStr = string.match(grupo, "(%d+)%-(.+)")
        if paiId and filhosStr then
            for filhoId in string.gmatch(filhosStr, "([^,]+)") do
                table.insert(nodes[paiId].filhos, filhoId)
                nodes[filhoId].temPai = true
            end
        end
    end

    local function renderizarSpan(id)
        local node = nodes[id]
        if not node then return "" end
        local cor = args["color" .. id] or "inherit"
        local bg = args["bg" .. id] or "var(--background-color-neutral)"
        local radius = args["border" .. id] or ".5em"
        local extraStyle = args["style" .. id] or ""
        
        local spanStyle = string.format(
            "z-index:1; display:flex; align-items:center; padding:.5em; border-radius:%s; background:%s; color:%s; %s",
            radius, bg, cor, extraStyle
        )
        return '<span style="' .. spanStyle .. '">' .. node.texto .. '</span>'
    end

    local function construirHTML(id)
        local node = nodes[id]
        if not node or ehParceiro[id] then return "" end

        local html = "<li>"

        local parceiroId = grupoRelacao[id]
        
        if parceiroId then
            html = html .. '<div class="group-tree">' 
            html = html .. renderizarSpan(id) .. renderizarSpan(parceiroId)
            html = html .. '</div>'
        else
            html = html .. renderizarSpan(id)
        end

        if #node.filhos > 0 then
            html = html .. "<ul>"
            for _, filhoId in ipairs(node.filhos) do
                html = html .. construirHTML(filhoId)
            end
            html = html .. "</ul>"
        end

        html = html .. "</li>"
        return html
    end

    local raizId = "1"
    for id, info in pairs(nodes) do
        if not info.temPai and not ehParceiro[id] then 
            raizId = id 
            break 
        end
    end

    return '<ul class="' .. containerClass .. '">' .. construirHTML(raizId) .. '</ul>'
end

return p