모듈:CustomTOC

이 모듈에 대한 설명문서는 모듈:CustomTOC/설명문서에서 만들 수 있습니다

local p = {}

-- 1. 앵커용(이동용 ID) 텍스트 추출: 링크/서식 모두 제거하고 순수 텍스트만 남김
local function get_anchor_text(text)
    text = string.gsub(text, "%[%[(.-)%]%]", function(inner)
        local pipe = string.find(inner, "|")
        if pipe then return string.sub(inner, pipe + 1)
        else return inner end
    end)
    text = string.gsub(text, "'''''", "")
    text = string.gsub(text, "'''", "")
    text = string.gsub(text, "''", "")
    return text
end

-- 2. 표시용 텍스트 추출: 위키 링크([[ ]])는 살려두고, 굵게/기울임꼴 서식만 제거
local function get_display_text(text)
    text = string.gsub(text, "'''''", "")
    text = string.gsub(text, "'''", "")
    text = string.gsub(text, "''", "")
    return text
end

function p.show(frame)
    local currentTitle = mw.title.getCurrentTitle()
    if not currentTitle then return "" end
    
    local content = currentTitle:getContent()
    if not content or content == "" then return "" end

    local html = {"<ul>"}
    local current_level = 2
    local has_headings = false
    local counters = {0, 0, 0, 0, 0}

    content = string.gsub(content, "\r", "")

    for line in string.gmatch(content, "[^\n]+") do
        line = string.gsub(line, "^%s*(.-)%s*$", "%1")
        
        local level_str, heading_text = string.match(line, "^(=+)%s*(.-)%s*=+$")
        
        if level_str and heading_text and heading_text ~= "" then
            if not string.match(line, "{{") and not string.match(line, "}}") then
                local level = #level_str
                
                if level >= 2 and level <= 5 then
                    has_headings = true
                    local idx = level - 1
                    
                    counters[idx] = counters[idx] + 1
                    for i = idx + 1, #counters do counters[i] = 0 end
                    
                    local num_str = ""
                    for i = 1, idx do
                        num_str = num_str .. counters[i] .. "."
                    end
                    
                    -- 앵커(문단 이동용)와 디스플레이(화면 표시용)를 분리
                    local anchor_text = get_anchor_text(heading_text)
                    local anchor = string.gsub(anchor_text, " ", "_")
                    local display_text = get_display_text(heading_text)
                    
                    while current_level < level do
                        table.insert(html, "<ul>")
                        current_level = current_level + 1
                    end
                    while current_level > level do
                        table.insert(html, "</ul>")
                        current_level = current_level - 1
                    end
                    
                    table.insert(html, string.format(
                        "<li>[[#%s|'''%s''']] %s</li>",
                        anchor, num_str, display_text
                    ))
                end
            end
        end
    end

    if not has_headings then return "" end

    while current_level > 2 do
        table.insert(html, "</ul>")
        current_level = current_level - 1
    end
    table.insert(html, "</ul>")

    return table.concat(html, "\n")
end

return p