Diferencia entre revisiones de «Módulo:Hatnote list»
(Simplified p.forSee) |
m (14 revisiones importadas) |
||
(No se muestran 6 ediciones intermedias de otro usuario) | |||
Línea 1: | Línea 1: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
− | -- | + | -- Module:Hatnote list -- |
− | -- | + | -- -- |
− | -- | + | -- This module produces and formats lists for use in hatnotes. In particular, -- |
− | -- {{about}} | + | -- it implements the for-see list, i.e. lists of "For X, see Y" statements, -- |
− | -- | + | -- as used in {{about}}, {{redirect}}, and their variants. Also introduced -- |
+ | -- are andList & orList helpers for formatting lists with those conjunctions. -- | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
Línea 13: | Línea 14: | ||
local p = {} | local p = {} | ||
− | function | + | -------------------------------------------------------------------------------- |
− | -- | + | -- List stringification helper functions |
− | return | + | -- |
+ | -- These functions are used for stringifying lists, usually page lists inside | ||
+ | -- the "Y" portion of "For X, see Y" for-see items. | ||
+ | -------------------------------------------------------------------------------- | ||
+ | |||
+ | --default options table used across the list stringification functions | ||
+ | local stringifyListDefaultOptions = { | ||
+ | conjunction = "and", | ||
+ | separator = ",", | ||
+ | altSeparator = ";", | ||
+ | space = " ", | ||
+ | formatted = false | ||
+ | } | ||
+ | |||
+ | -- Stringifies a list generically; probably shouldn't be used directly | ||
+ | function stringifyList(list, options) | ||
+ | -- Type-checks, defaults, and a shortcut | ||
+ | checkType("stringifyList", 1, list, "table") | ||
+ | if #list == 0 then return nil end | ||
+ | checkType("stringifyList", 2, options, "table", true) | ||
+ | options = options or {} | ||
+ | for k, v in pairs(stringifyListDefaultOptions) do | ||
+ | if options[k] == nil then options[k] = v end | ||
+ | end | ||
+ | local s = options.space | ||
+ | -- Format the list if requested | ||
+ | if options.formatted then list = mHatnote.formatPages(unpack(list)) end | ||
+ | -- Set the separator; if any item contains it, use the alternate separator | ||
+ | local separator = options.separator | ||
+ | for k, v in pairs(list) do | ||
+ | if string.find(v, separator) then | ||
+ | separator = options.altSeparator | ||
+ | break | ||
+ | end | ||
+ | end | ||
+ | -- Set the conjunction, apply Oxford comma, and force a comma if #1 has "§" | ||
+ | local conjunction = s .. options.conjunction .. s | ||
+ | if #list == 2 and string.find(list[1], "§") or #list > 2 then | ||
+ | conjunction = separator .. conjunction | ||
+ | end | ||
+ | -- Return the formatted string | ||
+ | return mw.text.listToText(list, separator .. s, conjunction) | ||
end | end | ||
− | + | -- Stringifies a list with "and" | |
− | + | function p.andList (list, formatted) | |
− | + | return stringifyList(list, {conjunction = "and", formatted = formatted}) | |
end | end | ||
− | function p. | + | -- Stringifies a list with "or" |
− | + | function p.orList (list, formatted) | |
− | + | return stringifyList(list, {conjunction = "or", formatted = formatted}) | |
− | return | ||
end | end | ||
− | + | -------------------------------------------------------------------------------- | |
− | + | -- For see | |
− | + | -- | |
− | + | -- Makes a "For X, see [[Y]]." list from raw parameters. Intended for the | |
+ | -- {{about}} and {{redirect}} templates and their variants. | ||
+ | -------------------------------------------------------------------------------- | ||
+ | |||
+ | --default options table used across the forSee family of functions | ||
+ | local forSeeDefaultOptions = { | ||
+ | title = mw.title.getCurrentTitle().text, | ||
+ | otherText = 'other uses', | ||
+ | forseeForm = 'For %s, see %s.', | ||
+ | punctuationCollapseReplacements = { | ||
+ | ["%.%.$"] = ".", | ||
+ | ["%?%.$"] = "?", | ||
+ | ["%!%.$"] = "!", | ||
+ | ["%.%]%]%.$"] = ".]]", | ||
+ | ["%?%]%]%.$"] = "?]]", | ||
+ | ["%!%]%]%.$"] = "!]]" | ||
+ | } | ||
+ | } | ||
+ | -- Structures arguments into a table for stringification, & options | ||
+ | function p.forSeeArgsToTable (args, from, options) | ||
-- Type-checks and defaults | -- Type-checks and defaults | ||
− | checkType(" | + | checkType("forSeeArgsToTable", 1, args, 'table') |
− | checkType(" | + | checkType("forSeeArgsToTable", 2, from, 'number', true) |
from = from or 1 | from = from or 1 | ||
− | checkType(" | + | checkType("forSeeArgsToTable", 3, options, 'table', true) |
options = options or {} | options = options or {} | ||
− | + | for k, v in pairs(forSeeDefaultOptions) do | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | for k, v in pairs( | ||
if options[k] == nil then options[k] = v end | if options[k] == nil then options[k] = v end | ||
end | end | ||
− | |||
-- maxArg's gotten manually because getArgs() and table.maxn aren't friends | -- maxArg's gotten manually because getArgs() and table.maxn aren't friends | ||
local maxArg = 0 | local maxArg = 0 | ||
Línea 55: | Línea 108: | ||
if type(k) == 'number' and k > maxArg then maxArg = k end | if type(k) == 'number' and k > maxArg then maxArg = k end | ||
end | end | ||
− | |||
-- Structure the data out from the parameter list | -- Structure the data out from the parameter list | ||
-- forTable is the wrapper table, with forRow rows | -- forTable is the wrapper table, with forRow rows | ||
Línea 66: | Línea 118: | ||
-- New empty row | -- New empty row | ||
local forRow = {} | local forRow = {} | ||
− | -- If there's a blank use, assume the list's ended, | + | -- If there's a blank use, assume the list's ended, leave empty for |
− | -- and break at the end of this loop-through. | + | -- defaulting elsewhere, and break at the end of this loop-through. |
− | forRow.use = args[i] | + | forRow.use = args[i] |
if not args[i] then terminated = true end | if not args[i] then terminated = true end | ||
-- New empty list of pages | -- New empty list of pages | ||
forRow.pages = {} | forRow.pages = {} | ||
− | -- | + | -- Try to insert first pages item; empty is ignored/defaulted elsewhere |
− | table.insert(forRow.pages, args[i + 1] | + | table.insert(forRow.pages, args[i + 1]) |
-- If the option after next is "and", do an inner loop where we collect | -- If the option after next is "and", do an inner loop where we collect | ||
-- items following "and"'s until the "and"'s stop. If there's a blank | -- items following "and"'s until the "and"'s stop. If there's a blank | ||
Línea 89: | Línea 141: | ||
table.insert(forTable, forRow) | table.insert(forTable, forRow) | ||
until terminated or i > maxArg | until terminated or i > maxArg | ||
+ | |||
+ | return forTable | ||
+ | end | ||
− | -- | + | -- Takes a table as formatted by forSeeArgsToTable and stringifies it |
+ | function p.forSeeTableToString (forSeeTable, options) | ||
+ | -- Type-checks and defaults | ||
+ | checkType("forSeeTableToString", 1, forSeeTable, "table") | ||
+ | checkType("forSeeTableToString", 2, options, "table", true) | ||
+ | options = options or {} | ||
+ | for k, v in pairs(forSeeDefaultOptions) do | ||
+ | if options[k] == nil then options[k] = v end | ||
+ | end | ||
+ | -- Format each for-see item and make a table containing them | ||
local strList = {} | local strList = {} | ||
− | for k, v in pairs( | + | for k, v in pairs(forSeeTable) do |
− | local useStr = v.use | + | local useStr = v.use or options.otherText |
− | local pagesStr = p.andList(mHatnote. | + | local pagesStr = p.andList(v.pages, true) or |
− | + | mHatnote._formatLink(mHatnote.disambiguate(options.title)) | |
+ | local forSeeStr = string.format(options.forseeForm, useStr, pagesStr) | ||
+ | for k, v in pairs(options.punctuationCollapseReplacements) do | ||
+ | forSeeStr = string.gsub(forSeeStr, k, v) | ||
+ | end | ||
+ | table.insert(strList, forSeeStr) | ||
end | end | ||
+ | -- Return the concatenated list | ||
return table.concat(strList, ' ') | return table.concat(strList, ' ') | ||
+ | end | ||
+ | |||
+ | -- Produces a "For X, see [[Y]]" string from arguments. Expects index gaps | ||
+ | -- but not blank or whitespace values; those should be filtered. Ignores | ||
+ | -- arguments less than "from", and named arguments. | ||
+ | function p._forSee (args, from, options) | ||
+ | local forSeeTable = p.forSeeArgsToTable(args, from, options) | ||
+ | return p.forSeeTableToString(forSeeTable, options) | ||
+ | end | ||
+ | |||
+ | -- Calls _forSee but pulls from the frame. | ||
+ | function p.forSee (frame, from, options) | ||
+ | mArguments = require('Module:Arguments') | ||
+ | return p._forSee(mArguments.getArgs(frame), from, options) | ||
end | end | ||
return p | return p |
Revisión actual del 13:31 31 may 2016
40px | This template is used on 369 000+ pages. To avoid large-scale disruption and unnecessary server load, any changes to this template should first be tested in its /sandbox or /testcases subpages, or in your own user subpage. The tested changes can then be added to this page in one single edit. Please consider discussing any changes on the talk page before implementing them. |
Usage from wikitext
This module cannot be used from wikitext.
Usage from Lua
To call the module, use <source lang="lua">local mHatList = require('Module:Hatnote list')</source> or similar, then access its methods through the mHatList
variable (or whatever was used).
andList
andList
takes a list in table form, and returns a string with the list separated with "and" and commas as appropriate.
orList
orList
takes a list in table form, and returns a string with the list separated with "or" and commas as appropriate.
forSee
_forSee
takes three arguments: a table of trimmed arguments with blanks removed, a "from" number with the index to start at, and an options table, and returns a string with a number of "For X, see [[Y]]
" sentences. The links are formatted using the methods from Module:Hatnote.
As a convenience, the forSee
method (without the leading underscore) takes the same arguments except with a frame instead of an args table, using getArgs()
from Module:Arguments to preprocess the arguments.
-------------------------------------------------------------------------------- -- Module:Hatnote list -- -- -- -- This module produces and formats lists for use in hatnotes. In particular, -- -- it implements the for-see list, i.e. lists of "For X, see Y" statements, -- -- as used in {{about}}, {{redirect}}, and their variants. Also introduced -- -- are andList & orList helpers for formatting lists with those conjunctions. -- -------------------------------------------------------------------------------- local mArguments --initialize lazily local mHatnote = require('Module:Hatnote') local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local p = {} -------------------------------------------------------------------------------- -- List stringification helper functions -- -- These functions are used for stringifying lists, usually page lists inside -- the "Y" portion of "For X, see Y" for-see items. -------------------------------------------------------------------------------- --default options table used across the list stringification functions local stringifyListDefaultOptions = { conjunction = "and", separator = ",", altSeparator = ";", space = " ", formatted = false } -- Stringifies a list generically; probably shouldn't be used directly function stringifyList(list, options) -- Type-checks, defaults, and a shortcut checkType("stringifyList", 1, list, "table") if #list == 0 then return nil end checkType("stringifyList", 2, options, "table", true) options = options or {} for k, v in pairs(stringifyListDefaultOptions) do if options[k] == nil then options[k] = v end end local s = options.space -- Format the list if requested if options.formatted then list = mHatnote.formatPages(unpack(list)) end -- Set the separator; if any item contains it, use the alternate separator local separator = options.separator for k, v in pairs(list) do if string.find(v, separator) then separator = options.altSeparator break end end -- Set the conjunction, apply Oxford comma, and force a comma if #1 has "§" local conjunction = s .. options.conjunction .. s if #list == 2 and string.find(list[1], "§") or #list > 2 then conjunction = separator .. conjunction end -- Return the formatted string return mw.text.listToText(list, separator .. s, conjunction) end -- Stringifies a list with "and" function p.andList (list, formatted) return stringifyList(list, {conjunction = "and", formatted = formatted}) end -- Stringifies a list with "or" function p.orList (list, formatted) return stringifyList(list, {conjunction = "or", formatted = formatted}) end -------------------------------------------------------------------------------- -- For see -- -- Makes a "For X, see [[Y]]." list from raw parameters. Intended for the -- {{about}} and {{redirect}} templates and their variants. -------------------------------------------------------------------------------- --default options table used across the forSee family of functions local forSeeDefaultOptions = { title = mw.title.getCurrentTitle().text, otherText = 'other uses', forseeForm = 'For %s, see %s.', punctuationCollapseReplacements = { ["%.%.$"] = ".", ["%?%.$"] = "?", ["%!%.$"] = "!", ["%.%]%]%.$"] = ".]]", ["%?%]%]%.$"] = "?]]", ["%!%]%]%.$"] = "!]]" } } -- Structures arguments into a table for stringification, & options function p.forSeeArgsToTable (args, from, options) -- Type-checks and defaults checkType("forSeeArgsToTable", 1, args, 'table') checkType("forSeeArgsToTable", 2, from, 'number', true) from = from or 1 checkType("forSeeArgsToTable", 3, options, 'table', true) options = options or {} for k, v in pairs(forSeeDefaultOptions) do if options[k] == nil then options[k] = v end end -- maxArg's gotten manually because getArgs() and table.maxn aren't friends local maxArg = 0 for k, v in pairs(args) do if type(k) == 'number' and k > maxArg then maxArg = k end end -- Structure the data out from the parameter list -- forTable is the wrapper table, with forRow rows -- Rows are tables of a "use" string and a "pages" table of pagename strings local forTable = {} local i = from local terminated = false -- Repeat to generate and append each row repeat -- New empty row local forRow = {} -- If there's a blank use, assume the list's ended, leave empty for -- defaulting elsewhere, and break at the end of this loop-through. forRow.use = args[i] if not args[i] then terminated = true end -- New empty list of pages forRow.pages = {} -- Try to insert first pages item; empty is ignored/defaulted elsewhere table.insert(forRow.pages, args[i + 1]) -- If the option after next is "and", do an inner loop where we collect -- items following "and"'s until the "and"'s stop. If there's a blank -- where we'd expect an item, ignore it: "1|and||and|3" → {1, 3} while args[i + 2] == 'and' do if args[i + 3] then table.insert(forRow.pages, args[i + 3]) end -- Increment to the next "and" i = i + 2 end -- Increment to the next use i = i + 2 -- Add the row to the table table.insert(forTable, forRow) until terminated or i > maxArg return forTable end -- Takes a table as formatted by forSeeArgsToTable and stringifies it function p.forSeeTableToString (forSeeTable, options) -- Type-checks and defaults checkType("forSeeTableToString", 1, forSeeTable, "table") checkType("forSeeTableToString", 2, options, "table", true) options = options or {} for k, v in pairs(forSeeDefaultOptions) do if options[k] == nil then options[k] = v end end -- Format each for-see item and make a table containing them local strList = {} for k, v in pairs(forSeeTable) do local useStr = v.use or options.otherText local pagesStr = p.andList(v.pages, true) or mHatnote._formatLink(mHatnote.disambiguate(options.title)) local forSeeStr = string.format(options.forseeForm, useStr, pagesStr) for k, v in pairs(options.punctuationCollapseReplacements) do forSeeStr = string.gsub(forSeeStr, k, v) end table.insert(strList, forSeeStr) end -- Return the concatenated list return table.concat(strList, ' ') end -- Produces a "For X, see [[Y]]" string from arguments. Expects index gaps -- but not blank or whitespace values; those should be filtered. Ignores -- arguments less than "from", and named arguments. function p._forSee (args, from, options) local forSeeTable = p.forSeeArgsToTable(args, from, options) return p.forSeeTableToString(forSeeTable, options) end -- Calls _forSee but pulls from the frame. function p.forSee (frame, from, options) mArguments = require('Module:Arguments') return p._forSee(mArguments.getArgs(frame), from, options) end return p