Модуль:chemcard
| Строка 30: | Строка 30: | ||
local currentInputs = {} | local currentInputs = {} | ||
local i = 1 | local i = 1 | ||
while i <= #lines do | while i <= #lines do | ||
local line = lines[i] | local line = lines[i] | ||
local lower = mw.ustring.lower(line) | local lower = mw.ustring.lower(line) | ||
if lower:find("смеш") then | if lower:find("смеш") then | ||
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: | Строка 47: | ||
i = i + 1 | i = i + 1 | ||
end | end | ||
table.insert(steps, { | table.insert(steps, { | ||
inputs = currentInputs, | inputs = currentInputs, | ||
| Строка 49: | Строка 53: | ||
action = mw.text.trim(line) | action = mw.text.trim(line) | ||
}) | }) | ||
currentInputs = {} | currentInputs = {} | ||
else | else | ||
| Строка 58: | Строка 63: | ||
end | end | ||
end | end | ||
if #currentInputs > 0 then | if #currentInputs > 0 then | ||
table.insert(steps, { inputs = currentInputs, outputs = {}, action = "" }) | table.insert(steps, { inputs = currentInputs, outputs = {}, action = "" }) | ||
end | end | ||
return steps | return steps | ||
end | end | ||
local FILE_PATTERN = "(%[%[File:[^]]+%]%])" | |||
local FILE_PATTERN = "(%[%[File:[^]]+%]%])" | |||
local function buildRecipeStepHtml(rec) | local function buildRecipeStepHtml(rec) | ||
| Строка 72: | Строка 78: | ||
local inner = html.create("div"):addClass("chem-recipe") | local inner = html.create("div"):addClass("chem-recipe") | ||
local inputsDiv = html.create("div"):addClass("recipe-inputs") | local inputsDiv = html.create("div"):addClass("recipe-inputs") | ||
for _, it in ipairs(rec.inputs) do | for _, it in ipairs(rec.inputs) do | ||
inputsDiv:tag("div") | |||
:addClass("recipe-item") | |||
:wikitext('[[File:Beaker.png|36px|class=chem-beaker]] ' .. it.name .. ' [' .. it.qty .. ']') | |||
end | end | ||
inner:node(inputsDiv) | inner:node(inputsDiv) | ||
- | local actionDiv = inner:tag("div"):addClass("recipe-action") | ||
if rec.action and rec.action ~= "" then | if rec.action and rec.action ~= "" then | ||
local content = actionDiv:tag("div"):addClass("recipe-action-content") | local content = actionDiv:tag("div"):addClass("recipe-action-content") | ||
| Строка 88: | Строка 93: | ||
local actionText = rec.action | local actionText = rec.action | ||
local customSprite = mw.ustring.match(actionText, FILE_PATTERN) | local customSprite = mw.ustring.match(actionText, FILE_PATTERN) | ||
if customSprite then | if customSprite then | ||
| Строка 99: | Строка 103: | ||
end | end | ||
local outputsDiv = html.create("div"):addClass("recipe-outputs") | local outputsDiv = html.create("div"):addClass("recipe-outputs") | ||
for _, it in ipairs(rec.outputs) do | for _, it in ipairs(rec.outputs) do | ||
outputsDiv:tag("div") | |||
:addClass("recipe-item") | |||
:wikitext('[[File:Beaker.png|36px|class=chem-beaker]] ' .. it.name .. ' [' .. it.qty .. ']') | |||
end | end | ||
inner:node(outputsDiv) | inner:node(outputsDiv) | ||
| Строка 109: | Строка 113: | ||
return inner | return inner | ||
end | end | ||
local function buildEffectsHtml(effects) | local function buildEffectsHtml(effects) | ||
if not effects or effects == "" or effects == "Нет" then return nil end | if not effects or effects == "" or effects == "Нет" then return nil end | ||
local container = html.create("div"):addClass("chem-effects-block") | local container = html.create("div"):addClass("chem-effects-block") | ||
local heading = html.create("div"):addClass("chem-heading | |||
local heading = html.create("div"):addClass("chem-heading") | |||
local hcontent = heading:tag("div"):addClass("chem-heading-content") | local hcontent = heading:tag("div"):addClass("chem-heading-content") | ||
hcontent:tag("span"):addClass("heading-text"):wikitext("Эффекты") | hcontent:tag("span"):addClass("heading-text"):wikitext("Эффекты") | ||
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 | local collapsible = html.create("div"):addClass("collapsible") | ||
local inner = html.create("div"):addClass("chem-effects") | local inner = html.create("div"):addClass("chem-effects") | ||
for effect in mw.text.gsplit(effects, "[;\n]") do | for effect in mw.text.gsplit(effects, "[;\n]") do | ||
effect = mw.text.trim(effect) | effect = mw.text.trim(effect) | ||
| Строка 128: | Строка 135: | ||
end | end | ||
end | end | ||
collapsible:node(inner) | collapsible:node(inner) | ||
container:node(collapsible) | container:node(collapsible) | ||
return container | return container | ||
end | end | ||
| Строка 135: | Строка 144: | ||
function p.card(frame) | function p.card(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
local name = args.name or "—" | local name = args.name or "—" | ||
local color = args.color or "#8cf" | local color = args.color or "#8cf" | ||
| Строка 142: | Строка 152: | ||
local variants = {} | local variants = {} | ||
local i = 1 | local i = 1 | ||
while true do | while true do | ||
local key = i == 1 and "recipe" or ("recipe" .. i) | local key = i == 1 and "recipe" or ("recipe" .. i) | ||
local recipeStr = args[key] | local recipeStr = args[key] | ||
if not recipeStr then break end | if not recipeStr then break end | ||
local steps = parseRecipeString(recipeStr) | local steps = parseRecipeString(recipeStr) | ||
if #steps > 0 then | if #steps > 0 then | ||
table.insert(variants, { | table.insert(variants, {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:tag("div"):addClass("chem-name-header"):wikitext(name) | :attr("style", "--card-accent:" .. color .. "; --card-border:" .. border) | ||
container:tag("div") | |||
:addClass("chem-name-header") | |||
:wikitext(name) | |||
if #variants > 0 then | 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 | |||
local heading = html.create("div"):addClass("chem-heading") | |||
local hcontent = heading:tag("div"):addClass("chem-heading-content") | local hcontent = heading:tag("div"):addClass("chem-heading-content") | ||
hcontent:tag("span"):addClass("heading-text"):wikitext("Рецепты") | hcontent:tag("span"):addClass("heading-text"):wikitext("Рецепты") | ||
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 | local collapsible = html.create("div"):addClass("collapsible") | ||
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 | for vidx, variant in ipairs(variants) do | ||
if #variants > 1 then | if #variants > 1 then | ||
stepsContainer:tag("div") | |||
:addClass("recipe-variant-header") | |||
:wikitext("Вариант " .. vidx) | |||
end | end | ||
| Строка 189: | Строка 209: | ||
if desc ~= "" then | if desc ~= "" then | ||
container:tag("div"):addClass("chem-desc"):wikitext(desc) | container:tag("div") | ||
:addClass("chem-desc") | |||
:wikitext(desc) | |||
end | end | ||