Модуль:ТранспортнаяСхема: различия между версиями
Tringoli (обсуждение | вклад) мНет описания правки |
Tringoli (обсуждение | вклад) мНет описания правки |
||
| Строка 13: | Строка 13: | ||
end | end | ||
-- Способ 1: | -- Способ 1: mw.loadJsonData | ||
local success, jsonData = pcall(mw.loadJsonData, dataPageTitle) | local success, jsonData = pcall(mw.loadJsonData, dataPageTitle) | ||
if success and jsonData then | if success and jsonData then | ||
| Строка 19: | Строка 19: | ||
end | end | ||
-- Способ 2: Резервная загрузка текста | -- Способ 2: Резервная загрузка текста | ||
local titleObj = mw.title.new(dataPageTitle) | local titleObj = mw.title.new(dataPageTitle) | ||
if titleObj and titleObj.exists then | if titleObj and titleObj.exists then | ||
local rawText = titleObj:getContent() | local rawText = titleObj:getContent() | ||
if rawText and rawText ~= '' then | if rawText and rawText ~= '' then | ||
rawText = mw.ustring.gsub(rawText, '<noinclude>.-</noinclude>', '') | rawText = mw.ustring.gsub(rawText, '<noinclude>.-</noinclude>', '') | ||
rawText = mw.ustring.gsub(rawText, '<!--.--->', '') | rawText = mw.ustring.gsub(rawText, '<!--.--->', '') | ||
| Строка 81: | Строка 80: | ||
local jsonData = loadData(frame) | local jsonData = loadData(frame) | ||
local isInfobox = (args['карточка'] == 'да' or args['тип'] == 'карточка' or frame.args['карточка'] == 'да') | |||
local defaultWidth = isInfobox and '280px' or '850px' | |||
local imageFile = args['файл'] or jsonData.image or 'Схема_Муроморского_метрополитена.png' | local imageFile = args['файл'] or jsonData.image or 'Схема_Муроморского_метрополитена.png' | ||
local width = args['ширина'] or jsonData.width or | local width = args['ширина'] or (not isInfobox and jsonData.width) or defaultWidth | ||
local caption = args['подпись'] or jsonData.caption or ' | local caption = args['подпись'] or jsonData.caption or '' | ||
local defaultRadius = args['радиус'] or jsonData.defaultRadius or '16' | local defaultRadius = args['радиус'] or jsonData.defaultRadius or '16' | ||
| Строка 89: | Строка 91: | ||
:addClass('ts-transport-scheme') | :addClass('ts-transport-scheme') | ||
:css({ | :css({ | ||
['clear'] = 'both', | ['clear'] = isInfobox and 'none' or 'both', | ||
['margin'] = '1.2em auto', | ['margin'] = isInfobox and '0 auto' or '1.2em auto', | ||
['width'] = '100%', | ['width'] = '100%', | ||
['text-align'] = 'center' | ['text-align'] = 'center' | ||
| Строка 99: | Строка 101: | ||
:addClass('ts-transport-map-card') | :addClass('ts-transport-map-card') | ||
:css({ | :css({ | ||
['display'] = 'inline-block', | ['display'] = isInfobox and 'block' or 'inline-block', | ||
['max-width'] = '100%', | ['max-width'] = '100%', | ||
['background'] = 'var(--background-color-base, #ffffff)', | ['background'] = isInfobox and 'transparent' or 'var(--background-color-base, #ffffff)', | ||
['border'] = '1px solid var(--border-color-base, #d0d7de)', | ['border'] = isInfobox and 'none' or '1px solid var(--border-color-base, #d0d7de)', | ||
['border-radius'] = '10px', | ['border-radius'] = isInfobox and '0' or '10px', | ||
['padding'] = '10px', | ['padding'] = isInfobox and '0' or '10px', | ||
['box-shadow'] = '0 3px 12px rgba(0,0,0,0.06)' | ['box-shadow'] = isInfobox and 'none' or '0 3px 12px rgba(0,0,0,0.06)' | ||
}) | }) | ||
local mapContainer = mapCard:tag('div') | local mapContainer = mapCard:tag('div') | ||
:css({ ['overflow-x'] = 'auto', ['max-width'] = '100%' }) | :css({ | ||
['overflow-x'] = 'auto', | |||
['max-width'] = '100%', | |||
['text-align'] = 'center' | |||
}) | |||
local imageMapContent = buildImageMap(jsonData, imageFile, width, defaultRadius) | local imageMapContent = buildImageMap(jsonData, imageFile, width, defaultRadius) | ||
mapContainer:wikitext(frame:preprocess('{{#tag:imagemap|' .. imageMapContent .. '}}')) | mapContainer:wikitext(frame:preprocess('{{#tag:imagemap|' .. imageMapContent .. '}}')) | ||
if caption ~= '' then | if caption ~= '' and not isInfobox then | ||
mapCard:tag('div') | mapCard:tag('div') | ||
:css({ | :css({ | ||
| Строка 126: | Строка 132: | ||
end | end | ||
-- 2. Легенда линий | -- В режиме карточки (инфобокса) скрываем громоздкую легенду и реестр | ||
if not isInfobox then | |||
-- 2. Легенда линий | |||
if jsonData.lines and #jsonData.lines > 0 then | |||
local legend = root:tag('div') | |||
:addClass('ts-transport-lines-legend') | |||
:css({ | |||
['margin'] = '12px auto', | |||
['max-width'] = '950px', | |||
['padding'] = '8px 12px', | |||
['background'] = '#f6f8fa', | |||
['border'] = '1px solid #d0d7de', | |||
['border-radius'] = '8px' | |||
}) | |||
legend:tag('div') | |||
:css({ | :css({ | ||
[' | ['font-size'] = '11px', | ||
[' | ['font-weight'] = 'bold', | ||
[' | ['color'] = '#57606a', | ||
['text-transform'] = 'uppercase', | |||
[' | ['margin-bottom'] = '6px', | ||
[' | ['letter-spacing'] = '0.5px' | ||
[' | |||
}) | }) | ||
:wikitext(jsonData.legendTitle or 'Линии скоростного транспорта') | |||
local legendBadges = legend:tag('div') | |||
:css({ | :css({ | ||
['display'] = ' | ['display'] = 'flex', | ||
[' | ['flex-wrap'] = 'wrap', | ||
['justify-content'] = 'center', | ['justify-content'] = 'center', | ||
[' | ['gap'] = '5px' | ||
}) | }) | ||
badge:tag('span') | for _, line in ipairs(jsonData.lines) do | ||
:wikitext('[[' .. (line.article or '') .. '|' .. (line.displayName or line.name or line.article or '') .. ']]') | local badge = legendBadges:tag('span') | ||
:css({ | |||
['display'] = 'inline-flex', | |||
['align-items'] = 'center', | |||
['padding'] = '2px 8px 2px 4px', | |||
['background'] = '#ffffff', | |||
['border'] = '1px solid #d0d7de', | |||
['border-radius'] = '20px', | |||
['font-size'] = '12px' | |||
}) | |||
badge:tag('span') | |||
:css({ | |||
['display'] = 'inline-flex', | |||
['align-items'] = 'center', | |||
['justify-content'] = 'center', | |||
['min-width'] = '16px', | |||
['height'] = '16px', | |||
['padding'] = '0 4px', | |||
['border-radius'] = '999px', | |||
['background-color'] = line.color or '#888888', | |||
['color'] = line.textColor or '#ffffff', | |||
['font-size'] = '9.5px', | |||
['font-weight'] = 'bold', | |||
['margin-right'] = '6px' | |||
}) | |||
:wikitext(line.symbol or line.number or '•') | |||
badge:tag('span') | |||
:wikitext('[[' .. (line.article or '') .. '|' .. (line.displayName or line.name or line.article or '') .. ']]') | |||
end | |||
end | end | ||
-- 3. Каталог станций | |||
if jsonData.lines and #jsonData.lines > 0 then | |||
local listCard = root:tag('div') | |||
:addClass('mw-collapsible toccolours') | |||
:css({ | |||
['margin'] = '12px auto 0 auto', | |||
['max-width'] = '950px', | |||
['text-align'] = 'left', | |||
['background'] = 'var(--background-color-neutral-subtle, #f8f9fa)', | |||
['border'] = '1px solid var(--border-color-base, #d0d7de)', | |||
['border-radius'] = '8px', | |||
['overflow'] = 'hidden' | |||
}) | |||
listCard:tag('div') | |||
:css({ | |||
['font-weight'] = 'bold', | |||
['font-size'] = '13.5px', | |||
['background'] = 'linear-gradient(180deg, #f6f8fa 0%, #eaeef2 100%)', | |||
['padding'] = '9px 14px', | |||
['border-bottom'] = '1px solid var(--border-color-base, #d0d7de)' | |||
}) | |||
:wikitext(jsonData.listTitle or '📋 Реестр станций метрополитена и МЖД') | |||
local listContent = listCard:tag('div') | |||
:addClass('mw-collapsible-content') | |||
:css({ | |||
['padding'] = '14px 18px', | |||
['column-width'] = '20em', | |||
['column-gap'] = '2em', | |||
['column-rule'] = '1px solid #e1e4e8', | |||
['font-size'] = '13px', | |||
['line-height'] = '1.7' | |||
}) | |||
local currentMode = nil | |||
local listWikitext = '' | |||
for _, line in ipairs(jsonData.lines) do | |||
local mode = line.mode or 'other' | |||
if mode ~= currentMode then | |||
currentMode = mode | |||
listWikitext = listWikitext .. "\n; " .. getModeLabel(mode) .. "\n" | |||
end | |||
listWikitext = listWikitext .. "* '''[[" .. (line.article or '') .. '|' .. (line.name or line.article or '') .. "]]'''\n" | |||
for _, station in ipairs(line.stations or {}) do | |||
local badge = "<span style='display:inline-flex;align-items:center;justify-content:center;min-width:14px;height:14px;padding:0 3px;border-radius:999px;background:" .. (line.color or '#888') .. ";color:" .. (line.textColor or '#fff') .. ";font-size:9px;font-weight:bold;margin-right:4px;'>" .. (line.symbol or line.number or '•') .. "</span>" | |||
listWikitext = listWikitext .. '** ' .. badge .. ' [[' .. station.article .. '|' .. (station.name or station.article) .. ']]' | |||
if station.transfer then | |||
listWikitext = listWikitext .. " <small style='color:#57606a;'>(" .. station.transfer .. ")</small>" | |||
end | |||
if station.future then | |||
listWikitext = listWikitext .. " <small style='color:#8c959f; font-style:italic;'>(строит.)</small>" | |||
end | |||
listWikitext = listWikitext .. '\n' | |||
end | end | ||
end | end | ||
listContent:wikitext(listWikitext) | |||
end | end | ||
end | end | ||