Модуль:Отексте
Реализует функциональность шаблона {{Отексте}} средствами Lua. Парсит в словниках шаблоны семейства {{Статья в словнике}}. Может подгружать на страницу секции из ПИ «Страница».
Используемые модули данных[править код]
- Модуль:Отексте/строки
- Модуль:Отексте/transl-lang — реализация шаблона {{Transl-lang}}
- Модуль:Источники по теме — генерация ссылок на словари и братские проекты
- MediaWiki:Encyclopedias settings.json — настройки энциклопедий, MediaWiki:Wikiprojects settings.json — настройки проектов
- Модули шаблонов словников (полный список):
- Модули расширений:
Шаблон:Статья в словнике[править код]
- Параметры шаблона
- 1-й и 2-й — названия страниц в двух орфографиях,
- 3-й параметр (а также 5-й и 7-й, если есть) — номера страниц/столбцов в печатном издании (hard), 4-й (также 6-й и 8-й) — номера страниц в скане (soft). Несколько пар этих параметров используются для сборки статьи из нескольких источников (см., например ЭСБЕ/Россия — единственный пока пример, где используются 7-й и 8-й параметры). Оба параметра (hard и soft) — составные, т. е. могут состоять из нескольких значений через слэш «/»: для hard —
страницы/пагинация/том
(пагинация — для случаев, когда том имеет несколько пагинаций, пока не используется); для soft — значенияfrom/to/exclude
для передачи в<pages>
.
Если параметр soft пустой или отсутствует, но в подмодуле имеется параметрoffsets
для данного тома — номера soft вычисляются на основе соответствующих номеров hard.
Переменные модуля[править код]
Пагинация[править код]
Номера страниц вычисляются по формуле: ((hard + correction) / factor) + offset (с округлением вверх)
.
- Параметры
hard
— номера страниц/столбцов в печатном изданииoffset
— смещение номеров страниц/столбцов книги относительно индексных страниц сканаsoft
— номера страниц в скане, = hard + correctionfactor
— для страниц скана, на которые приходится больше одного номера пагинации (колонки, сканы в разворот и т. п.). Например, при 2 номерах на страницу во всех томах:p.factor
= 2correction
— корректирующий сдвиг для factor. Если номера идут не в порядке 1-2,3-4,5-6… (здесь достаточно factor), а 1,2-3,4-5… — тогда используетсяcorrection = 1
Пример: для номеров 625 и 626 при correction=1, factor=2 и offset=17 получаем страницы 330 и 331; а при correction=0 (это значение по умолчанию) оба раза будет 330.
Модули-расширения[править код]
Модуль должен называться как подмодуль этого модуля, например Модуль:Отексте/Документ. И возвращать 3 значения (return params, categories, beforetext
). Где первое — таблица параметров в формате data.p
главного модуля, второе — таблица с категориями, третье — текст перед шаблоном-шапкой.
Для подключения в шаблоне (в данном примере в Шаблон:Документ) название модуля задаётся в переменной ext
:
{{#invoke:Отексте|textinfo|ext=Документ}}
- Алгоритм
Запускается Модуль:Отексте. По полученному из шаблона названию вызывается модуль расширения (extpath
), которому передается таблица с параметрами шаблона. Он их обрабатывает (в том числе все нестандартные параметры), и возвращает таблицу со стандартным набором данных для сборки Отексте. Далее главный модуль выполняется как обычно, только с другим набором данных.
Отслеживание ошибок[править код]
- Категория:Страница в оглавлении не найдена (оглавление — это словник)
- Категория:Оглавление не найдено
local p = {} -- Общие данные local data, flag = {}, {} local s = mw.loadData ( "Модуль:Отексте/строки" ) -- строки local util = require("Module:Util") local isPRS, isDict, isSub, isAuthor, isTrans, isData, isTypeJoin, isNewEdition, isExt -- флаги --[[ function p.textinfo( frame ) ------------------------------------------------------------------ Основная возвращаемая функция --------------------------------------------------------------------------------------------------]] function p.textinfo( frame ) initData ( frame ) -- Инициализация if not isDict then getDataMain () else getDataExt ( frame ) end -- Сборка ------------------------------------------------------------------ local midtext = renderTitle () .. renderSub () .. renderAuthorTrans () if flag.emPart then midtext = renderTitle () .. renderAuthorTrans () .. renderSub () end local root = mw.html.create() root :wikitext ( other_uses_tpl( frame, 1, data.p.disambig ) ) :wikitext ( s.PRS[isPRS] ) :wikitext ( renderQuality() ) local headertemplate = root:tag ( "div" ):attr ( "id", "headertemplate" ) -- Верхний блок ------------------------------------------------------------ headertemplate :tag ( "table" ):attr ( "id", "title_line" ):addClass ( "headertemplate ws-noexport" ) :css ( "clear", "both" ) :tag ( "tr" ) -- Ссылка назад :tag ( "td" ):addClass ( "header_backlink searchaux" ) :tag ( "span" ):attr ( "id", "headerprevious" ) :wikitext ( backarrow ( data.backlink ) ) :done() :done() -- Заголовок :tag ( "td" ):addClass ( "header_title" ) :wikitext ( midtext ) :done() -- Ссылка вперед :tag ( "td" ):addClass ( "header_forelink searchaux" ) :tag ( "span" ):attr ( "id", "headerprevious" ) :wikitext ( forearrow ( data.forelink ) ) :allDone() headertemplate:tag ( "div" ):attr ( "id", "sub_nav" ) :wikitext ( renderSubNav ( getSubNav () ) ) -- Дополнительная навигация -- Примечания (нижний блок) ------------------------------------------------ headertemplate :tag ( "table" ):addClass ( "header_notes ws-noexport" ) :tag ( "tr" ):attr ( "valign", "top" ) :wikitext ( renderNotes ( frame ) ) --:wikitext ( renderEditions ( frame ) ) :allDone() headertemplate :wikitext ( data.sortKey or "" ) -- Ключ сортировки :wikitext ( renderExtraNav ( frame ) ) -- Навигация-мини, Другие словари, НЕОДНОЗНАЧНОСТЬ, ПРЕДУПРЕЖДЕНИЕ, :wikitext ( renderImgFooter ( frame ) ) -- ИЗОБРАЖЕНИЕ и Footer :wikitext ( table.concat ( data.cat ) ) -- Категории -- if isDict or isExt then -- root:wikitext ( data.beforetext .. ( data.pagetext or "" ) ) -- end root:wikitext ( data.beforetext .. ( data.pagetext or "" )) return tostring ( root ) end -- Init functions ---------------------------------------------------------------------------------- --[[ function initData ( frame ) ------------------------------------------------------------------- Получает параметры из frame и frame:getParent() Производит первичную обработку параметров и наполняет таблицу data --------------------------------------------------------------------------------------------------]] function initData ( frame ) local page = mw.title.getCurrentTitle() local pagename = page.text local type, root, edition = parseTitle ( pagename ) isNewEdition = ( type == 1 or type == 2 ) isPRS = toBool ( pagename:find ( "/ДО$" ) or pagename:find ( "/ДО/" ) or pagename:find ( " %(ДО%)$" ) or pagename:find ( " %(ДО%)/" ) ) isSub = page.isSubpage data = { f = frame.args, -- args p = {}, cat = {}, -- categories tempcat = "", page = page, -- page data pagename = pagename, basename = page.baseText, rootname = page.rootText, subname = page.subpageText, ns = page.namespace, searchname = pagename, -- что искать prefix = "", suffix = "", curr = {}, -- link data prev = {}, next = {}, toc = {}, backlink = "", forelink = "", toc_curr = "", subnavs = {}, footer = {}, wpsearch = false, -- поиск по ВП beforetext = "", -- текстовые элементы между шаблоном Отексте и собственно текстом страницы aftertext = "", -- текстовые элементы между шаблоном текстом страницы и элементами ниже } isDict = toBool ( is( data.f.dict ) ) -- для словарных статей (данные обрабатываются локальной процедурой getDataExt) local nodict = not isDict local pargs = frame:getParent().args isExt = toBool ( is( data.f.ext ) ) -- для надстроек (данные обрабатываются подключаемым модулем) if isExt then local extpath = "Модуль:Отексте/" .. data.f.ext if mw.title.new( extpath ).exists then pargs, data.cat, data.beforetext = require( extpath ).wrapper( frame, pargs ) -- таблица параметров, таблица категорий, текстовая шапка end end data.p = { quality = pargs["КАЧЕСТВО"], title = is( pargs["НАЗВАНИЕ"] ), part = nodict and is( pargs["ЧАСТЬ"] ), -- nil или строка sub = nodict and is( pargs["ПОДЗАГОЛОВОК"] ), partsub = nodict and is( pargs["ПОДЗАГОЛОВОКЧАСТИ"] ), backlink = is( pargs["ПРЕДЫДУЩИЙ"] ), forelink = is( pargs["СЛЕДУЮЩИЙ"] ), author = nodict and is( pargs["АВТОР"] ), authors = nodict and is( pargs["АВТОРЫ"] ), noauthor = pargs["НЕТ_АВТОРА"], origLang = mw.ustring.lower( pargs["ЯЗЫКОРИГИНАЛА"] or "" ), -- nil (не задано) - перев. не известен; '' - нет; или код языка origTitle = nodict and is( pargs["НАЗВАНИЕОРИГИНАЛА"] ), origSub = nodict and is( pargs["ПОДЗАГОЛОВОКОРИГИНАЛА"] ), origCreated = nodict and is( pargs["ДАТАСОЗДАНИЯОРИГИНАЛА"] ), origPublished = nodict and is( pargs["ДАТАПУБЛИКАЦИИОРИГИНАЛА"] ), translator = nodict and is( pargs["ПЕРЕВОДЧИК"] ), other_translations = nodict and is( pargs["ДРУГИЕПЕРЕВОДЫ"] ), other_versions = is ( pargs["ДРУГИЕВЕРСИИ"] ), index = nodict and is( pargs["СОДЕРЖАНИЕ"] ), cycle = nodict and is( pargs["ИЗЦИКЛА"] ), collection = nodict and is( pargs["ИЗСБОРНИКА"] ), created = nodict and is( pargs["ДАТАСОЗДАНИЯ"] ), published = nodict and is( pargs["ДАТАПУБЛИКАЦИИ"] ), source = nodict and is( pargs["ИСТОЧНИК"] ), suppress_source = nodict and pargs["НЕТ_ИСТОЧНИКА"], other = is( pargs["ДРУГОЕ"] ), lawdeprecated = is( pargs["УТРАТИЛ СИЛУ"] ), toc = is( pargs["ОГЛАВЛЕНИЕ"] ), innerToc = is( pargs["ОГЛАВЛЕНИЕ2"] ), subnav = is( pargs["НАВИГАЦИЯ"] ), img = nodict and is( pargs["ИЗОБРАЖЕНИЕ"] ), imgDesc = nodict and is( pargs["ОПИСАНИЕИЗОБРАЖЕНИЯ"] ), editions = is( pargs["РЕДАКЦИИ"] ), disambig = is( pargs["НЕОДНОЗНАЧНОСТЬ"] ), section = is( pargs["СЕКЦИЯ"] ), license = is( pargs["ЛИЦЕНЗИЯ"] ), pages = pargs["СТРАНИЦЫ"], -- ЭСБЕ wp = is( pargs["ВИКИПЕДИЯ"] ), ws = is( pargs["ВИКИТЕКА"] ), commons = is( pargs["ВИКИСКЛАД"] ), sortKey = is( pargs["КЛЮЧ"] ), category = is( pargs["КАТЕГОРИЯ"] ), -- только для словарных статей (одна буква, для переопределения алфавитных категорий) categories = is( pargs["КАТЕГОРИИ"] ), -- список через тильду ("Категория 1~Категория 2") style = is( pargs["СТИЛЬ"] ), beforesimple = is( pargs["ПЕРЕДТЕКСТОМ"] ), beforeleft = is( pargs["СЛЕВА"] ), beforeright = is( pargs["СПРАВА"] ), } mw.logObject(pargs) -- контроль параметров и установка флагов if data.p.editions then addCat( s.cat.usesEditions ) end if data.p.pages then addCat( s.cat.usesPages ) end if data.p.part then data.p.part, flag.emPart = data.p.part:gsub ("^~+ *", "") data.p.part = is( data.p.part ) flag.emPart = ( flag.emPart ~= 0 ) -- 0 = false end if data.p.toc and data.p.toc:find("~") then local x = mw.text.split(data.p.toc," *~ *") data.p.toc, data.p.fallback = x[1], x[2] end -- expandstyle local expandstyle = { v = "poetry text", poetry = "poetry text", v2 = "poetry v2 text", v4 = "poetry v4 text", f = "drama text", drama = "drama text", i1 = "drama i1 text", i2 = "drama i2 text", i3 = "drama i3 text", i0 = "drama i0 text", i00 = "drama i00 text", i000 = "drama i000 text", i8 = "drama i8 text", i10 = "drama i10 text", i12 = "drama i12 text", i14 = "drama i14 text", i16 = "drama i16 text", i18 = "drama i18 text", i20 = "drama i20 text", i22 = "drama i22 text", i24 = "drama i24 text", i26 = "drama i26 text", i28 = "drama i28 text", i30 = "drama i30 text", i32 = "drama i32 text", i34 = "drama i34 text", i36 = "drama i36 text", f4 = "drama f4 text", f5 = "drama f5 text", f6 = "drama f6 text", f7 = "drama f7 text", f8 = "drama f8 text", f9 = "drama f9 text", f10 = "drama f10 text", f11 = "drama f11 text", f12 = "drama f12 text", f13 = "drama f13 text", f14 = "drama f14 text", f15 = "drama f15 text", f16 = "drama f16 text", f17 = "drama f17 text", f18 = "drama f18 text", fs4 = "drama f4 text poem-small", fs5 = "drama f5 text poem-small", fs6 = "drama f6 text poem-small", fs7 = "drama f7 text poem-small", fs8 = "drama f8 text poem-small", fs9 = "drama f9 text poem-small", fs10 = "drama f10 text poem-small", fs11 = "drama f11 text poem-small", fs12 = "drama f12 text poem-small", fs13 = "drama f13 text poem-small", fs14 = "drama f14 text poem-small", fs15 = "drama f15 text poem-small", fs16 = "drama f16 text poem-small", fs17 = "drama f17 text poem-small", fs18 = "drama f18 text poem-small", } data.p.style = expandstyle[data.p.style] or data.p.style --end -- категории if data.p.categories then local _cat = mw.text.split (data.p.categories, "%s*~%s*") for i, v in ipairs(_cat) do table.insert ( data.cat, '[[Категория:' .. v .. ']]' ) end end if isPRS and not isDict then addCat ( s.cat.oldOrthography ) end data.toc_choice = { data.p.author, data.p.index, data.p.cycle, data.p.collection, data.basename, data.rootname, data.p.translator, data.p.disambig } if isNewEdition then data.toc_choice[6] = root .. "/" .. edition end data.templates = { -- шаблоны словников "ЭСБЕ/Статья", "[Сс]татья в словнике%d?", "[Сс]татья в словнике ТСД", "[Тт]сдс", "[Tt]sds", "2[ОO] Статья в словнике" -- не используется?? } data.override = data.f.override data.title = data.p.title if data.subname == "ДО" then data.searchname, data.suffix = data.basename, "/" .. data.subname end if isDict then local edition = "" data.prefix = data.rootname .. "/" if data.prefix ~= pagename then edition = pagename:match ( "^" .. escapePattern ( data.prefix ) .. "([^/]+)/" ) or "" if edition == "ДО" or edition == "ВТ" then data.prefix = data.prefix .. edition .. "/" end data.searchname = mw.ustring.gsub ( data.searchname, "^" .. escapePattern ( data.prefix ), "" ) if data.prefix ~= "БСЭ1/" then -- временное решение для статей с / в названии data.searchname = mw.ustring.gsub ( data.searchname, "/.+$", "" ) end end data.beforetext = '<div class="' .. (data.p.style or 'text') .. '" style="max-width:100%"><div class="innertext">' end if data.p.style then data.beforetext = '<div class="' .. data.p.style .. '">' if is(data.p.beforeright) then data.beforetext = '<div style="float:right;">' .. data.p.beforeright .. '</div>' .. data.beforetext end if is(data.p.beforeleft) then data.beforetext = '<div style="float:left;">' .. data.p.beforeleft .. '</div>' .. data.beforetext end if is(data.p.beforesimple) then data.beforetext = data.p.beforesimple .. data.beforetext end end local ignoreLang = { [""] = true, ["ru"] = true, ["rus"] = true, ["ru-old"] = true, ["русский"] = true } if not ignoreLang[data.p.origLang] then isTrans = true end isData = data.p.index or data.p.cycle or data.p.collection or data.p.created or data.p.published or ( data.p.source and not data.p.suppress_source ) end -- Getting functions ------------------------------------------------------------------------------- --[[ function getDataMain () ----------------------------------------------------------------------- Получение ссылок и пр. данных для обычного режима Отексте --------------------------------------------------------------------------------------------------]] function getDataMain () local toc = data.p.toc -- параметр ОГЛАВЛЕНИЕ local tmpname, tmpsuffix = data.searchname, data.suffix local tocnum = tonumber ( toc ) if tocnum then -- ОГЛАВЛЕНИЕ = число -- использовать BASEPAGENAME вместо PAGENAME для навигации if tocnum > 20 then -- подняться на уровень выше и остаться там data.searchname, data.suffix = data.basename, "" tocnum = tocnum - 20 elseif tocnum > 10 then -- получить данные и вернуться к SUBPAGENAME data.searchname, data.suffix = data.basename, "/" .. data.subname tocnum = tocnum - 10 end -- если ОГЛАВЛЕНИЕ = 5 или 6 не на подстранице if (tocnum == 5 and data.basename == data.pagename) or (tocnum == 6 and data.rootname == data.pagename) then tocnum = 0 end -- число в оглавление if tocnum == 0 then toc = {} if data.p.cycle then table.insert ( toc, data.p.cycle ) end if data.p.collection then table.insert ( toc, data.p.collection ) end if data.p.index then table.insert ( toc, data.p.index ) end table.insert ( toc, data.p.author ) else toc = { data.toc_choice[tocnum] } end elseif toc then -- ОГЛАВЛЕНИЕ = строка toc = { toc } end if toc then -- получение данных data.toc = toc getLinks(); mw.logObject(data.curr,"data.curr") -- если не указан параметр НАЗВАНИЕ, использовать текст из оглавления if data.curr[1] then data.title = data.title or data.curr[1] elseif is( data.tempcat ) then addCat( data.tempcat ) end end data.backlink = is( data.backlink ) or data.p.backlink -- if all else fails data.forelink = is( data.forelink ) or data.p.forelink data.searchname, data.suffix = tmpname, tmpsuffix end --[[ function getDataExt ( frame ) ----------------------------------------------------------------- Получение ссылок и пр. данных для словарных статей --------------------------------------------------------------------------------------------------]] function getDataExt ( frame ) -- инициализация local name = data.searchname local dictname = data.f.dict; local dict if dictname == "generic" then dictname = data.rootname end -- префикс local dictpath = "Модуль:Отексте/" .. dictname if mw.title.new ( dictpath ) .exists then dict = mw.loadData ( dictpath ) else addCat ( s.moduleNotFound ) return end local function split (str, sep) return mw.text.split (str or "", sep or "/") end -- Общие данные ----------------------------------------------------------------------------------- data.p.noauthor = dict.noauthor[isPRS] data.override = dict.override[isPRS] -- категории и ключ сортировки local catpath = dict[data.rootname] or dict local maincat = catpath.maincat or dict.maincat local alphacat = catpath.alphacat or dict.alphacat if maincat then addCat ( maincat[isPRS] ) end if alphacat then local alpha = mw.ustring.upper ( mw.ustring.match ( data.p.category or name, "%w" ) ) if dict.alphacorrect then alpha = dict.alphacorrect[alpha] or alpha end -- коррекция алфавитной категории addCat ( alphacat[isPRS] .. alpha .. "]]" ) end if data.p.wp then local wp = mw.ustring.lower ( data.p.wp ); local iw = string.match ( wp, "^:?(%w%w):" ) or "" if dictname == 'РБС' then -- эту энциклопедию в общую категорию, [[ВТ:КУ#Служебные категории РБС]] addCat ( string.format ( s.cat.wpLink[""], dictname ) ) else addCat ( string.format ( s.cat.wpLink[iw] or s.cat.wpLink[""], dictname ) ) end end if data.p.ws then local ws = mw.ustring.lower ( data.p.ws ); local iw = toBool ( string.find ( ws, "^:" ) ) if iw then iw = string.match ( ws, "^:(%w%w):" ) or string.match ( ws, "^:(категория):" ) or iw end if dictname == 'РБС' then -- эту энциклопедию в общую категорию, [[ВТ:КУ#Служебные категории РБС]] addCat ( string.format ( s.cat.wsLink[false], dictname ) ) else addCat ( string.format ( s.cat.wsLink[iw] or s.cat.wsLink[true], dictname ) ) end end if data.p.commons then addCat ( string.format ( s.cat.cLink, dictname ) ) end data.sortKey = frame:preprocess ( "{{DEFAULTSORT:" .. mw.ustring.upper ( mw.ustring.gsub ( data.p.sortKey or name, "[%s%p]", "" ) ) .. "}}" ) -- поиск по ВП data.wpsearch = dict.wpsearch if data.wpsearch then frame.args.search = data.searchname else frame.args.search = "" end -- ссылка на словник local other = "[[Файл:Brockhaus Lexikon.jpg|20px|link=]] [[" .. ( dict.wordlist[isPRS] or dict.wordlist.default ) .. "|" .. s.wordlist[isPRS] .. "]]" data.beforetext = dict.beforetext or data.beforetext -- Источник --------------------------------------------------------------------------------------- local itemdata = {}; local _body if dict.type == "split" then _body = { dict[data.rootname] } elseif dict.type == "join" then _body = dict.body; isTypeJoin = true; else _body = { dict } end -- Заголовок в двух орфографиях ------------------------------------------------------------------- if dict.jointitles == 2 then data.doubletitle = true end -- Получение данных ------------------------------------------------------------------------------- for _, v in ipairs ( _body ) do if data.curr[1] then data.curr = {} end -- для повторного использования data.backlink = ""; data.forelink = "" -- " -- ссылка на словник -------------------------------------------------- local function link2wl(t) local n = t:match ( "/([^/]+)$" ); local title = "раздел " .. n; if v.wordlists[n] then title = v.wordlists[n][isPRS] or title end return "[[" .. ( v.listroot[isPRS] or v.listroot.default ) .. n .. "|" .. title .. "]]", n end -- отбор разделов для поиска ------------------------------------------- local toc = {}; local _list = v.listnum -- нормализация name для поиска: удаление диакритик (кроме й) и лишней пунктуации local _name = mw.ustring.gsub ( name, '[Йй]', 'и~' ) _name = mw.ustring.toNFD ( _name ) _name = mw.ustring.gsub ( mw.ustring.gsub ( _name, "[^%w,(~]", "" ), "^%p", "" ) _name = mw.ustring.gsub ( _name, 'и~', 'й' ) local lang = mw.language.new (mw.language.getContentLanguage().code) _name = lang:ucfirst ( lang:lc (_name) ); mw.logObject(_name,"_name") for i, _ in ipairs ( _list ) do if _name >= _list[i][1] and ( _list[i+1] == nil or _name < _list[i+1][1] ) then for _, w in ipairs ( _list[i][2] ) do table.insert ( toc, v.listroot.default .. w ) end break end end mw.logObject(toc,"toc") if toc[1] then -- непустой список словников data.toc = toc; getLinks() local _toc, _data = data.toc_curr, data.curr if _data[1] then -- страница в словниках найдена data.title = data.title or _data[1] -- название статьи local function addItemRow (h, s, a) local r = { body = v, title = _data[1], hard = { raw = h }, soft = { raw = s }, backlink = data.backlink, forelink = data.forelink, scans = {}, } r.list, r.num = link2wl ( _toc ) if v.subtitle then r.subtitle = is(v.subtitle[isPRS]) end if a then r.appendshort = dict.appendshort end table.insert ( itemdata, r ) end addItemRow (_data[2], _data[3]) if is( _data[4] ) then addItemRow (_data[4], _data[5], true) end if is( _data[6] ) then addItemRow (_data[6], _data[7], true) end else data.title = data.title or data.searchname -- название статьи --table.insert ( itemdata, { body = v, list = link2wl ( _toc ) } ) end end end if #itemdata == 0 and is( data.tempcat ) then addCat( data.tempcat ) end -- Обработка данных ------------------------------------------------------------------------------ for i, v in ipairs ( itemdata ) do local d = v.body addCat ( d.cat ); if not is( v.hard.raw ) then addCat ( d.catnopage ) end -- номера страниц -- mw.log("v.hard.raw:",mw.dumpObject(v.hard.raw), "v.soft.raw:",mw.dumpObject(v.soft.raw)) v.hard.s, v.pagination, v.volume = unpack ( split ( v.hard.raw ) ) v.soft.from, v.soft.to, v.soft.skip = unpack ( split ( v.soft.raw ) ) v.hard.from = tonumber ( v.hard.s:match ( "%d+" ) ) or 0 v.hard.to = tonumber ( v.hard.s:match ( "[-—]%s*(%d+)" ) ) or v.hard.from v.soft.from = tonumber ( v.soft.from ) -- строковое значение в число v.pagination = is ( v.pagination ) if v.volume then v.appendshort = false end -- номер тома if not is( v.volume ) then if d.splitvolume then v.volume = v.num:gsub ( "%-%d+$", "" ); v.scanvol = v.volume; else local volTable = d.wl2volume or d.page2volume if volTable then -- если есть таблица соответствия словник/том local x if not d.wl2volume and d.page2volume then x = v.hard.from else x = v.num end for _, w in ipairs ( volTable ) do local _from, _to = w.from, w.to if type ( x ) == "number" then _from, _to = tonumber ( _from ), tonumber ( _to ) end if x >= _from and x <= _to then v.volume = w.volume; v.scanvol = w.scan or v.volume; break end end else v.volume = v.num; v.scanvol = v.num -- нет таблицы, словник = том end end end -- ссылки на сканы и индекс local _volume = d.volumes[v.volume] or {}; addCat ( _volume.cat ) --local us; if _volume.usesource then us = _volume.usesource end -- us = 2 local offsets = _volume.offsets if v.pagination and type(_volume.paginations) == "table" then offsets = _volume.paginations[v.pagination].offsets end local base_factor = _volume.factor or d.volumes.factor or d.factor or dict.factor or 1 local base_correction = _volume.correction or d.volumes.correction or d.correction or dict.correction or 0 local factor, correction = base_factor, base_correction mw.logObject(v.hard,"v.hard") local isScanPages = toBool ( _volume.scanpages or dict.scanpages ) local isManual = toBool ( v.soft.from and not _volume.sources ) local isSources = toBool ( _volume.sources or _volume.map ) local isOffsets = toBool ( offsets ) local _scan = _volume.linkdata or _volume.scan or {}; mw.logObject(_scan,"_scan") local function fillScanData ( scan ) local sc = scan or _scan; mw.logObject(sc,"sc") local id, pid, title = sc[1], sc[2], sc[3] if type(title) ~= "string" then title = s.scan[isPRS] end local pattern = type (dict.scanpat) == "table" and dict.scanpat[pid] local isLink = id and pattern return id, title, pattern, isLink end local _id, _title, _pattern, isLink = fillScanData () local _index, _linkdata, _scan4index if isScanPages then -- постраничные сканы v.soft.from = v.hard.from; v.soft.to = v.hard.to _id, _title, _pattern, isLink = fillScanData(); mw.logObject(_scan,"_scan #1") if isLink and v.soft.from then local link = string.format ( _pattern, _id, v.soft.from, _title ) local filename = mw.ustring.match ( link, "%[%[:?([^%[%]|]+)|.+%]%]" ); mw.logObject(filename,"filename") if is( filename ) and mw.title.new(filename).file.exists then table.insert ( v.scans, link ) end end elseif isManual then -- номера страниц скана берутся из словника v.soft.to = tonumber ( v.soft.to ) or v.soft.from _id, _title, _pattern, isLink = fillScanData(); mw.logObject(_scan,"_scan #2") if isLink then table.insert ( v.scans, string.format ( _pattern, _id, v.soft.from, _title ) ) end elseif isSources then local _sources = _volume.sources or { _volume } mw.logObject(_sources,"_sources") if _sources then for i, w in ipairs(_sources) do local map = w.map if v.pagination and type(w.paginations) == "table" then map = w.paginations[v.pagination].map end factor = w.factor or base_factor correction = w.correction or base_correction if ( w.linkdata or w.index or w.scan ) and map then local map_len = 0; for i in ipairs ( map ) do map_len = i end local pagenum, hstart, sstart for j = map_len, 1, -1 do x = map[j] if v.hard.from >= x[1] then hstart = x[1] sstart = x[2] factor = x.factor or factor correction = x.correction or correction break end end if hstart and sstart and sstart > 0 then mw.logObject(hstart,"hstart"); mw.logObject(sstart,"sstart") pagenum = sstart + math.floor ((v.hard.from - hstart + correction) / factor) -- расчёт номера страницы скана if (w.linkdata or w.scan) and pagenum then _id, _title, _pattern, isLink = fillScanData( w.linkdata or w.scan ) mw.logObject(_scan,"_scan #3") if isLink then table.insert ( v.scans, string.format ( _pattern, _id, pagenum, _title ) ) end end if (w.index or w.scan) and not _index then v.soft.from = pagenum v.soft.to = sstart + math.floor ((v.hard.to - hstart + correction) / factor) _index = w.index; _linkdata = w.linkdata or w.scan; _scan4index = false end else v.soft.from = nil; v.soft.to = nil end end factor = base_factor; correction = base_correction end end elseif isOffsets then local offset = 0 for _, w in ipairs ( offsets ) do if v.hard.from >= w.from and v.hard.from <= w.to then offset = w.offset factor = w.factor or base_factor correction = w.correction or base_correction scansource = w.scansource break end end if offset then v.soft.from = math.ceil (( v.hard.from + correction ) / factor ) + offset if v.soft.from == 0 then v.soft.from = nil end v.soft.to = v.soft.to or math.ceil (( v.hard.to + correction ) / factor ) + offset else v.soft.from = nil; v.soft.to = nil end local _s = _scan; if tonumber ( scansource ) then _s = _scan[scansource] or _s end; mw.logObject(_s,"_s") _id, _title, _pattern, isLink = fillScanData( _s ) mw.logObject(_scan,"_scan #4"); mw.logObject(isLink,"isLink"); mw.logObject(_id,"_id"); mw.logObject(_pattern,"_pattern") if isLink and v.soft.from then table.insert ( v.scans, string.format ( _pattern, _id, v.soft.from, _title ) ) end end mw.logObject(offset, "offset"); mw.logObject(v.soft.from, "v.soft.from"); mw.logObject(v.soft.to, "v.soft.to") -- префикс ссылок на скан local scantitle = ""; local b = _volume.short or _volume; mw.logObject(v.volume,"v.volume") if v.appendshort then scantitle = v.hard.s else if b[isPRS] then scantitle = ( b.prefix or "" ) .. b[isPRS] .. ( b.suffix or "" ) elseif is( v.volume ) then scantitle = " т. " .. ( tonumber (v.volume) or v.volume ) end if is( v.hard.s ) then scantitle = scantitle .. ", " .. ( d.rnum or dict.rnum ) .. v.hard.s end end -- ссылка на индекс local indexfile if dict.indexpat then local id, pattern _index = _index or _volume.index; _linkdata = _linkdata or _scan; _scan4index = dict.scan4index if _index then if type(_index) == "table" then id, pattern = _index[1], _index[2] or 1 elseif type(_index) == "string" then id, pattern = _index, 1 elseif type(_index) == "number" then id, pattern = "", _index elseif type(_index) == "boolean" and type(_linkdata) == "table" then id, pattern = _linkdata[1], _linkdata[2] end elseif _linkdata and _scan4index then id, pattern = _linkdata[1] or "", _linkdata[2] or 1 else id, pattern = v.scanvol, 1 end if type(dict.indexpat) == "table" then indexfile = (string.format ( dict.indexpat[pattern], id )) elseif type(dict.indexpat) == "string" then indexfile = (string.format ( dict.indexpat, id )) end mw.logObject(indexfile,"indexfile") if exists ( "Индекс:" .. indexfile ) then v.index = "[[Индекс:" .. mw.text.trim(indexfile) .. "|" .. s.index[isPRS] .. "]]" mw.logObject(v.index,"v.index #") table.insert ( v.scans, v.index ) end end v.scan = scantitle mw.logObject(v.scans,"v.scans") if #v.scans > 0 then v.scan = v.scan .. " ( <span class=plainlinks>" .. table.concat ( v.scans, " · " ) .. "</span> )" end -- текст статьи из индекса if indexfile then if ( dictname == "ЭСБЕ" ) and isPRS then if data.p.pages == "нет" then data.p.pages = false else data.p.pages = true end -- ЭСБЕ/ДО end if ( data.p.pages or dict.transclude ) and is( v.soft.from ) then local _text; local _section = data.p.section or name if dict.section_mod then _section = _section .. (dict.section_mod[isPRS] or "") end;mw.logObject(_section,"_section") if dict.transclude_onlysection then _text = frame:extensionTag ( "pages", "", { index = indexfile, from = v.soft.from, to = v.soft.to or v.soft.from, exclude = v.soft.skip or "", onlysection = _section, } ) else _text = frame:extensionTag ( "pages", "", { index = indexfile, from = v.soft.from, to = v.soft.to or v.soft.from, exclude = v.soft.skip or "", fromsection = _section, tosection = _section, } ) end if is( _text ) then addToPage ( _text ); mw.logObject(_text,"_text") else addCat ( s.cat.noText ) end end end end -- Дообработка ------------------------------------------------------------------------------------ local mainlist if #itemdata > 1 and isTypeJoin then -- вынос доп. навигации в Subnav local subnavs = {} local main, to, step = 1, #itemdata, 1; if dict.reversenav then main, to, step = #itemdata, 1, -1 end local from = main + step for i = from, to, step do if itemdata[i].list ~= itemdata[i-step].list and not itemdata[i].body.skipnav then if is( itemdata[i].subtitle ) then itemdata[i].list = mw.ustring.gsub ( itemdata[i].list, "|[^%[%]]+%]%]", "|" .. itemdata[i].subtitle .. "]]" ) end table.insert ( subnavs, { itemdata[i].backlink, itemdata[i].forelink, itemdata[i].list } ) end end data.subnavs = subnavs -- исправление осн. навигации mainlist = itemdata[main].list data.backlink = itemdata[main].backlink; data.forelink = itemdata[main].forelink -- объединение названий if dict.jointitles == 1 then local titles = {}; local hash = {}; for i = main, to, step do local t = itemdata[i].title if is( t ) and not hash[t] then table.insert ( titles, t ); hash[t] = true end end if #titles > 0 then data.title = table.concat ( titles, " / " ) end end elseif #itemdata > 0 then data.backlink = itemdata[1].backlink; data.forelink = itemdata[1].forelink end if #itemdata > 0 then -- убираем повторы индексов for i = 2, #itemdata do for j = 1, i-1 do if itemdata[i].index == itemdata[j].index then itemdata[i].index = "" end end end -- добавляем ссылку на первый словник other = other .. ": " .. ( mainlist or itemdata[1].list ) .. ". " else other = other .. ". " end local sources = {} -- сборка ссылок на источники for i, v in ipairs ( itemdata ) do local src = itemdata[i].scan or "" -- if is( itemdata[i].index ) then src = src .. " (" .. itemdata[i].index .. ")" end if is( src ) then table.insert ( sources, src ) end end if #sources > 0 then other = other .. "'''" .. s.source[isPRS] .. "''' " .. table.concat ( sources, "; " ) end data.other = other .. ( getString ( dict.other ) ) end --[[ function getSubNav () ------------------------------------------------------------------------- Дополнительная навигация для верхнего колонтитула --------------------------------------------------------------------------------------------------]] function getSubNav () if data.subnavs and #data.subnavs > 0 then return data.subnavs end -- уже есть local subnav, subnavs = data.p.subnav, {} if subnav then if subnav:find ( "headertemplate" ) then -- есть шаблон Sub-nav for m in subnav:gmatch ( "<table[^>]*>(.-)</table>" ) do local z = {} for j in m:gmatch ( "<td[^>]*>(.-)</td>" ) do table.insert ( z, j ) end z[2], z[3] = z[3], z[2] table.insert ( subnavs, z ) end else -- заморозка значений local b, f = data.backlink, data.forelink; data.backlink = ""; data.forelink = ""; local tmp1, tmp2, tmp3 = data.searchname, data.prefix, data.suffix; if isDict then data.searchname, data.prefix = data.pagename, "" end; local _toc = mw.text.split ( subnav, "%s*~%s*" ) for i, v in ipairs( _toc ) do local tocnum = tonumber ( v ) if tocnum then if tocnum > 20 then -- подняться на уровень выше и остаться там data.searchname, data.suffix = data.basename, "" tocnum = tocnum - 20 elseif tocnum > 10 then -- получить данные и вернуться к SUBPAGENAME data.searchname, data.suffix = data.basename, "/" .. data.subname tocnum = tocnum - 10 end v = data.toc_choice[tocnum] end if is( v ) then data.toc = { v }; getLinks(); if #data.curr > 0 then table.insert ( subnavs, { data.backlink, data.forelink, linkify ( v ) } ) end mw.logObject(data.curr,"data.curr"); mw.logObject(subnavs,"subnavs") end end data.backlink = b; data.forelink = f; data.searchname, data.prefix, data.suffix = tmp1, tmp2, tmp3; end end data.subnavs = subnavs return subnavs end --[[ function getFooter () ------------------------------------------------------------------------- Навигация для нижнего колонтитула --------------------------------------------------------------------------------------------------]] function getFooter () local footer = mw.clone ( data.subnavs ) -- Для подстраниц local parents = {} local temp, temp1, x if isSub then local parts = mw.text.split ( data.basename, "/" ) for i, v in ipairs ( parts ) do if temp then temp = temp .. "/" .. v else temp = v end if temp1 then temp1 = temp1 .. "/" .. v else temp1 = v end local x = mw.title.new ( temp ) if x.exists then table.insert ( parents, "[[" .. temp .. "|" .. temp1 .. "]]" ) temp1 = nil end end if #parents > 0 then temp = table.concat ( parents, " : " ) else temp = nil end end local tocnum = tonumber ( data.p.toc ) local _toc; if tocnum then _toc = data.toc_choice[tocnum] end local middlelink = data.override or temp or _toc or toLink(data.p.cycle) or toLink(data.p.collection) or toLink(data.p.index) or toLink(linkify(data.p.author)) or "[[#top|Наверх]]" middlelink = linkify ( middlelink ) table.insert ( footer, 1, { data.backlink or "", data.forelink or "", middlelink } ) return footer, true end --[[ function getLinks () -------------------------------------------------------------------------- Формирует ссылки на основе данных getLinkData --------------------------------------------------------------------------------------------------]] function getLinks () local prefix, suffix = data.prefix, data.suffix local link_title, toc_curr for i, v in ipairs ( data.toc ) do data.tempcat = "" -- очистка временной категории -- если используется отдельное оглавление для /ДО if mw.ustring.match ( v, "/ДО$" ) and not isNewEdition then data.searchname = data.searchname .. "/ДО" suffix = "" end data.toc_curr = v getLinkData () if is( data.curr[1] ) then break end end if is( data.prev[1] ) then link_title = is( data.prev[2] ) or is( data.prev[1] ) if isPRS then link_title = is( data.prev[3] ) or link_title end data.backlink = "[[" .. prefix .. data.prev[1] .. suffix .. "|" .. link_title .. "]]" else data.backlink = "" end if is( data.next[1] ) then link_title = is( data.next[2] ) or is( data.next[1] ) if isPRS then link_title = is( data.next[3] ) or link_title end data.forelink = "[[" .. prefix .. data.next[1] .. suffix .. "|" .. link_title .. "]]" else data.forelink = "" end local link_curr = {} if is( data.curr[1] ) then link_title = is( data.curr[2] ) or is( data.curr[1] ) if data.doubletitle and is( data.curr[3] ) then link_title = link_title .. " / " .. data.curr[3] elseif isPRS then link_title = is( data.curr[3] ) or link_title end link_curr[1] = link_title for i = 4, #data.curr do table.insert ( link_curr, data.curr[i] ) end end data.curr = link_curr --addCat ( data.tempcat ) end --[[ function getLinkData () ----------------------------------------------------------------------- Parses data.toc for link to given data.pagename Returns link data about current, previous and next pages --------------------------------------------------------------------------------------------------]] function getLinkData () local name, toc, prefix = data.searchname, data.toc_curr, data.prefix local curr, prev, next = {}, {}, {} -- для сбора данных data.curr, data.prev, data.next = curr, prev, next -- очистка if not is( toc ) then data.tempcat = s.cat.indexNone return end if type ( toc ) ~= "string" then data.tempcat = s.cat.indexWrongType .. type ( toc ) .. "]]" return end toc = toc:match ( "%[%[([^%[%]|#]+)[%]|#]" ) or toc -- очистка названия оглавления if name == toc then return end -- имя страницы = имени оглавления -- проверка корректности имени оглавления local title = mw.title.new ( toc ) if not title then data.tempcat = s.cat.indexWrongName return end -- проверка на редирект if title.isRedirect then title = title.redirectTarget end x = title:getContent();mw.logObject(title.fullText,"title.fullText") -- проверка наличия страницы оглавления if not x then data.tempcat = s.cat.indexNotFound return end -- Подстановка переменных x = x:gsub ( "{{PAGENAME}}", title.text ) x = x:gsub ( "{{НАЗВАНИЕ_СТРАНИЦЫ}}", title.text ) if toc:find( "Малый энциклопедический словарь Брокгауза и Ефрона" ) and prefix == "МЭСБЕ/" then x = x:gsub ( "%[%[[^/]+/([^%[%]]+)%]%] *''([0-9—]+)''", "{{Статья в словнике|%1|%2|}}" ) x = x:gsub ( "%[%[[^/]+/([^%[%]]+)%]%]", "{{Статья в словнике|%1||}}" ) mw.logObject(x,"x") end -- Определяем шаблон, используемый в словнике local pattern, template for i, v in ipairs ( data.templates ) do template = mw.ustring.match ( x, "{{%s*(" .. v .. ")%s*|" ) if template then pattern = v break end end local pattern1, pattern2, pattern3, pattern4 if template then x = mw.ustring.gsub ( x, "%s*|%s*", "|" ) pattern1 = "{{%s*" .. pattern .. "%s*|%s*(" .. escapePattern( name ) .. "%s*|[^{}]+)%s*}}" pattern2 = "{{%s*" .. pattern .. "%s*|%s*(" .. escapePattern( name ) .. ")%s*}}" pattern3 = "{{%s*" .. pattern .. "%s*|%s*([^{}]+)%s*}}" pattern4 = "{{%s*Статья в другом словнике%s*|%s*([^{}]+)%s*}}" else -- маркер-граница списка (в виде шаблона) x = x:gsub("{{Начало списка в оглавлении}}", "[[Викитека:Граница списка в оглавлении]]") x = x:gsub("{{Конец списка в оглавлении}}", "[[Викитека:Граница списка в оглавлении]]") -- лишние секции и заголовки x = x:gsub ( "\n== *См%. также *==.*", "" ) x = x:gsub ( "\n== *Примечания *==.*", "" ) x = x:gsub ( "\n===?=?=?[^=\n]+===?=?=?", "" ) -- м.б. ссылки в заголовках -- Шаблон {{2О}} в ссылку x = x:gsub ( "{{lang|[^|]+|([^{}]+)}}", "%1" ) x = mw.ustring.gsub ( x, "{{%s*2[ОO]%s*|([^{}]+)}}", "[[%1]]" ) -- Убираем лишние фигурные скобки перед очисткой шаблонов x = x:gsub ( "\n{|", "\n" ) x = x:gsub ( "\n|}", "\n" ) x = mw.ustring.gsub ( x, "{{%s*[Oo]ncolor%s*|", "" ) x = mw.ustring.gsub ( x, "{{%s*[Dd]otted TOC", "" ) x = mw.ustring.gsub ( x, "{{%s*[Hh]eading%s*|", "" ) x = x:gsub ( "{{ВАР2?", "" ) x = x:gsub ( "{{:MediaWiki:Proofreadpage.index.template", "" ) x = x:gsub ( "{{%s*[Rr]azr2?%s*|", "" ) -- Удаляем оставшиеся шаблоны и пр. x = x:gsub ( "%b{}", "" ) x = x:gsub ( "%[%[[:#][^%[%]]-%]%]", "" ) x = x:gsub ( "%[%[[^%[%]|#]+#[^%[%]]+%]%]", "" ) x = x:gsub ( "%[%[[%a-]+: *[^%[%]]-%]%]", "" ) -- Википедия и пр. x = x:gsub ( "%[%[Категория: *[^%[%]]-%]%]", "" ) x = x:gsub ( "%[%[Файл: *[^%[%]]-%]%]", "" ) x = x:gsub ( "%[%[Изображение: *[^%[%]]-%]%]", "" ) -- Развертка имен подстраниц x = x:gsub ( "%[%[/", "[[" .. toc .. "/" ) if is( prefix ) then x = x:gsub ( "%[%[ *" .. prefix, "[[" ) end pattern1 = "%[%[ *(" .. escapePattern( name ) .. " *|[^%[%]]*)%]%]" pattern2 = "%[%[ *(" .. escapePattern( name ) .. ") *%]%]" pattern3 = "%[%[ *([^%[%]]+) *%]%]" end x = mw.ustring.gsub ( x, "[%s_]+", " " ) mw.logObject(pattern1,"pattern1") mw.logObject(pattern2,"pattern2") mw.logObject(pattern3,"pattern3") mw.logObject(pattern4,"pattern4") local offset1, offset2, foundstr = mw.ustring.find ( x, pattern1 ) if not offset1 then offset1, offset2, foundstr = mw.ustring.find ( x, pattern2 ) end if (not offset1) and data.p.fallback then pattern1 = "%[%[ *(" .. escapePattern( data.p.fallback ) .. " *|[^%[%]]*)%]%]" pattern2 = "%[%[ *(" .. escapePattern( data.p.fallback ) .. ") *%]%]" offset1, offset2, foundstr = mw.ustring.find ( x, pattern1 ) if not offset1 then offset1, offset2, foundstr = mw.ustring.find ( x, pattern2 ) end end if not offset1 then data.tempcat = s.cat.pageNotFound; return end local x1 = mw.ustring.sub ( x, 1, offset1 ) local foundstr1 = mw.ustring.match ( x1, ".+" .. pattern3 ) if not foundstr1 and pattern4 then foundstr1 = mw.ustring.match ( x1, ".+" .. pattern4 ) end local x2 = mw.ustring.sub ( x, offset2 ) local foundstr2 = mw.ustring.match ( x2, pattern3 ) if not foundstr2 and pattern4 then foundstr2 = mw.ustring.match ( x2, pattern4 ) end if foundstr then curr = mw.text.split ( foundstr, " *| *" ) for i = #curr, 1, -1 do if curr[i]:find ( "=" ) then table.remove ( curr, i ) end end mw.logObject(curr,"curr") if template then table.insert ( curr, 1, name ) else curr[1] = name end end if foundstr1 and foundstr1 ~= "Викитека:Граница списка в оглавлении" then prev = mw.text.split ( foundstr1, " *| *" ) if template then table.insert ( prev, 1, prev[1] ) end end if foundstr2 and foundstr2 ~= "Викитека:Граница списка в оглавлении" then next = mw.text.split ( foundstr2, " *| *" ) if template then table.insert ( next, 1, next[1] ) end end data.curr, data.prev, data.next = curr, prev, next end --[[ function p.getlinkdata( frame ) --------------------------------------------------------------- Вспомогательная функция для вызова getLinkData из фрейма (тест) --------------------------------------------------------------------------------------------------]] function p.getlinkdata( frame ) local links = getLinkData ( frame.args.name, frame.args.toc ) local result = {} for i, v in pairs ( links ) do table.insert( result, "* " .. i .. ": " .. table.concat ( v, " --- " ) ) end return table.concat( result, "\n" ) end -- Rendering functions ----------------------------------------------------------------------------- --[[ function renderQuality () --------------------------------------------------------------------- КАЧЕСТВО --------------------------------------------------------------------------------------------------]] function renderQuality () local quality = s.q[data.p.quality] or "00%" if is( quality ) then addCat ( "[[Категория:" .. quality .. "]]" ) -- render local result = mw.html.create( "div" ) result :addClass ( "ws-noexport" ):css ( "display", "none" ) :tag ( "span" ):attr ( "id", "textquality" ):addClass ( quality ) return tostring ( result ) else return "" end end --[[ function renderTitle () ----------------------------------------------------------------------- НАЗВАНИЕ, ПОДЗАГОЛОВОК --------------------------------------------------------------------------------------------------]] function renderTitle () local title = is( data.title ) or s.notitle[isPRS] local sub, part, partsub = data.p.sub, data.p.part, data.p.partsub if sub then sub = " : " .. sub; addCat(s.cat.pageWithSub) else sub = "" end if part then if sub and partsub then sub = "" end -- ЧАСТЬ + ПОДЗАГОЛОВОКЧАСТИ - ПОДЗАГОЛОВОК end -- render local result = mw.html.create() result :tag ( "span" ):attr ( "id", "header_title_text" ):css ( "font-weight", "bold" ) :tag ( "span" ):attr ( "id", "ws-title" ) :wikitext ( title ) :done() :tag ( "span" ):attr ( "id", "ws-subtitle" ) :wikitext ( sub ) return tostring ( result ) end --[[ function renderSub () ----------------------------------------------------------------- ЧАСТЬ, ПОДЗАГОЛОВОКЧАСТИ --------------------------------------------------------------------------------------------------]] function renderSub () local part, partsub = data.p.part, data.p.partsub local joiner = " — "; if flag.emPart then joiner = "<br>" end if not part then return "" end if partsub then partsub = " : " .. partsub; addCat(s.cat.pageWithSub) else partsub = "" end -- render local result = mw.html.create() result :tag ( "span" ):attr ( "id", "header_section_text" ) :wikitext ( joiner ) :tag ( "span" ):attr ( "id", "ws-chapter" ) :wikitext ( part ) :done() :wikitext ( partsub ) return tostring ( result ) end --[[ function renderAuthorTrans () ----------------------------------------------------------------- АВТОР(ы), ПЕРЕВОДЧИК --------------------------------------------------------------------------------------------------]] function renderAuthorTrans () local author, translator, translatortext local open_bracket, close_bracket -- Author if flag.emPart then open_bracket = " (" close_bracket = ")" if data.p.noauthor then author = "" elseif data.p.authors then author = data.p.authors elseif data.p.author then author = linkify ( data.p.author ) else author = "" end else if data.p.noauthor then author = is( data.p.noauthor ) or "" elseif data.p.authors then author = "авторы: " .. data.p.authors elseif data.p.author then author = s.author[isPRS] .. linkify ( data.p.author ) else author = s.unknown_author[isPRS] end end isAuthor = toBool ( is( author ) ) -- Translator if isTrans then translator = data.p.translator if translator == nil then if flag.emPart then translatortext = "" else translatortext = s.unknown_trans[isAuthor][isPRS] end addCat ( s.cat.unknownTranslator ) elseif translator == "нет" then translatortext, translator = "", nil elseif flag.emPart then translatortext = "пер. "; if isAuthor then translatortext = ", пер. " end else translatortext = s.trans[isAuthor] end end if flag.emPart and ( isAuthor or is( translator ) ) then open_bracket, close_bracket = "(", ")" else open_bracket, close_bracket = "", "" end -- render local result = mw.html.create() if flag.emPart then result:wikitext( " " ) elseif isAuthor or isTrans then result:tag( "br" ) end local header_author_text = result:tag ( "span" ):attr ( "id", "header_author_text" ) if not isDict then header_author_text:css ( "font-style", "italic" ) end header_author_text:wikitext ( open_bracket ) :tag ( "span" ):attr ( "id", "ws-author" ) :wikitext ( author ) if isTrans then header_author_text:wikitext ( translatortext ) end if is( translator ) then header_author_text :tag ( "span" ):attr ( "id", "ws-translator" ) :wikitext ( linkify ( translator ) ) end header_author_text:wikitext ( close_bracket ) return tostring ( result ) end --[[ function renderNotes ( frame ) ---------------------------------------------------------------- ЯЗЫКОРИГИНАЛА, СОДЕРЖАНИЕ, ИЗЦИКЛА, ИЗСБОРНИКА, ДАТАСОЗДАНИЯ, ДАТАПУБЛИКАЦИИ, ИСТОЧНИК и ДРУГОЕ --------------------------------------------------------------------------------------------------]] function renderNotes ( frame ) -- Languages local ol, os, ot, od, oc = data.p.origLang, data.p.origSub, data.p.origTitle, data.p.origPublished, data.p.origCreated local orig_str = "" if isTrans then local langs = mw.loadData('Модуль:Отексте/transl-lang') if not langs[ol] then ol = 'un' end if ot then if ol == 'un' then lang_str = '<span id="ws-original_lang">' .. langs[ol].abbr .. '</span>' .. ',' else lang_str = '<span id="ws-original_lang" data-langcode="' .. ol .. '">' .. langs[ol].abbr .. '</span>' end if os then subtitle_str = ' : <span id="ws-original_subtitle">' .. os .. '</span>' addCat(s.cat.pageWithSub) else subtitle_str = '' end title_str = '<span id="ws-original_title">' .. ot .. '</span>' .. subtitle_str orig_str = orig_str .. ' ' .. lang_str .. " ''" .. title_str .. "''" else orig_str = langs[ol][isPRS] end if od and oc then ocd_str = ', созд.: ' .. '<span id="ws-original_created">' .. oc .. '</span>' .. ', опубл: ' .. '<span id="ws-original_published">' .. od .. '</span>' elseif oc then ocd_str = ', созд.: ' .. '<span id="ws-original_created">' .. oc .. '</span>' elseif od then ocd_str = ', опубл.: <span id="ws-original_published">' .. od .. '</span>' end if ocd_str then orig_str = 'Оригинал: ' .. orig_str .. ocd_str else orig_str = 'Оригинал: ' .. orig_str end addCat ( s.cat.transFrom .. langs[ol]["cat"] .. "]]" ) end -- Notes local created, published, source = data.p.created, data.p.published, data.p.source local coll_pre if data.p.cycle and data.p.collection then coll_pre = "сб. " else coll_pre = s.collection[isPRS] end local dates if isTrans then if created and published then dates = "Перевод созд.: " .. '<span id="ws-created">' .. created .. '</span>' .. ', опубл: ' .. '<span id="ws-published">' .. published .. '</span>' elseif created then dates = "Перевод созд.: " .. '<span id="ws-created">' .. created .. '</span>' elseif published then dates = "Перевод опубл.: " .. '<span id="ws-published">' .. published .. '</span>' end else local publ_pre if created and published then publ_pre = ", опубл.: " else publ_pre = "Опубл.: " end if created then created = s.created[isPRS] .. '<span id="ws-created">' .. created .. '</span>' else created = "" end if published then published = publ_pre .. '<span id="ws-published">'.. published .. '</span>' else published = "" end dates = created .. published end if is( dates ) then dates = dates .. ". " else dates = "" end if data.p.suppress_source then -- параметр НЕТ_ИСТОЧНИКА source = "" elseif source then source = s.source[isPRS] .. '<span class="ws-source">' .. source .. "</span> " else source = "" if data.ns == 0 and not isSub then addCat ( s.cat.noSource ) end end local other = data.other or data.p.other local lawdeprecated = data.lawdeprecated or data.p.lawdeprecated -- separators if isData or other then if is( orig_str ) then orig_str = orig_str .. ". — " end end if isData then if other then other = " • " .. other else other = "" end if lawdeprecated then other = other .. s.lawdeprecated[isPRS] .. lawdeprecated; addCat ( s.cat.lawdeprecated ) end end frame.isPRS = isPRS -- render local result = mw.html.create( "td" ) result:wikitext ( orig_str ) if data.p.index then result :wikitext ( "''См. ") :tag ( "span" ):attr ( "id", "header_contents" ) :wikitext ( linkify ( data.p.index ) ) :done() :wikitext ( ".'' " ) end if data.p.cycle then result :wikitext ( "''" .. s.cycle[isPRS] .. "«") :tag ( "span" ):attr ( "id", "header_cycle_text" ) :wikitext ( data.p.cycle ) :done() :wikitext ( "»''" ) if data.p.collection then result:wikitext ( ", " ) else result:wikitext ( ". " ) end end if data.p.collection then result :wikitext ( " ''" .. coll_pre .. "«") :tag ( "span" ):attr ( "id", "header_coll_text" ) :wikitext ( data.p.collection ) :done() :wikitext ( "»''. " ) end result:wikitext ( dates, source, other ) return tostring ( result ) end --[[ function renderEditions ( frame ) ------------------------------------------------------------- ДО/СО и Редакции --------------------------------------------------------------------------------------------------]] function renderEditions ( frame ) local pagename = data.pagename local e = data.f.editions or data.p.editions; if e == "нет" or e == "no" then return "" end local isShort = ( e == "0" ) or ( e == "short" ) or ( e == "кратко" ) local editions = "<li id='menu-editions'><b>Другие редакции</b>" -- helper functions local function binaryLink ( oldspell, newspell ) local target, linktext = oldspell, "В дореформенной орфографии" if isPRS then target, linktext = newspell, "В новой орфографии" end local result if exists (target) then result = editions .. "\n<ul><li>[[" .. target .. "|" .. linktext .. "]]</li></ul>" end return result end -- получение данных local t, root, sub if is(e) and not isShort then t, root = 1, e -- ручная ссылка из параметра РЕДАКЦИИ else t, root, _, sub = parseTitle ( pagename ) end -- обработка if t == 1 then local title = mw.title.new( root ) if not title or title.isRedirect then return end if not title.exists then -- если нет родителя, но есть пара ДО/ВТ local osp, nsp, newname if pagename:find(" %(ДО%)") then osp, nsp = pagename, pagename:gsub(" %(ДО%)"," (ВТ)",1); newname = nsp elseif pagename:find(" %(ВТ%)") then nsp, osp = pagename, pagename:gsub(" %(ВТ%)"," (ДО)",1); newname = osp else return end local newtitle = mw.title.new( newname ) if newtitle.exists then addCat(s.cat.editionTextNoList) return binaryLink ( osp, nsp ) else return end end local rootlink = "\n<li><b>[[" .. root .. "|" .. s.editionsList[isPRS] .. "]]</b></li>" local txt = title:getContent() txt = txt:gsub( "\n%s+\n", "\n" ) -- пустые строки txt = txt:gsub( "\n+", "\n" ) if txt:find( "{{ *неоднозначность *| *тип *= *перевод *}}") then mw.logObject(txt,"txt:000") txt = txt:match( "\n(%*%*.-)\n[^%*]" ); if not txt then return end txt = txt:gsub( "\n%*+", "%0 " ) mw.logObject(txt,"txt") local txtsplit = mw.text.split( txt, "\n%* [^\n]+" ) local txt1 mw.logObject(txtsplit,"txtsplit") for _, v in ipairs (txtsplit) do if v:find( escapePattern(pagename) ) then txt1 = v; break end end mw.logObject(txt1,"txt1") if txt1 then txt = txt1 else return end else txt = txt:match( '<section +begin="?list"? */>(.-)<section +end="?list"? */>' ) or txt:match( "<!%-%-[^\n]*\n(%*.-)%-%->") or txt:match( "\n(%*.-)\n==[^=].-$" ) or txt:match( "\n(%*.-)$" ) if not txt then editions = editions .. "<ul>" .. rootlink .. "</ul>" return editions end -- лишние строки txt = txt:gsub ( "\n[^%*][^\n]+", "" ) -- не список txt = txt:gsub ( "\n%*%*[^\n]+", "" ) -- 2+ уровень списка txt = txt:gsub ( "\n%*:[^\n]+", "" ) -- <dd> в списке txt = txt:gsub ( "(%[%[/?)([^%[%]|]+)(%]%])", "%1%2|%2%3" ) txt = txt:gsub ( "%[%[/", "[[" .. root .. "/" ) txt = frame:preprocess ( txt ) txt = txt:gsub ("%]%].-\n", "]]\n") -- текст после ссылок end txt = txt:gsub ( "%[%[" .. escapePattern(pagename) .. "|" .. "[^%[%]|]+%]%]", "" ) -- selflink local alttext = "" for m in txt:gmatch ( "%*[^%[%]]-(%[%[[^%[%]]+%]%])" ) do local mainlink, toclink, spell_mark = m, "", "'NS_edition'" if m:find ( "^[^|]+ %(ДО%)" ) then spell_mark = "'PRS_edition'" end if (not isShort) and sub then mainlink = m:gsub ( "|", "/" .. sub .. "|" ) toclink = m:gsub ( "|[^%[%]]+%]%]", "|(огл.)]]" ) end alttext = alttext .. "\n<li><span class=" .. spell_mark .. ">" .. mainlink .. "</span>" if is( toclink ) then alttext = alttext .. " " .. toclink end alttext = alttext .. "</li>" end if #alttext > 0 then addCat ( s.cat.editionText ) end editions = editions .. "<ul>" .. alttext .. rootlink .. "</ul></li>" return editions elseif t == 2 then return binaryLink ( root .. "/ДО/" .. sub, root .. "/ВТ/" .. sub ) elseif t == 3 then return binaryLink ( root .. "/ДО", root ) end end --[[ function renderOtherTrans ( frame ) ----------------------------------------------------------- ДРУГИЕПЕРЕВОДЫ, Альтернативные переводы и Версии --------------------------------------------------------------------------------------------------]] -- test function renderOtherTrans ( frame ) local pagename = data.pagename pagename = pagename:gsub( "/ДО$", "" ) pagename = pagename:gsub( "/[^/]+ %(ДО%)$", "" ) pagename = pagename:gsub( "/[^/]+ %(ВТ%)$", "" ) pagename = pagename:gsub( "/[^/]+ %(ВТ:Ё%)$", "" ) pagename = pagename:gsub( "/[^/]+ %(СО%)$", "" ) local txt, rootlink local title = "<b>Другие переводы</b>" local function template_parts (text) local t1 = text:match ( '<div id="otherVersions" style="display: none;">[^\n]*(\n.-)</div>' ) local t2 = text:match ( "<b>[^<>]+</b>") or title for cat in text:gmatch("(%[%[Категория:[^%[%]]+%]%])") do addCat( cat ) end return t1, t2 end local ot, template_name = data.p.other_versions, "Дубль" if data.p.other_translations then ot, template_name = data.p.other_translations, "Версии" end if not ot then return end local otp = mw.title.new ( ot ) if otp and otp.isRedirect then otp = otp.redirectTarget end mw.logObject(ot,"ot") if otp and otp.exists then txt = otp:getContent(); if not txt then return end mw.logObject(txt,"txt:1") txt = txt:match( '<section +begin="?list"? */>(.-)<section +end="?list"? */>' ) or txt:match( "\n(%*.-)\n==[^=].-$" ) or txt:match( "\n(%*.-)$" ) if not txt then return end mw.logObject(txt,"txt:2") txt = "\n" .. txt txt = txt:gsub( "\n+", "\n" ) --local suffix = ""; if isPRS then suffix = "/ДО" end txt = txt:gsub( "{{2О|([^{}|]+)|([^{}|]+)}}", "[[%1|%2]]" ) -- cyr. txt = txt:gsub( "{{2O|([^{}|]+)|([^{}|]+)}}", "[[%1|%2]]" ) -- lat. mw.logObject(txt,"txt:3") txt = txt:gsub( " *%[%[Файл:[^%[%]]+%]%] *", " " ) txt = txt:gsub( "\n[^%*][^\n]+", "" ) -- не список txt = txt:gsub( "\n%*%*[^\n]+", "" ) -- 2+ уровень списка txt = txt:gsub( "\n%*:[^\n]+", "" ) -- <dd> в списке txt = txt:gsub( "\n%* +[^%[][^\n]+", "" ) -- нет ссылки в начале txt = frame:preprocess(txt) rootlink = "\n<li><b>[[" .. ot .. "|" .. "список переводов]]</b></li>" else if ot:match("otherVersions") then mw.logObject(ot,"ot") txt, title = template_parts(ot) if not txt then return end else local template_name_alt = 'Альтернативные переводы/' .. ( data.p.origLang or 'de' ) .. '/' .. ot local ot1 if exists( 'Шаблон:' .. template_name_alt ) then ot1 = frame:expandTemplate{ title = template_name_alt }; mw.logObject(ot1,"ot1:alt") if ot1 then txt, title = template_parts(ot1) end elseif mw.title.new( ot ) then ot1 = frame:expandTemplate{ title = template_name, args = mw.text.split(ot, '~') }; mw.logObject(ot1,"ot1:plain") if ot1 then txt, title = template_parts(ot1) end end if not txt then return end end end mw.logObject(txt,"txt") txt = txt:gsub ( "\n%* -%[%[" .. escapePattern(pagename) .. "|" .. "[^%[%]|]+%]%][^\n]*", "" ) -- selflink txt = txt:gsub ( "\n%* -%[%[" .. escapePattern(pagename) .. "%]%][^\n]*", "" ) -- selflink txt = txt:gsub( "\n%* -([^ ][^\n]+)", "\n<li>%1</li>") mw.logObject(txt,"txt+") local other_trans = "<li id='menu-trans'>" .. title .. "<ul>" .. txt .. (rootlink or "") .. "</ul></li>" mw.logObject(other_trans,"other_trans") return tostring ( other_trans ) end --[[ function renderExtraNav ( frame ) ------------------------------------------------------------- Навигация-мини, другие словари, НЕОДНОЗНАЧНОСТЬ и ПРЕДУПРЕЖДЕНИЕ --------------------------------------------------------------------------------------------------]] function renderExtraNav ( frame ) -- мини-навигация по странице local innerToc if data.p.innerToc then if string.find ( data.p.innerToc, "~" ) then local n = 0; data.p.innerToc = string.gsub ( data.p.innerToc, "%s*~%s*", "~" ) data.p.innerToc = string.gsub ( data.p.innerToc, "[^~]+", function(x) n=n+1; return "* [[#m" .. n .. "|" .. x .."]]" end ) data.p.innerToc = string.gsub ( data.p.innerToc, "~", "\n" ) end innerToc = frame:expandTemplate { title = "tocline", args = { "\n" .. data.p.innerToc, color = "", fs = "inherit" } } end local editions = renderEditions ( frame ) local translations = renderOtherTrans ( frame ) mw.logObject(editions,"editions") mw.logObject(translations,"translations") -- ссылки на другие словари и проекты local other_sources = require( "Модуль:Источники по теме" ).get_data( frame ) -- mw.logObject(other_sources, "other_sources") local encyclopedias = other_sources.enc_links_rendered local navigation = other_sources.projects_links_rendered for _, cat in pairs(other_sources.categories) do addCat ( cat ) end -- render local result = mw.html.create() local function addDiv( id ) return result:tag ( "div" ):addClass ( "ws-noexport searchaux" ):attr( 'id', id or '' ):css( "display", "none" ) end if is(editions) or is(translations) or is(encyclopedias) or is(navigation) then local div = addDiv( 'extra_nav' ) local menu = div:tag ("ul"):css({ display = "none" }) if editions then menu:css({ display = "block" }):wikitext( editions ) div:css({ display = "flex" }) end --mw.logObject(menu,"menu") if translations then menu:css({ display = "block" }):wikitext( translations ) div:css({ display = "flex" }) end if encyclopedias then encyclopedias = encyclopedias:gsub ( "%[([^%[%]]-/articles/)([^%[%]/ ]+)( [^%[%]]+)%]", "[%1%2%3" .. "<span class=xtitle> ► " .. "%2</span>]" ) encyclopedias = encyclopedias:gsub ( "(%[%[)([^%[%]|]+)(|[^%[%]|]+)(%]%])", "%1%2%3" .. "<span class=xtitle> // " .. "%2</span>%4" ) encyclopedias = encyclopedias:gsub ( "/ДО%]%]", "]]" ) encyclopedias = encyclopedias:gsub ( " %(DNB%d%d%)%]%]", "]]" ) encyclopedias = encyclopedias:gsub ( "// :%a%a:[A-ZÄÖÜ0-9]-:", "► " ) encyclopedias = encyclopedias:gsub ( "// [^/]+/ДО/", "► " ) encyclopedias = encyclopedias:gsub ( "// [^/]+/ВТ/", "► " ) encyclopedias = encyclopedias:gsub ( "// [^/]+/6e éd., 1863/", "► " ) encyclopedias = encyclopedias:gsub ( "// [^/%[%]]+/", "► " ) --encyclopedias = encyclopedias:gsub ( " // ", " ► " ) menu:css({ display = "block" }):wikitext ( encyclopedias ) div:css({ display = "flex" }) end if navigation then navigation = navigation:gsub ( "(Special:Search/[^%[%]|]+|)Википедия","%1''Википедия (поиск)''") menu:css({ display = "block" }):wikitext ( navigation ) div:css({ display = "flex" }) end end if innerToc then local div = addDiv( 'inner_toc'); div:wikitext( innerToc ):css( "display", "block" ):done() addCat( s.cat.innerToc ) end return tostring ( result ) end --[[ function renderImgFooter ( frame ) ------------------------------------------------------------ Нижний колонтитул и ИЗОБРАЖЕНИЕ --------------------------------------------------------------------------------------------------]] function renderImgFooter ( frame ) local license = "" local license_template = s.license[data.p.license or ""] or data.p.license if license_template then if exists ( "Шаблон:" .. license_template ) then license = frame:expandTemplate { title = license_template } else addCat ( s.cat.unknownLicense ) end end frame.args.nocat = "yes" local external_links = require( "Module:External links" ).render( frame ) local img = "" if data.p.img then img = "[[Файл:" .. data.p.img .. "|right|180px" if data.p.imgDesc then img = img .. "|thumb|" .. data.p.imgDesc .. "]]" else img = img .. "|border]]" end end -- render local result = mw.html.create() result :tag ( "div" ):attr ( "id", "ws-footer" ):addClass ( "ws-noexport" ):css ( "display", "none" ) :tag ( "br" ):attr ( "clear", "all" ):done() :newline() :newline() :wikitext ( renderSubNav ( getFooter() ) ) -- Нижний колонтитул :wikitext ( external_links ) :wikitext ( license ) :done() :tag ( "br" ):attr ( "clear", "all" ):done() :wikitext ( img ) return tostring ( result ) end --[[ function renderSubNav ( tbl, footer ) --------------------------------------------------------- Дополнительная навигация для Sub-nav и Footer --------------------------------------------------------------------------------------------------]] function renderSubNav ( tbl, footer ) local result = mw.html.create() if #tbl > 0 then --if footer then result:tag ( "br" ):done() end for i, v in ipairs ( tbl ) do local tr = result :tag ( "table" ):attr('id', 'footer-subnav'):addClass ( "headertemplate ws-noexport" ) :css ( "margin-top", "-1px" ) :tag ( "tr" ) if footer then tr:css ( "line-height", "120%" ) else tr:css ( "line-height", "100%" ) end tr :tag ( "td" ):addClass ( "header_backlink searchaux" ) :css ({ ["width"] = "30%", ["overflow"] = "hidden", ["text-align"] = "left" }) :wikitext ( backarrow (v[1]) ) :done() :tag ( "td" ):addClass ( "header_title" ) :css ({ ["width"] = "40%", ["overflow"] = "hidden", ["text-align"] = "center", ["font-size"] = "90%" }) :wikitext ( v[3] ) :done() :tag ( "td" ):addClass ( "header_forelink searchaux" ) :css ({ ["width"] = "30%", ["overflow"] = "hidden", ["text-align"] = "right" }) :wikitext ( forearrow (v[2]) ) end end return tostring ( result ) end -- Helper functions -------------------------------------------------------------------------------- -- проверка переменной, возврат её или nil если пустая function is ( var ) if ( var == '' or var == nil ) then return nil else return var end end function exists (title) local t = mw.title.new (title) if t then return t.exists end end -- возврат действительного true/false function toBool ( val ) return not not val end -- добавление категории в data.cat function addCat ( cat ) if is(cat) then table.insert( data.cat, cat ) end end function addToPage ( val ) if data.pagetext then data.pagetext = data.pagetext .. s.append[isPRS] .. tostring ( val ) else data.pagetext = tostring ( val ) end end -- анализ названия страницы по критериям именования редакций function parseTitle ( name ) -- формат 1: Название/Редакция (ДО)/Подстраницы local r, e, f, s = name:match ( "^([^/]+%b())/([^/]+ (%b()))/(.+)" ) if not f then r, e, f, s = name:match ( "^([^/]+%b())/([^/]+ (%b()))$" ) end if not f then r, e, f, s = name:match ( "^([^/]+)/([^/]+ (%b()))/(.+)" ) end if not f then r, e, f, s = name:match ( "^([^/]+)/([^/]+ (%b()))$" ) end if f and string.find ( "(ДО)(СО)(ВТ)(ВТ:Ё)(ВТ:У)", f ) then return 1, r, e, s else -- формат 2: Префикс/ДО/Название (для сл. статей) r, f, e, s = name:match ( "^([^/]+)(/([^/]+)/)(.+)" ) if f and string.find ( "/ДО/ВТ/", f ) then return 2, r, e, s else -- формат 3: Название/ДО (old style) r, e = name:match ( "^(.+)(/ДО)$" ) if e then return 3, r, e elseif exists ( name .. "/ДО" ) then return 3, name, "" else return 0 end end end end -- escape certain characters in regex patterns function escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); end -- преобразует строку в ссылку, добавляя [[]] при необходимости -- upd 02.10.2018: ссылка не добавляется, если строка начинается с ~ function linkify ( link ) if not is( link ) then return end if link:find ("^~%s*") then link = link:gsub ("^~%s*", "") else if not link:find ("%[%[") then link = "[[" .. link .. "]]" end end return link end -- добавляет стрелку для ссылки назад function backarrow ( link ) if is( link ) and type( link ) == "string" then return "← " .. link end end -- добавляет стрелку для ссылки вперед function forearrow ( link ) if is( link ) and type( link ) == "string" then return link .. " →" end end function other_uses_tpl( frame, tpl_type, link ) local tpl = '' if link then local img_s = '[[Файл:Disambig.svg|100x13px|link=]] ' if tpl_type == 1 then local link = util.make_wikilink(link, 'одноимённые страницы') tpl = frame:expandTemplate{title = 'Другое значение', args = { img_s .. 'См. также ' .. link .. '.', extraclasses = 'ws-noexport'}} elseif tpl_type == 2 then local link = util.make_wikilink(link, 'другие переводы') tpl = frame:expandTemplate{title = 'Другое значение', args = { img_s .. 'См. также ' .. link .. '.', extraclasses = 'ws-noexport'}} end end return tpl end -- извлечение ссылки из строки (первой, если несколько) function toLink ( str ) return string.match ( str or "", "(%[%[[^%[%]]+%]%])" ) end -- проверяет тип переменной и возвращает строковое значение function getString ( val ) if type ( val ) == "table" then return val.default or val[isPRS] or val[not isPRS] or "" elseif type ( val ) == "nil" then return "" else return tostring ( val ) end end function screen ( str ) if type (str) == "string" then return str:gsub ( "|", "@" ) else return str end end function unscreen ( str ) if type (str) == "string" then return str:gsub ( "@", "|" ) else return str end end ---------------------------------------------------------------------------------------------------- return p