Модуль:Навигация курса
Внешний вид
Для документации этого модуля может быть создана страница Модуль:Навигация курса/doc
-- Module:Навигация
local p = {}
-- Функция для обрезки пробельных символов с начала и конца строки.
local function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
-- Основная функция навигации.
function p.nav(frame)
local args = frame.args
-- Получаем аргументы: main – имя главной страницы, page – имя текущей подстраницы.
local parentTitle = args.main or args[1]
local currentSubPage = args.page or args[2]
if not parentTitle or not currentSubPage then
return "Ошибка: не переданы обязательные аргументы 'main' (главная страница) и 'page' (текущая подстраница)."
end
-- Если имя подстраницы содержит слэш, оставляем только часть после последнего слеша.
if currentSubPage:find("/") then
local temp = currentSubPage:match(".*/(.*)")
if temp then
currentSubPage = trim(temp)
end
else
currentSubPage = trim(currentSubPage)
end
-- Получаем объект главной страницы и её содержимое.
local parentPageObj = mw.title.new(parentTitle)
local parentContent = parentPageObj and parentPageObj:getContent() or ""
if parentContent == "" then
return "Не удалось получить содержимое главной страницы '" .. parentTitle .. "'."
end
-- Ищем в содержимом блок шаблона {{Содержание ...}}
local contentBlock = parentContent:match("{{Содержание(.-)}}")
if not contentBlock then
return "На странице '" .. parentTitle .. "' не найден шаблон {{Содержание}}."
end
-- Собираем список страниц из найденного блока.
local pages = {}
for line in contentBlock:gmatch("[^\n]+") do
local trimmedLine = trim(line)
-- Обрабатываем только строки, начинающиеся с *, : или #
if trimmedLine:match("^[%*#:]") then
-- Ищем все wikilinks в строке.
for link in trimmedLine:gmatch("%[%[([^%]]-)%]%]") do
local target, display = link:match("([^|]+)|(.+)")
if target and target:match("^/") then
-- Если target начинается со слеша, берём текст после него и игнорируем display.
table.insert(pages, trim(target:sub(2)))
elseif display then
table.insert(pages, trim(display))
else
-- Если нет разделителя, выделяем часть после слеша, если она есть.
local afterSlash = link:match(".*/(.*)")
if afterSlash then
table.insert(pages, trim(afterSlash))
else
table.insert(pages, trim(link))
end
end
end
end
end
if #pages == 0 then
return "Не удалось извлечь список страниц из шаблона {{Содержание}} на странице '" .. parentTitle .. "'."
end
-- Ищем индекс текущей подстраницы в массиве.
local currentIndex = nil
for i, page in ipairs(pages) do
if page == currentSubPage then
currentIndex = i
break
end
end
if not currentIndex then
return "Имя страницы '" .. parentTitle .. "/" .. currentSubPage .. "' не найдено в содержании родительской страницы."
end
-- Формируем ссылки на предыдущую и следующую страницы, если они существуют.
local prevLink = ""
local nextLink = ""
if currentIndex > 1 then
local prevPage = pages[currentIndex - 1]
prevLink = "[[" .. parentTitle .. "/" .. prevPage .. "|" .. prevPage .. "]]"
end
if currentIndex < #pages then
local nextPage = pages[currentIndex + 1]
nextLink = "[[" .. parentTitle .. "/" .. nextPage .. "|" .. nextPage .. "]]"
end
-- Обработка аргумента type: prev, next или оба варианта.
local navType = (args.type and args.type:lower()) or ""
if navType == "prev" then
if prevLink ~= "" then
return "[[Файл:Left Arrow - The Noun Project.svg|25px|link=]] " .. prevLink
else
return ""
end
elseif navType == "next" then
if nextLink ~= "" then
return nextLink .. " [[Файл:Right Arrow - The Noun Project.svg|25px|link=]]"
else
return ""
end
else
local outputParts = {}
if prevLink ~= "" then
table.insert(outputParts, "Предыдущая: " .. prevLink)
end
if nextLink ~= "" then
table.insert(outputParts, "Следующая: " .. nextLink)
end
return table.concat(outputParts, " | ")
end
end
return p