Модуль:ТранспортнаяСхема: различия между версиями

ПОЕХАЛИ
 
мНет описания правки
Строка 1: Строка 1:
local p = {}
local p = {}


-- Загрузка и проверка JSON-данных
-- Безопасная загрузка JSON из пространства Шаблонов
local function loadData(frame)
local function loadData(frame)
     local dataPage = frame.args['данные'] or frame.args[1]
     local dataParam = frame.args['данные'] or frame.args[1]
     if not dataPage or dataPage == '' then
     if not dataParam or dataParam == '' then
         error('Не указана страница данных JSON (параметр 1 или |данные=)')
         error('Не указано имя базы данных или страница JSON (параметр 1 или |данные=)')
     end
     end
      
      
     if not mw.ustring.find(dataPage, ':') then
    local dataPageTitle = dataParam
         dataPage = 'Шаблон:Интерактивная схема ' .. dataPage .. '/data.json'
     if not mw.ustring.find(dataParam, ':') then
         dataPageTitle = 'Шаблон:Интерактивная схема ' .. dataParam .. '/data.json'
     end
     end
      
      
     local success, jsonData = pcall(mw.loadJsonData, dataPage)
    -- Способ 1: Стандартная загрузка через mw.loadJsonData (если тип контента страницы = JSON)
     if not success or not jsonData then
     local success, jsonData = pcall(mw.loadJsonData, dataPageTitle)
         error('Не удалось загрузить JSON-данные со страницы: ' .. dataPage)
     if success and jsonData then
         return jsonData
     end
     end
     return jsonData
      
    -- Способ 2: Резервная загрузка текста и декодирование (если страница сохранена как wikitext)
    local titleObj = mw.title.new(dataPageTitle)
    if titleObj and titleObj.exists then
        local rawText = titleObj:getContent()
        if rawText and rawText ~= '' then
            -- Очистка от возможных noinclude / комментариев
            rawText = mw.ustring.gsub(rawText, '<noinclude>.-</noinclude>', '')
            rawText = mw.ustring.gsub(rawText, '<!--.--->', '')
            rawText = mw.text.trim(rawText)
           
            local decodeSuccess, decodedData = pcall(mw.text.jsonDecode, rawText)
            if decodeSuccess and decodedData then
                return decodedData
            else
                error('Ошибка в синтаксисе JSON на странице [[' .. dataPageTitle .. ']]! Проверьте запятые и кавычки.')
            end
        end
    end
   
    error('Страница данных [[' .. dataPageTitle .. ']] не найдена. Убедитесь, что она создана.')
end
end


-- Генерация тела <imagemap>
-- Генерация кода <imagemap>
local function buildImageMap(jsonData, imageFile, width, defaultRadius)
local function buildImageMap(jsonData, imageFile, width, defaultRadius)
     local radius = defaultRadius or '16'
     local radius = defaultRadius or '16'
     local mapText = 'Файл:' .. imageFile .. '|' .. width .. '|center|alt=' .. (jsonData.title or 'Схема общественного транспорта Муроморска') .. '\n'
     local mapText = 'Файл:' .. imageFile .. '|' .. width .. '|center|alt=' .. (jsonData.title or 'Схема скоростного транспорта Муроморска') .. '\n'
      
      
     for _, line in ipairs(jsonData.lines or {}) do
     for _, line in ipairs(jsonData.lines or {}) do
Строка 41: Строка 63:
end
end


-- Получение названия категории транспорта
-- Названия категорий транспорта
local function getModeLabel(mode)
local function getModeLabel(mode)
     local modes = {
     local modes = {
         metro = '🚇 Линии Муроморского метрополитена',
         metro = '🚇 Линии Муроморского метрополитена',
         train = '🚆 Направления Мурской железной дороги (МЖД)',
         train = '🚆 Направления Мурской железной дороги (МЖД)',
        tram = '🚋 Маршруты Муроморского трамвая',
         other = '🚍 Прочие линии'
        trolley = '🚎 Маршруты Муроморского троллейбуса',
        bus = '🚌 Маршруты Муроморского автобуса',
         other = '🚍 Прочие маршруты'
     }
     }
     return modes[mode] or modes.other
     return modes[mode] or modes.other
