Модуль:Таблица

Материал из ЧТМ
Перейти к навигации Перейти к поиску

local p = {}

-- Парсинг ячейки для выявления префиксов подсветки
local function parseCell(cellStr)
    if not cellStr then return { text = "" } end
    cellStr = mw.text.trim(cellStr)

    -- Фирменная палитра ЧТМ из Config.styles
    local colors = {
        gold          = 'background-color:gold;',
        silver        = 'background-color:silver;',
        bronze        = 'background-color:rgb(204,153,102);',
        wood          = 'background-color:darkkhaki;',
        lightgreen    = 'background-color:lightgreen;',
        palegoldenrod = 'background-color:palegoldenrod;',
        lightyellow   = 'background-color:lightyellow;',
        lightsalmon   = 'background-color:lightsalmon;',
        group         = 'background-color:silver;',
        gainsboro     = 'background-color:Gainsboro;',
        peachpuff     = 'background-color:PeachPuff;',
    }

    -- 1. Проверка на стандартные префиксы вида "gold:Текст"
    local prefix, content = string.match(cellStr, "^([%a_]+):(.*)$")
    if prefix and colors[prefix] then
        return {
            text = content,
            style = colors[prefix] .. 'text-align:center; white-space:nowrap;'
        }
    end

    -- 2. Возможность передать произвольный цвет через bg=#hex:Текст
    local customBg, content2 = string.match(cellStr, "^bg=([#%a%d%,%s%(%)]+):(.*)$")
    if customBg and content2 then
        return {
            text = content2,
            style = 'background-color:' .. customBg .. '; text-align:center; white-space:nowrap;'
        }
    end

    -- По умолчанию: выравнивание по центру, запрет переноса строк
    return {
        text = cellStr,
        style = 'text-align:center; white-space:nowrap;'
    }
end

function p.render(frame)
    local args = frame:getParent().args
    if not args[1] and not args.headers and not args['шапка'] then
        args = frame.args
    end

    local headersStr = args.headers or args['шапка'] or ""
    local separator = args.sep or args['разделитель'] or ";"

    -- Формируем массив заголовков
    local headers = mw.text.split(headersStr, separator)
    for i, h in ipairs(headers) do
        headers[i] = mw.text.trim(h)
    end

    -- Системные настройки стилей
    local classes = 'article-table sortable ts-stickytableheader'
    local defaultHeaderStyle = 'background-color:#e0f0ff;'
    local wikiTemplates = '<templatestyles src="Шаблон:Плавающая_шапка_таблицы/styles.css" />\n'

    local html = mw.html.create('table')
        :addClass(classes)
        :attr('border', "1")
        :attr('cellspacing', "1")
        :attr('cellpadding', "1")

    -- Создаем строку заголовков
    local headerRow = html:tag('tr')
    for _, colText in ipairs(headers) do
        headerRow:tag('th')
            :cssText(defaultHeaderStyle)
            :wikitext(colText)
    end

    -- Наполняем таблицу строками (строка1, строка2 или row1, row2...)
    local rowIndex = 1
    while true do
        local rowKey = "row" .. rowIndex
        local rowKeyRu = "строка" .. rowIndex
        local rowStr = args[rowKey] or args[rowKeyRu]

        if not rowStr then
            break
        end

        local rawCells = mw.text.split(rowStr, separator)
        local tr = html:tag('tr')

        -- Цикл идет строго по числу заголовков, чтобы избежать сломанной разметки
        for i = 1, #headers do
            local rawCell = rawCells[i] or ""
            local parsed = parseCell(rawCell)
            tr:tag('td')
                :cssText(parsed.style)
                :wikitext(parsed.text)
        end

        rowIndex = rowIndex + 1
    end

    -- Используем preprocess для подключения стилей плавающей шапки
    return frame:preprocess(wikiTemplates .. tostring(html))
end

return p