Модуль:chemcard
| Строка 27: | Строка 27: | ||
if not recipeStr or recipeStr == "" then return {} end | if not recipeStr or recipeStr == "" then return {} end | ||
local lines = splitLines(recipeStr) | local lines = splitLines(recipeStr) | ||
local | local steps = {} | ||
local currentInputs = {} | local currentInputs = {} | ||
local i = 1 | local i = 1 | ||
| Строка 36: | Строка 36: | ||
if #currentInputs > 0 then | if #currentInputs > 0 then | ||
local outputs = {} | local outputs = {} | ||
i = i + 1 | i = i + 1 | ||
while i <= #lines do | while i <= #lines do | ||
local nextLine = lines[i] | local nextLine = lines[i] | ||
| Строка 44: | Строка 44: | ||
i = i + 1 | i = i + 1 | ||
end | end | ||
table.insert(steps, { | |||
table.insert( | |||
inputs = currentInputs, | inputs = currentInputs, | ||
outputs = outputs, | outputs = outputs, | ||
action = | action = mw.text.trim(line) | ||
}) | }) | ||
currentInputs = {} | currentInputs = {} | ||
else | else | ||
i = i + 1 | i = i + 1 | ||
end | end | ||
else | else | ||
| Строка 60: | Строка 59: | ||
end | end | ||
if #currentInputs > 0 then | if #currentInputs > 0 then | ||
table.insert( | table.insert(steps, { inputs = currentInputs, outputs = {}, action = "" }) | ||
end | end | ||
return | return steps | ||
end | end | ||
local function buildRecipeStepHtml(rec) | local function buildRecipeStepHtml(rec) | ||
if not rec or (#rec.inputs == 0 | if not rec or (#rec.inputs == 0 and #rec.outputs == 0) then return nil end | ||
local inner = html.create("div"):addClass("chem-recipe") | local inner = html.create("div"):addClass("chem-recipe") | ||
-- INPUTS | -- INPUTS | ||
local inputsDiv = html.create("div"):addClass("recipe-inputs") | local inputsDiv = html.create("div"):addClass("recipe-inputs") | ||
| Строка 78: | Строка 76: | ||
end | end | ||
inner:node(inputsDiv) | inner:node(inputsDiv) | ||
-- ACTION + | -- ACTION (спрайт строго сверху + текст) | ||
if rec.action and rec.action ~= "" then | if rec.action and rec.action ~= "" then | ||
local actionDiv = inner:tag("div"):addClass("recipe-action") | local actionDiv = inner:tag("div"):addClass("recipe-action") | ||
local | local content = actionDiv:tag("div"):addClass("recipe-action-content") | ||
local sprite = '[[File:Beaker.png|36px|class=chem-beaker]]' | |||
local actionText = rec.action | |||
-- Если пользователь указал свой спрайт в строке действия | |||
local customSprite = mw.ustring.match(actionText, "(%[%[File:[^%]]+%]%]%)") | |||
if customSprite then | |||
sprite = customSprite | |||
actionText = mw.text.trim(mw.ustring.gsub(actionText, "%[%[File:[^%]]+%]%]", "")) | |||
end | end | ||
content:tag("div"):addClass("action-sprite"):wikitext(sprite) | |||
content:tag("div"):addClass("action-text"):wikitext(actionText) | |||
end | end | ||
-- OUTPUTS | -- OUTPUTS | ||
local outputsDiv = html.create("div"):addClass("recipe-outputs") | local outputsDiv = html.create("div"):addClass("recipe-outputs") | ||
| Строка 97: | Строка 103: | ||
end | end | ||
inner:node(outputsDiv) | inner:node(outputsDiv) | ||
return inner | return inner | ||
end | end | ||
| Строка 109: | Строка 115: | ||
hcontent:tag("span"):addClass("collapse-btn"):wikitext("развернуть") | hcontent:tag("span"):addClass("collapse-btn"):wikitext("развернуть") | ||
container:node(heading) | container:node(heading) | ||
local collapsible = html.create("div"):addClass("collapsible collapsed"):attr("data-kind", "effects") | local collapsible = html.create("div"):addClass("collapsible collapsed"):attr("data-kind", "effects") | ||
local inner = html.create("div"):addClass("chem-effects") | local inner = html.create("div"):addClass("chem-effects") | ||
| Строка 128: | Строка 135: | ||
local border = args.border or "#444" | local border = args.border or "#444" | ||
local desc = args.desc or "" | local desc = args.desc or "" | ||
local | -- Собираем ВСЕ варианты рецептов (recipe, recipe2, recipe3…) | ||
local variants = {} | |||
local i = 1 | local i = 1 | ||
while true do | while true do | ||
| Строка 135: | Строка 143: | ||
local recipeStr = args[key] | local recipeStr = args[key] | ||
if not recipeStr then break end | if not recipeStr then break end | ||
local | local steps = parseRecipeString(recipeStr) | ||
if #steps > 0 then | |||
table.insert( | table.insert(variants, {id = i, steps = steps}) | ||
end | end | ||
i = i + 1 | i = i + 1 | ||
end | end | ||
local container = html.create("div"):addClass("chem-card") | local container = html.create("div"):addClass("chem-card") | ||
container:attr("style", "border-color:" .. border .. "; --card-accent:" .. color) | container:attr("style", "border-color:" .. border .. "; --card-accent:" .. color) | ||
container:tag("div"):addClass("chem-name-header"):wikitext(name) | container:tag("div"):addClass("chem-name-header"):wikitext(name) | ||
if # | if #variants > 0 then | ||
local recipeBlock = html.create("div"):addClass("chem-recipe-block") | local recipeBlock = html.create("div"):addClass("chem-recipe-block") | ||
local heading = html.create("div"):addClass("chem-heading"):attr("data-kind", "recipe") | local heading = html.create("div"):addClass("chem-heading"):attr("data-kind", "recipe") | ||
| Строка 153: | Строка 161: | ||
hcontent:tag("span"):addClass("collapse-btn"):wikitext("развернуть") | hcontent:tag("span"):addClass("collapse-btn"):wikitext("развернуть") | ||
recipeBlock:node(heading) | recipeBlock:node(heading) | ||
local collapsible = html.create("div"):addClass("collapsible collapsed"):attr("data-kind", "recipe") | local collapsible = html.create("div"):addClass("collapsible collapsed"):attr("data-kind", "recipe") | ||
local stepsContainer = html.create("div"):addClass("chem-recipe-steps") | local stepsContainer = html.create("div"):addClass("chem-recipe-steps") | ||
for vidx, variant in ipairs(variants) do | |||
-- Если несколько вариантов — показываем «Вариант X» | |||
if #variants > 1 then | |||
local varHeader = stepsContainer:tag("div"):addClass("recipe-variant-header") | |||
varHeader:wikitext("Вариант " .. vidx) | |||
end | |||
for _, rec in ipairs(variant.steps) do | |||
local step = buildRecipeStepHtml(rec) | |||
if step then stepsContainer:node(step) end | |||
end | |||
end | end | ||
collapsible:node(stepsContainer) | collapsible:node(stepsContainer) | ||
recipeBlock:node(collapsible) | recipeBlock:node(collapsible) | ||
container:node(recipeBlock) | container:node(recipeBlock) | ||
end | end | ||
local effectsBlock = buildEffectsHtml(args.effects) | local effectsBlock = buildEffectsHtml(args.effects) | ||
if effectsBlock then container:node(effectsBlock) end | if effectsBlock then container:node(effectsBlock) end | ||
if desc ~= "" then | if desc ~= "" then | ||
container:tag("div"):addClass("chem-desc"):wikitext(desc) | container:tag("div"):addClass("chem-desc"):wikitext(desc) | ||
end | end | ||
return tostring(container) | return tostring(container) | ||
end | end | ||
return p | return p | ||