end
end


-- Главная функция рендеринга схемы
-- Рендеринг схемы
function p.render(frame)
function p.render(frame)
     local args = frame:getParent().args
     local args = frame:getParent().args
Строка 62: Строка 81:


     local jsonData = loadData(frame)
     local jsonData = loadData(frame)
     local imageFile = args['файл'] or jsonData.image or 'Схема_транспорта_Муроморска.png'
     local imageFile = args['файл'] or jsonData.image or 'Схема_Муроморского_метрополитена.png'
     local width = args['ширина'] or jsonData.width or '950px'
     local width = args['ширина'] or jsonData.width or '850px'
     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'
      
      
Строка 107: Строка 126:
     end
     end


     -- 2. Легенда линий и маршрутов
     -- 2. Легенда линий
     if jsonData.lines and #jsonData.lines > 0 then
     if jsonData.lines and #jsonData.lines > 0 then
         local legend = root:tag('div')
         local legend = root:tag('div')
Строка 113: Строка 132:
             :css({
             :css({
                 ['margin'] = '12px auto',
                 ['margin'] = '12px auto',
                 ['max-width'] = '980px',
                 ['max-width'] = '950px',
                 ['padding'] = '10px 14px',
                 ['padding'] = '8px 12px',
                 ['background'] = '#f6f8fa',
                 ['background'] = '#f6f8fa',
                 ['border'] = '1px solid #d0d7de',
                 ['border'] = '1px solid #d0d7de',
Строка 122: Строка 141:
         legend:tag('div')
         legend:tag('div')
             :css({
             :css({
                 ['font-size'] = '11.5px',
                 ['font-size'] = '11px',
                 ['font-weight'] = 'bold',
                 ['font-weight'] = 'bold',
                 ['color'] = '#57606a',
                 ['color'] = '#57606a',
                 ['text-transform'] = 'uppercase',
                 ['text-transform'] = 'uppercase',
                 ['margin-bottom'] = '8px',
                 ['margin-bottom'] = '6px',
                 ['letter-spacing'] = '0.5px'
                 ['letter-spacing'] = '0.5px'
             })
             })
             :wikitext(jsonData.legendTitle or 'Линии и маршруты Муроморского транспорта')
             :wikitext(jsonData.legendTitle or 'Линии скоростного транспорта')


         local legendBadges = legend:tag('div')
         local legendBadges = legend:tag('div')
Строка 173: Строка 192:
     end
     end


     -- 3. Каталог станций и остановочных пунктов
     -- 3. Каталог станций
     if jsonData.lines and #jsonData.lines > 0 then
     if jsonData.lines and #jsonData.lines > 0 then
         local listCard = root:tag('div')
         local listCard = root:tag('div')
Строка 179: Строка 198:
             :css({
             :css({
                 ['margin'] = '12px auto 0 auto',
                 ['margin'] = '12px auto 0 auto',
                 ['max-width'] = '980px',
                 ['max-width'] = '950px',
                 ['text-align'] = 'left',
                 ['text-align'] = 'left',
                 ['background'] = 'var(--background-color-neutral-subtle, #f8f9fa)',
                 ['background'] = 'var(--background-color-neutral-subtle, #f8f9fa)',
Строка 195: Строка 214:
                 ['border-bottom'] = '1px solid var(--border-color-base, #d0d7de)'
                 ['border-bottom'] = '1px solid var(--border-color-base, #d0d7de)'
             })
             })
             :wikitext(jsonData.listTitle or '📋 Реестр линий, маршрутов и остановочных пунктов Муроморска')
             :wikitext(jsonData.listTitle or '📋 Реестр станций метрополитена и МЖД')


         local listContent = listCard:tag('div')
         local listContent = listCard:tag('div')
Строка 224: Строка 243:
                 if station.transfer then
                 if station.transfer then
                     listWikitext = listWikitext .. " <small style='color:#57606a;'>(" .. station.transfer .. ")</small>"
                     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
                 end
                 listWikitext = listWikitext .. '\n'
                 listWikitext = listWikitext .. '\n'