Модуль:AlchemyRecipe: различия между версиями

Материал из Space Stories Wiki
Нет описания правки
Нет описания правки
Строка 4: Строка 4:
     local args = frame:getParent().args
     local args = frame:getParent().args
      
      
     -- Обработка и экранирование параметров
     -- Обработка параметров
     local name = mw.text.killMarkers(args.name or "Без названия")
     local name = mw.text.killMarkers(args.name or "Без названия")
     local recipe = args.recipe or ""
     local recipe = args.recipe or ""
Строка 10: Строка 10:
     local method = (recipe ~= "" and "Смешайте") or "Неизвестно"
     local method = (recipe ~= "" and "Смешайте") or "Неизвестно"


     -- Функция для обработки реагентов (безопасная и с поддержкой запятых)
     -- Функция для форматирования реагентов с чекбоксами
     local function formatReagents(input)
     local function formatReagents(input)
         if input == "" then return "" end
         if input == "" then return "" end
          
          
         local result = {}
         local result = {}
         -- Регулярка для обработки элементов вида "Название [10]"
        local count = 0
         for item, qty in mw.ustring.gmatch(input, "([^%[%],]-)%s*%[(%d+)%]%s*,?") do
       
             item = mw.text.trim(item)
         -- Обрабатываем каждый элемент рецепта
             if item ~= "" then
         for item in mw.text.gsplit(input, ",") do
             local trimmed = mw.text.trim(item)
             if trimmed ~= "" then
                count = count + 1
                 table.insert(result, string.format(
                 table.insert(result, string.format(
                     '<div class="reagent-item">🧪 <span class="reagent">%s</span> <span class="qty">[%s]</span></div>',
                     '<div class="recipe-step">'..
                     mw.text.nowiki(item), qty
                    '<input type="checkbox" id="step%d" disabled>'..
                    '<label for="step%d">%s</label></div>',
                     count, count, mw.text.nowiki(trimmed)
                 ))
                 ))
             end
             end
         end
         end
       
        -- Добавляем шаг смешивания
        if count > 0 then
            table.insert(result, string.format(
                '<div class="recipe-step">'..
                '<input type="checkbox" id="step-mix" disabled checked>'..
                '<label for="step-mix">%s</label></div>',
                method
            ))
        end
       
         return table.concat(result)
         return table.concat(result)
     end
     end


     -- Современное сворачивание без JavaScript
     -- Генерация HTML
    local function makeCollapsible(title, body)
        return string.format([[
        <details class="alchemy-collapsible">
            <summary>%s</summary>
            <div class="alchemy-collapsible-content">%s</div>
        </details>]], title, body)
    end
 
    -- Сборка HTML-карточки
     local html = {
     local html = {
         '<div class="alchemy-card">',
         '<div class="alchemy-card">',
         '<div class="alchemy-title">' .. name .. '</div>',
         '<h1 class="alchemy-title">' .. name .. '</h1>',
       
         '<div class="alchemy-section">',
         '<div class="alchemy-section">',
         makeCollapsible("Рецепт", formatReagents(recipe) .. '<div class="method">🔄 ' .. method .. '</div>'),
         '<div class="section-header" onclick="toggleSection(this)">',
        '<span class="section-title">Рецепты</span>',
        '<span class="collapse-toggle">[свернуть]</span>',
         '</div>',
         '</div>',
        '<div class="section-content">',
        formatReagents(recipe),
        '</div>',
        '</div>',
       
        '<hr class="alchemy-divider">',
       
         '<div class="alchemy-section">',
         '<div class="alchemy-section">',
         makeCollapsible("Эффекты", effects),
         '<div class="section-header" onclick="toggleSection(this)">',
        '<span class="section-title">Эффекты</span>',
        '<span class="collapse-toggle">[свернуть]</span>',
         '</div>',
         '</div>',
         '</div>'
        '<div class="section-content">',
        effects,
        '</div>',
         '</div>',
       
        '</div>', -- закрываем alchemy-card
       
        -- JavaScript для сворачивания
        [[<script>
        function toggleSection(header) {
            const content = header.nextElementSibling;
            const toggle = header.querySelector('.collapse-toggle');
            if (content.style.display === "none") {
                content.style.display = "block";
                toggle.textContent = "[свернуть]";
            } else {
                content.style.display = "none";
                toggle.textContent = "[развернуть]";
            }
        }
        </script>]]
     }
     }
      
      

Версия от 11:15, 22 июня 2025

Для документации этого модуля может быть создана страница Модуль:AlchemyRecipe/doc

local p = {}

function p.main(frame)
    local args = frame:getParent().args
    
    -- Обработка параметров
    local name = mw.text.killMarkers(args.name or "Без названия")
    local recipe = args.recipe or ""
    local effects = frame:preprocess(args.effects or "Нет описания.")
    local method = (recipe ~= "" and "Смешайте") or "Неизвестно"

    -- Функция для форматирования реагентов с чекбоксами
    local function formatReagents(input)
        if input == "" then return "" end
        
        local result = {}
        local count = 0
        
        -- Обрабатываем каждый элемент рецепта
        for item in mw.text.gsplit(input, ",") do
            local trimmed = mw.text.trim(item)
            if trimmed ~= "" then
                count = count + 1
                table.insert(result, string.format(
                    '<div class="recipe-step">'..
                    '<input type="checkbox" id="step%d" disabled>'..
                    '<label for="step%d">%s</label></div>',
                    count, count, mw.text.nowiki(trimmed)
                ))
            end
        end
        
        -- Добавляем шаг смешивания
        if count > 0 then
            table.insert(result, string.format(
                '<div class="recipe-step">'..
                '<input type="checkbox" id="step-mix" disabled checked>'..
                '<label for="step-mix">%s</label></div>',
                method
            ))
        end
        
        return table.concat(result)
    end

    -- Генерация HTML
    local html = {
        '<div class="alchemy-card">',
        '<h1 class="alchemy-title">' .. name .. '</h1>',
        
        '<div class="alchemy-section">',
        '<div class="section-header" onclick="toggleSection(this)">',
        '<span class="section-title">Рецепты</span>',
        '<span class="collapse-toggle">[свернуть]</span>',
        '</div>',
        '<div class="section-content">',
        formatReagents(recipe),
        '</div>',
        '</div>',
        
        '<hr class="alchemy-divider">',
        
        '<div class="alchemy-section">',
        '<div class="section-header" onclick="toggleSection(this)">',
        '<span class="section-title">Эффекты</span>',
        '<span class="collapse-toggle">[свернуть]</span>',
        '</div>',
        '<div class="section-content">',
        effects,
        '</div>',
        '</div>',
        
        '</div>', -- закрываем alchemy-card
        
        -- JavaScript для сворачивания
        [[<script>
        function toggleSection(header) {
            const content = header.nextElementSibling;
            const toggle = header.querySelector('.collapse-toggle');
            if (content.style.display === "none") {
                content.style.display = "block";
                toggle.textContent = "[свернуть]";
            } else {
                content.style.display = "none";
                toggle.textContent = "[развернуть]";
            }
        }
        </script>]]
    }
    
    return table.concat(html)
end

return p