Модуль:Template call code
Материал из Occultica
Для документации этого модуля может быть создана страница Модуль:Template call code/doc
local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end --предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '[') str = string.gsub(str, '%]', ']') str = string.gsub(str, '<', '<') str = string.gsub(str, '>', '>') str = string.gsub(str, '{', '{') str = string.gsub(str, '|', '|') str = string.gsub(str, '}', '}') str = string.gsub(str, '\'', ''') str = string.gsub(str, '"', '"') str = string.gsub(str, '(://)', '<span>%1</span>') end return str end local function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span class="' if not params.spaced then text = text .. ' ts-templateCallCode-pipe' end if not params.black then text = text .. ' ts-templateCallCode-weak' end -- |, чтобы не трактовалось как разделитель ячеек в таблицах text = text .. '">|</span>' end local beforeParam = '<span class="ts-templateCallCode-param">' local afterParam = '</span>' for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam else -- Истинно неименованные addPipe() local paramValue = processText(v, params.nowiki) if #paramValue ~= 0 then text = text .. beforeParam .. paramValue .. afterParam end end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam end end return text end function p._main(args, flags) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end local yesno = require('Module:Yesno') local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false) tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1 end global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span' if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if namePrefix == '' then namePrefix = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ( ( ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="ts-templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-opening' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">{{' if namePrefix then text = text .. namePrefix end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">' local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.withoutParams then if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from }) if spaced then text = text .. ' ' end end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-closing' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">}}</span>' if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } } return ts .. text end function p._onlyParams(args) local yesno = require('Module:Yesno') return addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }) end p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams') return p