-- This module implements {{italic title}}.require('strict')local libraryUtil = require('libraryUtil')local checkType = libraryUtil.checkTypelocal checkTypeForNamedArg = libraryUtil.checkTypeForNamedArglocal yesno = require('Module:Yesno')---------------------------------------------------------------------------------- ItalicTitle class--------------------------------------------------------------------------------local ItalicTitle = {}do------------------------------------------------------------------------------ Class attributes and functions-- Things that belong to the class are here. Things that belong to each-- object are in the constructor.------------------------------------------------------------------------------ Keys of title parts that can be italicized.local italicizableKeys = {namespace = true,title = true,dab = true,}------------------------------------------------------------------------------ ItalicTitle constructor-- This contains all the dynamic attributes and methods.----------------------------------------------------------------------------function ItalicTitle.new()local obj = {}-- Function for checking self variable in methods.local checkSelf = libraryUtil.makeCheckSelfFunction('ItalicTitle','obj',obj,'ItalicTitle object')-- Checks a key is present in a lookup table.-- Param: name - the function name.-- Param: argId - integer position of the key in the argument list.-- Param: key - the key.-- Param: lookupTable - the table to look the key up in.local function checkKey(name, argId, key, lookupTable)if not lookupTable[key] thenerror(string.format("bad argument #%d to '%s' ('%s' is not a valid key)",argId,name,key), 3)endend-- Set up object structure.local parsed = falselocal categories = {}local italicizedKeys = {}local italicizedSubstrings = {}-- Parses a title object into its namespace text, title, and-- disambiguation text.-- Param: options - a table of options with the following keys:-- title - the title object to parse-- ignoreDab - ignore any disambiguation parentheses-- Returns the current object.function obj:parseTitle(options)checkSelf(self, 'parseTitle')checkType('parseTitle', 1, options, 'table')checkTypeForNamedArg('parseTitle', 'title', options.title, 'table')local title = options.title-- Title and dab textlocal prefix, parenthesesif not options.ignoreDab thenprefix, parentheses = mw.ustring.match(title.text,'^(.+) %(([^%(%)]+)%)$')endif prefix and parentheses thenself.title = prefixself.dab = parentheseselseself.title = title.textend-- Namespacelocal namespace = mw.site.namespaces[title.namespace].nameif namespace and #namespace >= 1 thenself.namespace = namespaceend-- Register the object as having parsed a title.parsed = truereturn selfend-- Italicizes part of the title.-- Param: key - the key of the title part to be italicized. Possible-- keys are contained in the italicizableKeys table.-- Returns the current object.function obj:italicize(key)checkSelf(self, 'italicize')checkType('italicize', 1, key, 'string')checkKey('italicize', 1, key, italicizableKeys)italicizedKeys[key] = truereturn selfend-- Un-italicizes part of the title.-- Param: key - the key of the title part to be un-italicized. Possible-- keys are contained in the italicizableKeys table.-- Returns the current object.function obj:unitalicize(key)checkSelf(self, 'unitalicize')checkType('unitalicize', 1, key, 'string')checkKey('unitalicize', 1, key, italicizableKeys)italicizedKeys[key] = nilreturn selfend-- Italicizes a substring in the title. This only affects the main part-- of the title, not the namespace or the disambiguation text.-- Param: s - the substring to be italicized.-- Returns the current object.function obj:italicizeSubstring(s)checkSelf(self, 'italicizeSubstring')checkType('italicizeSubstring', 1, s, 'string')italicizedSubstrings[s] = truereturn selfend-- Un-italicizes a substring in the title. This only affects the main-- part of the title, not the namespace or the disambiguation text.-- Param: s - the substring to be un-italicized.-- Returns the current object.function obj:unitalicizeSubstring(s)checkSelf(self, 'unitalicizeSubstring')checkType('unitalicizeSubstring', 1, s, 'string')italicizedSubstrings[s] = nilreturn selfend-- Renders the object into a page name. If no title has yet been parsed,-- the current title is used.-- Returns stringfunction obj:renderTitle()checkSelf(self, 'renderTitle')-- Italicizes a string-- Param: s - the string to italicize-- Returns string.local function italicize(s)assert(type(s) == 'string', 's was not a string')assert(s ~= '', 's was the empty string')return string.format('<i>%s</i>', s)end-- Escape characters in a string that are magic in Lua patterns.-- Param: pattern - the pattern to escape-- Returns string.local function escapeMagicCharacters(s)assert(type(s) == 'string', 's was not a string')return s:gsub('%p', '%%%0')end-- If a title hasn't been parsed yet, parse the current title.if not parsed thenself:parseTitle{title = mw.title.getCurrentTitle()}end-- Italicize the different parts of the title and store them in a-- titleParts table to be joined together later.local titleParts = {}-- Italicize the italicizable keys.for key in pairs(italicizableKeys) doif self[key] thenif italicizedKeys[key] thentitleParts[key] = italicize(self[key])elsetitleParts[key] = self[key]endendend-- Italicize substrings. If there are any substrings to be-- italicized then start from the raw title, as this overrides any-- italicization of the main part of the title.if next(italicizedSubstrings) thentitleParts.title = self.titlefor s in pairs(italicizedSubstrings) dolocal pattern = escapeMagicCharacters(s)local italicizedTitle, nReplacements = titleParts.title:gsub(pattern,italicize)titleParts.title = italicizedTitle-- If we didn't make any replacements then it means that we-- have been passed a bad substring or that the page has-- been moved to a bad title, so add a tracking category.if nReplacements < 1 thencategories['Pages using italic title with no matching string'] = trueendendend-- Assemble the title together from the parts.local ret = ''if titleParts.namespace thenret = ret .. titleParts.namespace .. ':'endret = ret .. titleParts.titleif titleParts.dab thenret = ret .. ' (' .. titleParts.dab .. ')'endreturn retend-- Returns an expanded DISPLAYTITLE parser function called with the-- result of obj:renderTitle, plus any other optional arguments.-- Returns stringfunction obj:renderDisplayTitle(...)checkSelf(self, 'renderDisplayTitle')return mw.getCurrentFrame():callParserFunction('DISPLAYTITLE',self:renderTitle(),...)end-- Returns an expanded DISPLAYTITLE parser function called with the-- result of obj:renderTitle, plus any other optional arguments, plus-- any tracking categories.-- Returns stringfunction obj:render(...)checkSelf(self, 'render')local ret = self:renderDisplayTitle(...)for cat in pairs(categories) doret = ret .. string.format('[[Category:%s]]',cat)endreturn retendreturn objendend---------------------------------------------------------------------------------- Exports--------------------------------------------------------------------------------local p = {}local function getArgs(frame, wrapper)assert(type(wrapper) == 'string', 'wrapper was not a string')return require('Module:Arguments').getArgs(frame, {wrappers = wrapper})end-- Main function for {{italic title}}function p._main(args)checkType('_main', 1, args, 'table')local italicTitle = ItalicTitle.new()italicTitle:parseTitle{title = mw.title.getCurrentTitle(),ignoreDab = yesno(args.all, false)}if args.string thenitalicTitle:italicizeSubstring(args.string)elseitalicTitle:italicize('title')endreturn italicTitle:render(args[1])endfunction p.main(frame)return p._main(getArgs(frame, 'Template:Italic title'))endfunction p._dabonly(args)return ItalicTitle.new():italicize('dab'):render(args[1])endfunction p.dabonly(frame)return p._dabonly(getArgs(frame, 'Template:Italic dab'))endreturn p