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

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


-- Загрузка и нормализация данных из JSON/Wikitext
-- Безопасная очистка текста JSON
local function cleanJsonText(rawText)
    -- Убираем комментарии и noinclude
    rawText = mw.ustring.gsub(rawText, '<noinclude>.-</noinclude>', '')
    rawText = string.gsub(rawText, '<!%-%-.-%-%->', '')
   
    -- Замена неразрывных пробелов (UTF-8 C2 A0) через байтовый string.gsub
    rawText = string.gsub(rawText, '\194\160', ' ')
    rawText = string.gsub(rawText, '\194\173', '') -- soft hyphen
   
    return mw.text.trim(rawText)
end
 
-- Загрузка данных из data.json
local function loadData(args)
local function loadData(args)
     local dataParam = args['данные'] or args[1] or 'Муроморского'
     local dataParam = args['данные'] or args[1] or 'Муроморского'
Строка 31: Строка 44:
     end
     end
      
      
    -- Если уже передан полный путь с пространством имён или .json
     if mw.ustring.find(dataParam, ':') or mw.ustring.find(dataParam, '%.json$') then
     if mw.ustring.find(dataParam, ':') or mw.ustring.find(dataParam, '%.json$') then
         addCandidate(dataParam)
         addCandidate(dataParam)
Строка 46: Строка 58:
      
      
     for _, pageTitle in ipairs(candidates) do
     for _, pageTitle in ipairs(candidates) do
         -- 1. Пробуем штатный mw.loadJsonData
         -- 1. Попытка через mw.loadJsonData (если страница с моделью JSON)
         local ok, data = pcall(mw.loadJsonData, pageTitle)
         local ok, data = pcall(mw.loadJsonData, pageTitle)
         if ok and type(data) == 'table' then
         if ok and type(data) == 'table' then
Строка 52: Строка 64:
         end
         end
          
          
         -- 2. Пробуем прочитать как страницу wikitext
         -- 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 = cleanJsonText(rawText)
                 rawText = mw.ustring.gsub(rawText, '<noinclude>.-</noinclude>', '')
                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)
                  
                  
                 local decOk, decoded = pcall(mw.text.jsonDecode, rawText)
                 local decOk, decoded = pcall(mw.text.jsonDecode, rawText)
Строка 68: Строка 75:
                     return decoded
                     return decoded
                 else
                 else
                     lastError = 'Ошибка парсинга JSON на странице [[' .. pageTitle .. ']]: ' .. tostring(decoded)
                     lastError = 'Ошибка в синтаксисе JSON на странице [[' .. pageTitle .. ']]: ' .. tostring(decoded)
                 end
                 end
             end
             end