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

Нет описания правки
Нет описания правки
Строка 16: Строка 16:
end
end


-- Загрузка данных из data.json с расширенным поиском
-- Загрузка и нормализация данных из JSON/Wikitext
local function loadData(args)
local function loadData(args)
     local dataParam = args['данные'] or args[1] or 'Муроморского'
     local dataParam = args['данные'] or args[1] or 'Муроморского'
    dataParam = mw.text.trim(dataParam)
      
      
     local candidates = {}
     local candidates = {}
Строка 30: Строка 31:
     end
     end
      
      
     -- Проверяем прямое имя, основное пространство и пространство Шаблон:
     -- Если уже передан полный путь с пространством имён или .json
     addCandidate(dataParam)
     if mw.ustring.find(dataParam, ':') or mw.ustring.find(dataParam, '%.json$') then
    addCandidate(dataParam .. '/data.json')
        addCandidate(dataParam)
    addCandidate('Шаблон:' .. dataParam)
     else
     addCandidate('Шаблон:' .. dataParam .. '/data.json')
        addCandidate('Шаблон:Интерактивная схема ' .. dataParam .. '/data.json')
    addCandidate('Шаблон:Интерактивная схема ' .. dataParam .. '/data.json')
        addCandidate('Шаблон:Интерактивная схема ' .. dataParam .. ' метрополитена/data.json')
    addCandidate('Шаблон:Интерактивная схема ' .. dataParam .. ' метрополитена/data.json')
        addCandidate('Шаблон:' .. dataParam .. '/data.json')
    addCandidate('Интерактивная схема ' .. dataParam .. '/data.json')
        addCandidate('Интерактивная схема ' .. dataParam .. '/data.json')
    addCandidate('Интерактивная схема ' .. dataParam .. ' метрополитена/data.json')
        addCandidate(dataParam .. '/data.json')
        addCandidate(dataParam)
    end
      
      
     local jsonErrors = {}
     local lastError = nil
      
      
     for _, pageTitle in ipairs(candidates) do
     for _, pageTitle in ipairs(candidates) do
         -- 1. Загрузка через mw.loadJsonData
         -- 1. Пробуем штатный mw.loadJsonData
         local ok, data = pcall(mw.loadJsonData, pageTitle)
         local ok, data = pcall(mw.loadJsonData, pageTitle)
         if ok and data and type(data) == 'table' then
         if ok and type(data) == 'table' then
             return data
             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
         end
          
          
         -- 2. Загрузка текста через mw.title (если страница создана как вики-текст)
         -- 2. Пробуем прочитать как страницу wikitext
         local titleObj = mw.title.new(pageTitle)
         local titleObj = mw.title.new(pageTitle)
         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, '<!--.-?-->', '')
                -- Замена неразрывных пробелов (U+00A0 / \194\160) и спец-символов на стандартные пробелы
                rawText = mw.ustring.gsub(rawText, '[\194\160\160\u{00A0}\u{200B}\u{202F}\u{FEFF}]', ' ')
                 rawText = mw.text.trim(rawText)
                 rawText = mw.text.trim(rawText)
                  
                  
                 local decOk, decoded = pcall(mw.text.jsonDecode, rawText)
                 local decOk, decoded = pcall(mw.text.jsonDecode, rawText)
                 if decOk and decoded and type(decoded) == 'table' then
                 if decOk and type(decoded) == 'table' then
                     return decoded
                     return decoded
                 else
                 else
                     table.insert(jsonErrors, pageTitle .. ' (ошибка синтаксиса JSON: ' .. tostring(decoded) .. ')')
                     lastError = 'Ошибка парсинга JSON на странице [[' .. pageTitle .. ']]: ' .. tostring(decoded)
                 end
                 end
             end
             end
Строка 70: Строка 74:
     end
     end
      
      
     if #jsonErrors > 0 then
     if lastError then
         error('Ошибка в синтаксисе JSON на найденной странице:\n* ' .. table.concat(jsonErrors, '\n* '))
         error(lastError)
     end
     end
      
      
     error('Страница данных JSON не найдена. Убедитесь, что страница создана и сохранена под одним из названий:\n* [[' .. table.concat(candidates, ']]\n* [[') .. ']]')
     error('Страница данных не найдена. Проверены пути:\n* [[' .. table.concat(candidates, ']]\n* [[') .. ']]')
end
end


Строка 193: Строка 197:


     if data.lines then
     if data.lines then
         -- Слой путей
         -- 1. Слой путей
         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'
Строка 229: Строка 233:
         end
         end


         -- Слой станций и подписей
         -- 2. Слой станций и подписей
         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'