Модуль:ТранспортнаяСхема: различия между версиями
Tringoli (обсуждение | вклад) мНет описания правки |
Tringoli (обсуждение | вклад) Нет описания правки |
||
| Строка 16: | Строка 16: | ||
end | end | ||
-- Загрузка данных из data.json | -- Загрузка данных из data.json с расширенным поиском | ||
local function loadData(args) | local function loadData(args) | ||
local dataParam = args['данные'] or args[1] or 'Муроморского' | local dataParam = args['данные'] or args[1] or 'Муроморского' | ||
for _, title in ipairs(candidates) do | local candidates = {} | ||
local | local function addCandidate(title) | ||
if | if title and title ~= '' then | ||
for _, existing in ipairs(candidates) do | |||
if existing == title then return end | |||
end | |||
table.insert(candidates, title) | |||
end | |||
end | |||
-- Проверяем прямое имя, основное пространство и пространство Шаблон: | |||
addCandidate(dataParam) | |||
addCandidate(dataParam .. '/data.json') | |||
addCandidate('Шаблон:' .. dataParam) | |||
addCandidate('Шаблон:' .. dataParam .. '/data.json') | |||
addCandidate('Шаблон:Интерактивная схема ' .. dataParam .. '/data.json') | |||
addCandidate('Шаблон:Интерактивная схема ' .. dataParam .. ' метрополитена/data.json') | |||
addCandidate('Интерактивная схема ' .. dataParam .. '/data.json') | |||
addCandidate('Интерактивная схема ' .. dataParam .. ' метрополитена/data.json') | |||
local jsonErrors = {} | |||
for _, pageTitle in ipairs(candidates) do | |||
-- 1. Загрузка через mw.loadJsonData | |||
local ok, data = pcall(mw.loadJsonData, pageTitle) | |||
if ok and data and type(data) == 'table' then | |||
return data | |||
elseif not ok and data and not mw.ustring.find(tostring(data), 'does not exist') and not mw.ustring.find(tostring(data), 'не существует') then | |||
table.insert(jsonErrors, pageTitle .. ': ' .. tostring(data)) | |||
end | |||
local titleObj = mw.title.new( | -- 2. Загрузка текста через mw.title (если страница создана как вики-текст) | ||
local titleObj = mw.title.new(pageTitle) | |||
if titleObj and titleObj.exists then | if titleObj and titleObj.exists then | ||
local | local rawText = titleObj:getContent() | ||
if | if rawText and rawText ~= '' then | ||
rawText = mw.ustring.gsub(rawText, '<noinclude>.-</noinclude>', '') | |||
rawText = mw.ustring.gsub(rawText, '<!--.-?-->', '') | |||
local | rawText = mw.text.trim(rawText) | ||
if | |||
local decOk, decoded = pcall(mw.text.jsonDecode, rawText) | |||
if decOk and decoded and type(decoded) == 'table' then | |||
return decoded | |||
else | |||
table.insert(jsonErrors, pageTitle .. ' (ошибка синтаксиса JSON: ' .. tostring(decoded) .. ')') | |||
end | |||
end | end | ||
end | end | ||
end | end | ||
error('Страница данных JSON не найдена: ' .. | |||
if #jsonErrors > 0 then | |||
error('Ошибка в синтаксисе JSON на найденной странице:\n* ' .. table.concat(jsonErrors, '\n* ')) | |||
end | |||
error('Страница данных JSON не найдена. Убедитесь, что страница создана и сохранена под одним из названий:\n* [[' .. table.concat(candidates, ']]\n* [[') .. ']]') | |||
end | end | ||
| Строка 52: | Строка 84: | ||
end | end | ||
-- Генерация Canvas схемы | -- Генерация Canvas схемы | ||
function p.canvas(frame) | function p.canvas(frame) | ||
local args = getArgs(frame) | local args = getArgs(frame) | ||
local data = loadData(args) | local data = loadData(args) | ||
local origW = tonumber(args['ширина_оригинала'] or 850) or 850 | local origW = tonumber(args['ширина_оригинала'] or 850) or 850 | ||
local origH = tonumber(args['высота_оригинала'] or 620) or 620 | local origH = tonumber(args['высота_оригинала'] or 620) or 620 | ||
local cropX, cropY, cropW, cropH = nil, nil, nil, nil | local cropX, cropY, cropW, cropH = nil, nil, nil, nil | ||
if args['кадрирование'] or args['crop'] then | if args['кадрирование'] or args['crop'] then | ||
| Строка 78: | Строка 108: | ||
end | end | ||
local targetW = cropW or origW | local targetW = cropW or origW | ||
local targetH = cropH or origH | local targetH = cropH or origH | ||
| Строка 94: | Строка 123: | ||
local finalBoxH = tonumber(args['высота_блока'] or args['высота_карточки'] or args['высота']) or (targetH * scale) | local finalBoxH = tonumber(args['высота_блока'] or args['высота_карточки'] or args['высота']) or (targetH * scale) | ||
local wrapper = mw.html.create('div') | local wrapper = mw.html.create('div') | ||
:addClass('ts-transport-map-viewport') | :addClass('ts-transport-map-viewport') | ||
| Строка 113: | Строка 141: | ||
}) | }) | ||
local shiftX = cropX or 0 | local shiftX = cropX or 0 | ||
local shiftY = cropY or 0 | local shiftY = cropY or 0 | ||
local canvas = wrapper:tag('div') | local canvas = wrapper:tag('div') | ||
:addClass('ts-html-transport-canvas') | :addClass('ts-html-transport-canvas') | ||
| Строка 131: | Строка 157: | ||
}) | }) | ||
if not (args['шапка'] == 'нет' or cropX ~= nil) then | if not (args['шапка'] == 'нет' or cropX ~= nil) then | ||
local header = canvas:tag('div') | local header = canvas:tag('div') | ||
| Строка 163: | Строка 188: | ||
header:tag('div') | header:tag('div') | ||
:css({['text-align'] = 'left'}) | :css({['text-align'] = 'left'}) | ||
:tag('div'):css({['font-weight'] = 'bold', ['font-size'] = '13px', ['color'] = '#1f2328'}):wikitext(data.title or ' | :tag('div'):css({['font-weight'] = 'bold', ['font-size'] = '13px', ['color'] = '#1f2328'}):wikitext(data.title or 'Скоростной транспорт'):done() | ||
:tag('div'):css({['font-size'] = '10px', ['color'] = '#57606a', ['text-transform'] = 'uppercase', ['letter-spacing'] = '0.5px'}):wikitext('Интерактивная схема линий'):done() | :tag('div'):css({['font-size'] = '10px', ['color'] = '#57606a', ['text-transform'] = 'uppercase', ['letter-spacing'] = '0.5px'}):wikitext('Интерактивная схема линий'):done() | ||
end | end | ||
if data.lines then | if data.lines then | ||
-- | -- Слой путей | ||
for _, line in ipairs(data.lines) do | for _, line in ipairs(data.lines) do | ||
local color = line.color or '#888888' | local color = line.color or '#888888' | ||
| Строка 204: | Строка 229: | ||
end | end | ||
-- | -- Слой станций и подписей | ||
for _, line in ipairs(data.lines) do | for _, line in ipairs(data.lines) do | ||
local color = line.color or '#888888' | local color = line.color or '#888888' | ||
| Строка 215: | Строка 240: | ||
local isFuture = (st.future == true) | local isFuture = (st.future == true) | ||
local node = canvas:tag('div') | local node = canvas:tag('div') | ||
:css({ | :css({ | ||
| Строка 233: | Строка 257: | ||
node:wikitext('[[' .. article .. '|<span style="display:block;width:100%;height:100%;" title="' .. name .. '"></span>]]') | node:wikitext('[[' .. article .. '|<span style="display:block;width:100%;height:100%;" title="' .. name .. '"></span>]]') | ||
local isRightSide = (x >= (origW / 2)) | |||
local isRightSide = (x >= | |||
local label = canvas:tag('div') | local label = canvas:tag('div') | ||
:css({ | :css({ | ||