| This is the module sandbox page for Module:R. |
| This module is rated as pre-alpha. It is incomplete and may or may not be in active development. Do not use it in article namespace pages. A module remains in pre-alpha until its developer, or another editor who adopts it if it is abandoned for some time, considers the basic structure complete. |
Implement Template:R and Template:Rp
Usage
edit{{#invoke:R|function_name}}
local rp = {}
local r = {}
local hyphen2dash = require('Module:String2').hyphen_to_dash
local lang = require('Module:Lang')
local trim_quotes = require('Module:trim quotes')._trim
local getArgs = require('Module:Arguments').getArgs
local plainText = require('Module:Plain text')._main
local mt = {__call = function (t, v) t[#t+1] = v end}
local notblank = function(v) return (v or '') ~= '' end
local pageTest = {pages = 1, pp = 1, page = 1, p = 1}
local wrapTest = {yes = 1, y = 1, forced = 1, f = 1}
-- get first non-empty argument from a list of names
local function firstArg(args, ...)
for i = 1, select('#', ...) do
local n = select(i, ...)
local v = args[n]
if notblank(v) then return v end
end
return nil
end
local function firstArgN(s, args, ...)
for i = 1, select('#', ...) do
local n = select(i, ...)
local v = args[n .. s]
if notblank(v) then return v end
end
return nil
end
-- Implements [[Template:page_needed]]
-- may replace with lua implementation at some point
local function page_needed(frame, date, reason)
return frame:expandTemplate{title='Page needed', args = {date = date, reason = reason}}
end
-- Implements [[Template:R/langcode]]
-- Only for template/module use: |language=code/name
function r._langcode(language)
language = language or ''
local tag, result = lang._tag_from_name{language}
if result then
return tag
elseif lang._is_ietf_tag(language) then
return language
end
return 'mis' -- use language code "mis" for any unrecognized language
end
function r.langcode(frame)
local args = getArgs(frame)
return r._langcode(args.language)
end
-- Implements [[Template:R/where]] sub-template
-- Only for template/module use: |plural=pages |singular=page |location=in-source-location |spacing=character
function r._where(params)
local out = setmetatable({}, mt)
if notblank(params.plural) then
out(params.plural)
if notblank(params.singular) then
out("," .. (params.spacing or "") .. "[" .. params.singular .. "]")
end
elseif notblank(params.singular) then
out(params.singular)
end
if notblank(params.location) then
if notblank(params.plural) or notblank(params.singular) then
out("," .. (params.spacing or ""))
end
out(params.location)
end
return table.concat(out)
end
function r.where(frame)
return r._where(getArgs(frame))
end
-- Implements [[Template:R/superscript]]
-- Only for template/module use: |wrap=n[o]/y[es]/f[orced] |leadin=value |prefix=value |pp=value |where=value |sup-where=value |quote-where=value |quote=value |language=value |translation=value |suffix=value
function r._superscript(params)
if not params or not notblank(params.where) then
return ""
end
local out = setmetatable({}, mt)
-- "wrap" if wrap is "yes", "y", "f" or "forced", else "nowrap"
local wrap = wrapTest[string.ulower(params.wrap or '')]
out('<sup class="reference ' .. (wrap and "" or "no") .. 'wrap">')
--prefix, if there's a quote
if notblank(params.quote) and notblank(params.prefix) then
out(params.prefix)
end
-- open tooltip span
out('<span title="')
-- Lead-in text (escaped)
local whereText = notblank(params["quote-where"]) and params["quote-where"]
or (params["where"] or "")
local tooltipText = plainText((params.leadin or "") .. ": " .. whereText, false)
out(mw.text.encode(tooltipText, '<>"'))
-- Quotation block if present
if notblank(params.quote) then
local quoteTab = setmetatable({}, mt)
if notblank(params.language) then
local langText = lang._is_ietf_tag(params.language) and lang._name_from_tag{params.language} or params.language
quoteTab(" (" .. langText .. ")")
end
quoteTab(": "" .. trim_quotes(params.quote) ..
""")
if notblank(params.translation) then
quoteTab(" Translation: "" ..
trim_quotes(params.translation) .. """)
end
local quoteText = plainText(table.concat(quoteTab), false)
out(" Quotation" .. mw.text.encode(quoteText, '<>"') ..
'" class="tooltip tooltip-dashed" style="border-bottom: 1px dashed;')
end
-- close tooltip span
out('">')
-- prefix, if not inserted above
if (not notblank(params.quote)) and notblank(params.prefix) then
out(params.prefix)
end
--pp and sup-where
out(params.pp or '')
out(params['sup-where'] or '')
-- suffix
if notblank(params.quote) then
out("</span>" .. (params.suffix or ""))
else
out((params.suffix or "") .. "</span>")
end
out("</sup>")
return table.concat(out)
end
function r.superscript(frame)
return r._superscript(getArgs(frame))
end
-- Implements [[Template:R/ref]]
function r._ref(params, frame)
frame = frame or mw.getCurrentFrame()
local out = setmetatable({}, mt)
local contextSectionName = mw.uri.anchorEncode(
'cite_sect-' ..
trim_quotes(params[1] or '') .. '-' ..
trim_quotes(params[2] or '') .. '-' ..
trim_quotes(
(notblank(params.page) and params.page or hyphen2dash(params.pages or '', ' ')) ..
(params.location or '')
)
)
local contentId = notblank(params['content-id']) and mw.uri.anchorEncode(params['content-id']) or nil
local whereArgs = {
plural = hyphen2dash(params.pages, ' '),
singular = params.page,
location = params.location,
spacing = ' '
}
local quoteWhereArgs = {
plural = hyphen2dash(params['quote-pages'], ' '),
singular = params['quote-page'],
location = params['quote-location'],
spacing = ' '
}
local refArgs = {name = params[1] or '', group = params[2] or ''}
-- Debug facility
if notblank(params.debug) then
out("DEBUG: ")
for k, v in pairs(params) do
out(k .. "=" .. (v or '') .. ", ")
end
out(". Potential context-section-name:")
out(contextSectionName .. '".')
end
-- Opening "support context" span
local lst
if notblank(params.section) then
local section = (params.section == 'yes' or params.section == 'y') and
contextSectionName or params.section
lst = frame:callParserFunction('#lst', {
mw.title.getCurrentTitle().fullText,
section
})
if notblank(lst) then
out('<templatestyles src="Template:Tooltip/styles.css"/>')
out('<span class="rt-commentedText tooltip tooltip-dotted"' ..
'title="Context: "' .. mw.text.encode(plainText(lst, false), '<>"') ..
'"">')
end
end
--First call to create reference link (variants identical except for dir):
if notblank(params['link-id']) then
out('<span id="' .. mw.uri.anchorEncode(params['link-id']) ..
'class="citation">')
end
local refContent = setmetatable({}, mt)
if (not notblank(params.annotation)) then
refContent(params.reference or '')
if contentId then
refContent(1, '<span id="' .. contentId .. '" class="citation">')
refContent('</span>')
end
refContent(params.postscript or '')
end
if notblank(params.direction) then
refArgs.dir = params.direction
end
out(frame:extensionTag('ref', table.concat(refContent), refArgs))
if notblank(params['link-id']) then
out('</span>')
end
--Optional second call to append data to reference (variants identical except for dir):
if notblank(params.annotation) then
refContent = setmetatable({}, mt)
if pageTest[params.annotation] then
if notblank(firstArg(params, 'pages', 'page', 'location')) then
refContent(params.leadin or '')
refContent(r._where(whereArgs))
if contentId then
refContent(1, '<span id="' .. contentId .. '">')
refContent('</span>')
end
refContent(1, '‌')
end
elseif ({quote = 1, q = 1})[params.annotation] then
refContent('‌')
if pageTest[firstArg(params, 'quote-pages', 'quote-page', 'quote-location')] then
if notblank(firstArg(params, 'pages', 'page', 'location')) then
refContent(params.leadin or '')
refContent(r._where(whereArgs) .. ': ')
end
else
refContent(params.leadin or '')
refContent(r._where(quoteWhereArgs) .. ': ')
end
refContent('<q ')
if contentId then
refContent('id="' .. contentId .. '" ')
end
local qcli = firstArg(params, 'quote-cite', 'link-id')
if notblank(qcli) then
refContent('cite="#' .. (mw.uri.anchorEncode(qcli)) .. '" ')
end
if notblank(params.language) then
local langcode = r._langcode(params.language)
refContent('lang="' .. langcode .. '">')
refContent('<bdi lang="' .. langcode .. '">')
else
refContent('><bdi>')
end
refContent(trim_quotes(params.quote or '') .. '</bdi></q>')
if notblank(params.translation) then
refContent(' [<bdi ')
if notblank(params.language) then
refContent('lang="' .. r._langcode(params.language) .. '"')
end
refContent('>' .. trim_quotes(params.translation .. '</bdi>]'))
end
elseif contentId then
refContent('<span id="' .. contentId ..
' class="citation">' .. (params.leadin or '') ..
params.annotation .. '</span>')
else
refContent((params.leadin or '') .. params.annotation)
end
refContent(params.postscript or '')
refArgs = {follow = params[1] or '', group = params[2] or ''}
if notblank(params.direction) then
refArgs.dir = params.direction
end
out(frame:extensionTag('ref', table.concat(refContent), refArgs))
end
--Superscript pages and tooltip for help, pages, quotes:
local ssAma = string.ulower(params.style or '') == 'ama'
-- p/pp is only used in superscript label, therefore it does not contain any qp params
local ssPp = ''
if ssAma and (not notblank(params['no-pp'])) then
if notblank(params.pages) then
ssPp = 'pp'
elseif notblank(params.page) then
ssPp = 'p'
end
end
-- leadin is only used in tooltip
local ssLeadin = 'Page / location'
if pageTest[firstArg(params, 'quote-pages', 'quote-page', 'quote-location')] then
if notblank(params.pages) then
ssLeadin = 'Pages'
elseif notblank(params.page) then
ssLeadin = 'Page'
elseif notblank(params.location) then
ssLeadin = 'Location'
end
elseif notblank(params['quote-pages']) then
ssLeadin = 'Pages'
elseif notblank(params['quote-page']) then
ssLeadin = 'Page'
elseif notblank(params['quote-location']) then
ssLeadin = 'Location'
end
out(r._superscript{
prefix = ssAma and '(' or ': ',
suffix = ssAma and ')' or ' ',
pp = ssPp,
leadin = ssLeadin,
where = r._where(whereArgs), -- where must not include qp params
['sup-where'] = r._where{ -- sup-where same as where, but with improved list spacing for superscript
plural = hyphen2dash(params.pages, ' '),
singular = params.page,
location = params.location,
spacing=' '
},
['quote-where'] = r._where( -- quote-where must not contain normal in-source-location params
pageTest[firstArg(params, 'quote-pages', 'quote-page', 'quote-location')] and
whereArgs or quoteWhereArgs
),
quote = params.quote,
language = params.language,
translation = params.translation,
['wrap'] = params['wrap']
})
-- Closing "support context" span:
if notblank(params.section) and notblank(lst) then
out('</span>')
end
-- Page needed functionality:
if notblank(params['needed-reason']) then
local pnReason = ({yes = 1, y = 1})[params['needed-reason']] and
'No reason given' or params['needed-reason']
out(page_needed(frame, params['needed-date'], pnReason))
end
-- Line wrapping functionality:
if wrapTest[string.ulower(params.wrap or '')] then
out("​") --zero-width space
end
--End of code
return table.concat(out)
end
function r.ref(frame)
return r._ref(getArgs(frame), frame)
end
function r._r(args, frame)
frame = frame or mw.getCurrentFrame()
local output = setmetatable({}, mt)
-- ### 1 ###
output(r._ref({
[1] = firstArg(args, 'name1', 'name', 'n1', 'n', 1),
[2] = firstArg(args, 'group', 'grp', 'g'),
direction = firstArg(args, 'direction1', 'direction', 'dir1', 'dir'),
page = firstArg(args, 'page1', 'page', 'p1', '1p', 'p'),
pages = firstArg(args, 'pages1', 'pages', 'pp1', '1pp', 'pp'),
location = firstArg(args, 'location1', 'location', 'loc1', '1loc', 'loc', 'at1', 'at'),
['quote-page'] = firstArg(args, 'quotation-page1', 'quotation-page', 'quote-page1', 'quote-page', 'qp1', 'qp'),
['quote-pages'] = firstArg(args, 'quotation-pages1', 'quotation-pages', 'quote-pages1', 'quote-pages', 'qpp1', 'qpp'),
['quote-location'] = firstArg(args,
'quotation-location1', 'quotation-location', 'quote-location1', 'quote-location', 'quote-loc1', 'quote-loc',
'quote-at1', 'quote-at'
),
quote = firstArg(args, 'quotation1', 'quotation', 'quote1', 'quote', 'q1', 'q'),
language = firstArg(args,
'quotation-language1', 'quotation-language', 'quote-language1', 'quote-language', 'quotation-lang1',
'quotation-lang', 'quote-lang1', 'quote-lang', 'ql1', 'ql', 'language1', 'language', 'lang1', 'language', 'l1', 'l'
),
translation = firstArg(args,
'translation-quotation1', 'translation-quotation', 'trans-quotation1', 'trans-quotation', 'translation-quote1',
'translation-quote', 'trans-quote1', 'trans-quote', 'tq1', 'tq', 'translation1', 'translation', 'trans1', 'trans',
't1', 't', 'xlat1', 'xlat'
),
['quote-cite'] = firstArg(args, 'quotation-cite1', 'quotation-cite', 'quote-cite1', 'quote-cite', 'qc1', 'qc'),
reference = firstArg(args,
'reference1', 'references', 'reference', 'notes', 'note', 'content', 'text', 'refn1', 'refn', 'refs', 'r1', 'r'
),
annotation = firstArg(args, 'annotation1', 'annotation', 'annot1', 'annot', 'a1', 'a'),
leadin = args.leadin,
postscript = firstArg(args, 'postscript', 'postscript1', 'ps', 'ps1', '1ps'),
section = firstArg(args, 'section1', 'section', 'sec1', 'sec', 's1', 's'),
['needed-reason'] = firstArg(args, 'needed-reason1', 'needed-reason', 'needed1', 'needed', 'reason'),
['needed-date'] = firstArg(args, 'needed-date', 'date'),
wrap = args.wrap,
['no-pp'] = firstArg(args, 'no-pp', 'nopp'),
style = args.style,
['content-id'] = firstArg(args, 'ref1', '1ref', 'ref', 'id1', 'id'),
['link-id'] = firstArg(args, 'link-id1', 'link-id'),
['debug'] = args['debug']
}, frame))
-- ### 2+ ###
local n = 2
while firstArg(args, "name" .. n, "n" .. n, n) ~= nil do
output(r._ref({
[1] = firstArg(args, 'name' .. n, 'n' .. n, n),
[2] = firstArg(args, 'group', 'grp', 'g'),
direction = firstArgN(n, args, 'direction', 'dir'),
page = firstArg(args, 'page' .. n, 'p' .. n, n .. 'p'),
pages = firstArg(args, 'pages' .. n, 'pp' .. n, n .. 'pp'),
location = firstArg(args, 'location' .. n, 'loc' .. n, n .. 'loc', 'at' .. n),
['quote-page'] = firstArgN(n, args, 'quotation-page', 'quote-page', 'qp'),
['quote-pages'] = firstArgN(n, args, 'quotation-pages', 'quote-pages', 'qpp'),
['quote-location'] = firstArgN(n, args, 'quotation-location', 'quote-location', 'quote-loc', 'quote-at'),
quote = firstArgN(n, args, 'quotation', 'quote', 'q'),
language = firstArgN(n, args,
'quotation-language', 'quote-language', 'quotation-lang', 'quote-lang', 'ql', 'language', 'lang', 'l'
),
translation = firstArgN(n, args,
'translation-quotation', 'trans-quotation', 'translation-quote', 'trans-quote', 'tq', 'translation', 'trans', 't',
'xlat'
),
['quote-cite'] = firstArgN(n, args, 'quotation-cite', 'quote-cite', 'qc'),
reference = firstArgN(n, args, 'reference', 'refn', 'r'),
annotation = firstArgN(n, args, 'annotation', 'annot', 'a'),
leadin = args.leadin,
postscript = firstArg(args, 'postscript' .. n, 'ps' .. n, n .. 'ps', 'postscript', 'ps'),
section = firstArgN(n, args, 'section', 'sec', 's'),
['needed-reason'] = firstArgN(n, args, 'needed-reason', 'needed'),
['needed-date'] = firstArg(args, 'needed-date', 'date'),
['wrap'] = args['wrap'],
['no-pp'] = firstArg(args, 'no-pp', 'nopp'),
style = args.style,
['content-id'] = firstArg(args, 'ref' .. n, n .. 'ref', 'id' .. n),
['link-id'] = args['link-id' .. n],
['debug'] = args['debug'],
}, frame))
n = n + 1
end
return table.concat(output)
end
function r.r(frame)
return r._r(getArgs(frame), frame)
end
-- Implements [[Template:Rp]]
function rp._rp(args, frame)
frame = frame or mw.getCurrentFrame()
-- If needed param is present and non-empty, show {{page needed}}
if notblank(args.needed) then
return page_needed(frame, args.date, args.reason)
end
-- prefix/suffix depending on style
local ama = string.ulower(args.style or "") == "ama"
local prefix = ama and "(" or ": "
local suffix = ama and ")" or " "
-- p/pp is only used in superscript label, therefore it does not contain any qp params
local pp = ""
if ama and not notblank(args["no-pp"]) and not notblank(args.nopp) then
if notblank(args.pages) or notblank(args.pp) then
pp = "pp"
elseif notblank(args.page) or notblank(args.p) then
pp = "p"
end
end
-- leadin is only used in tooltip
local leadin
local quote_switch = firstArg(args, "quotation-pages", "quote-pages", "qpp",
"quotation-page", "quote-page", "qp",
"quotation-location", "quote-location", "quote-loc", "quote-at")
if not pageTest[quote_switch] then
if notblank(firstArg(args, "quotation-pages", "quote-pages", "qpp")) then
leadin = "Pages"
elseif notblank(firstArg(args, "quotation-page", "quote-page", "qp")) then
leadin = "Page"
elseif notblank(firstArg(args, "quotation-location", "quote-location", "quote-loc", "quote-at")) then
leadin = "Location"
end
end
if not leadin then
--either the quote_switch wasn't 'pages', 'pp', 'page',
-- or 'p', or the 'quotation' params were all blank/nil
if notblank(firstArg(args, "pages", "pp")) then
leadin = "Pages"
elseif notblank(firstArg(args, "page", "p")) then
leadin = "Page"
elseif notblank(firstArg(args, "location", "loc", "at")) then
leadin = "Location"
else
leadin = "Page / location"
end
end
-- where must not include qp params
local where = r._where{
plural = hyphen2dash(firstArg(args, "pages", "pp", "1"), ' '),
singular = firstArg(args, "page", "p"),
location = firstArg(args, "location", "loc", "at"),
spacing = " "
}
-- sup-where same as where, but with improved list spacing for superscript
local sup_where = r._where{
plural = hyphen2dash(firstArg(args, "pages", "pp", "1"), ' '),
singular = firstArg(args, "page", "p"),
location = firstArg(args, "location", "loc", "at"),
spacing = " "
}
-- quote-where must not contain normal in-source-location params
local quote_where
if pageTest[quote_switch] then
quote_where = r._where{
plural = hyphen2dash(firstArg(args, "pages", "pp", 1), ' '),
singular = firstArg(args, "page", "p"),
location = firstArg(args, "location", "loc", "at"),
spacing = " "
}
else
quote_where = r._where{
plural = hyphen2dash(firstArg(args, "quotation-pages", "quote-pages", "qpp"), ' '),
singular = firstArg(args, "quotation-page", "quote-page", "qp"),
location = firstArg(args, "quotation-location", "quote-location", "quote-loc", "quote-at"),
spacing = " "
}
end
local zws = ""
if wrapTest[string.ulower(args.wrap or '')] then
zws = "​" --zero-width space
end
return r._superscript{
prefix = prefix,
suffix = suffix,
pp = pp,
leadin = leadin,
["where"] = where,
["sup-where"] = sup_where,
["quote-where"] = quote_where,
quote = firstArg(args, "quotation", "quote", "q"),
language = firstArg(args, "quotation-language", "quote-language",
"quotation-lang", "quote-lang", "ql", "language", "lang", "l"),
translation = firstArg(args, "translation-quotation", "trans-quotation",
"translation-quote", "trans-quote", "tq", "translation", "trans",
"t", "xlat"),
["wrap"] = args.wrap
} .. zws
end
function rp.rp(frame)
return rp._rp(getArgs(frame), frame)
end
return {
[''] = r.r,
r = r.r,
_r = r._r,
rp = rp.rp,
_rp = rp._rp,
ref = r.ref,
_ref = r._ref,
where = r.where,
_where = r._where,
langcode = r.langcode,
_langcode = r._langcode,
superscript = r.superscript,
_superscript = r._superscript
}