Module:Format
Jump to navigation
Jump to search
Shared implementation for formatting helpers.
--------------------------------------------------------------------------------
-- Module:Format
-- Simple formatting utilities for inline and block-level elements.
--
-- INSTALLATION:
-- 1. Create page: Module:Format
-- 2. Paste this entire file
-- 3. Create TemplateStyles page: Module:Format/styles.css
--
-- USAGE:
-- {{#invoke:Format|abbr|abbreviation|full text}}
-- {{#invoke:Format|nowrap|text that should not wrap}}
-- {{#invoke:Format|lang|fr|Bonjour}}
-- {{#invoke:Format|sic}}
-- {{#invoke:Format|clear}}
--
-- @author Remilia Wiki
-- @license MIT
--------------------------------------------------------------------------------
local p = {}
--------------------------------------------------------------------------------
-- UTILITY FUNCTIONS
--------------------------------------------------------------------------------
local function trim(s)
if not s then return nil end
return tostring(s):match("^%s*(.-)%s*$")
end
local function isEmpty(s)
if s == nil then return true end
if type(s) == 'string' then
return trim(s) == ''
end
return false
end
local function hasValue(s)
return not isEmpty(s)
end
local function getArg(args, name, default)
local val = args[name]
if isEmpty(val) then return default end
return trim(val)
end
local function getFrameArgs(frame)
return require('Module:Arguments').getArgs(frame, {
trim = false,
removeBlanks = false,
})
end
--------------------------------------------------------------------------------
-- ABBREVIATION
--------------------------------------------------------------------------------
function p.abbr(frame)
local args = getFrameArgs(frame)
local abbr = getArg(args, 1)
local title = getArg(args, 2) or getArg(args, 'title')
if isEmpty(abbr) then
return '<span class="error">Error: Abbreviation required</span>'
end
local span = mw.html.create('abbr')
:addClass('abbr')
if hasValue(title) then
span:attr('title', title)
end
span:wikitext(abbr)
return tostring(span)
end
--------------------------------------------------------------------------------
-- NOWRAP
--------------------------------------------------------------------------------
function p.nowrap(frame)
local args = getFrameArgs(frame)
local text = getArg(args, 1)
if isEmpty(text) then
return ''
end
local span = mw.html.create('span')
:addClass('nowrap')
:wikitext(text)
return tostring(span)
end
--------------------------------------------------------------------------------
-- LANGUAGE MARKUP
--------------------------------------------------------------------------------
function p.lang(frame)
local args = getFrameArgs(frame)
local code = getArg(args, 1) or getArg(args, 'code')
local text = getArg(args, 2) or getArg(args, 'text')
if isEmpty(text) then
return '<span class="error">Error: Text required</span>'
end
local span = mw.html.create('span')
:addClass('lang')
if hasValue(code) then
span:attr('lang', code)
span:addClass('lang-' .. code)
end
span:wikitext(text)
return tostring(span)
end
--------------------------------------------------------------------------------
-- SIC
--------------------------------------------------------------------------------
function p.sic(frame)
local args = getFrameArgs(frame)
local text = getArg(args, 1)
local reason = getArg(args, 'reason')
local result = ''
if hasValue(text) then
result = text
end
local span = mw.html.create('span')
:addClass('sic')
:addClass('noprint')
if hasValue(reason) then
span:attr('title', reason)
end
span:wikitext('[<i>sic</i>]')
return result .. tostring(span)
end
--------------------------------------------------------------------------------
-- CLEAR
--------------------------------------------------------------------------------
function p.clear(frame)
local args = getFrameArgs(frame)
local side = getArg(args, 1, 'both')
local div = mw.html.create('div')
:addClass('clear')
if side == 'left' then
div:addClass('clear-left')
elseif side == 'right' then
div:addClass('clear-right')
else
div:addClass('clear-both')
end
return tostring(div)
end
--------------------------------------------------------------------------------
-- BLOCK INDENT
--------------------------------------------------------------------------------
function p.indent(frame)
local args = getFrameArgs(frame)
local text = getArg(args, 1) or getArg(args, 'text')
local level = math.max(1, math.min(5, math.floor(tonumber(getArg(args, 'level', '1')) or 1)))
local amount = tonumber(getArg(args, 'em'))
if isEmpty(text) then
return ''
end
local div = mw.html.create('div')
:addClass('block-indent')
:wikitext(text)
if amount then
amount = math.max(0, math.min(20, amount))
div:css('margin-left', amount .. 'em'):css('margin-right', amount .. 'em')
else
div:addClass('indent-' .. level)
end
return tostring(div)
end
--------------------------------------------------------------------------------
-- EMPHASIS
--------------------------------------------------------------------------------
function p.em(frame)
local args = getFrameArgs(frame)
local text = getArg(args, 1)
if isEmpty(text) then
return ''
end
local em = mw.html.create('em')
:wikitext(text)
return tostring(em)
end
--------------------------------------------------------------------------------
-- STRONG
--------------------------------------------------------------------------------
function p.strong(frame)
local args = getFrameArgs(frame)
local text = getArg(args, 1)
if isEmpty(text) then
return ''
end
local strong = mw.html.create('strong')
:wikitext(text)
return tostring(strong)
end
--------------------------------------------------------------------------------
-- ANCHOR
--------------------------------------------------------------------------------
function p.anchor(frame)
local args = getFrameArgs(frame)
local name = getArg(args, 1) or getArg(args, 'name')
if isEmpty(name) then
return ''
end
local span = mw.html.create('span')
:attr('id', name)
return tostring(span)
end
--------------------------------------------------------------------------------
-- UNBULLETED LIST
--------------------------------------------------------------------------------
function p.unbulleted(frame)
local args = getFrameArgs(frame)
local ul = mw.html.create('ul')
:addClass('unbulleted-list')
for i = 1, 30 do
local item = getArg(args, i)
if hasValue(item) then
ul:tag('li'):wikitext(item)
end
end
return tostring(ul)
end
--------------------------------------------------------------------------------
-- PLAINLIST
--------------------------------------------------------------------------------
function p.plainlist(frame)
local args = getFrameArgs(frame)
local content = getArg(args, 1) or getArg(args, 'content')
if isEmpty(content) then
return ''
end
local div = mw.html.create('div')
:addClass('plainlist')
:wikitext(content)
return tostring(div)
end
--------------------------------------------------------------------------------
-- CIRCA
--------------------------------------------------------------------------------
function p.circa(frame)
local args = getFrameArgs(frame)
local date = getArg(args, 1)
local lc = require('Module:Yesno')(getArg(args, 'lc'), false)
local prefix = lc and 'c.' or 'C.'
local abbr = mw.html.create('abbr')
:attr('title', 'circa')
:wikitext(prefix)
local result = tostring(abbr)
if hasValue(date) then
result = result .. ' ' .. date
end
return result
end
--------------------------------------------------------------------------------
-- IPA
--------------------------------------------------------------------------------
function p.ipa(frame)
local args = getFrameArgs(frame)
local text = getArg(args, 1)
if isEmpty(text) then
return ''
end
local span = mw.html.create('span')
:addClass('ipa')
:attr('title', 'Representation in the International Phonetic Alphabet')
:wikitext('/' .. text .. '/')
return tostring(span)
end
--------------------------------------------------------------------------------
-- APOSTROPHE (after italics)
--------------------------------------------------------------------------------
function p.apostrophe(frame)
-- Returns a properly formatted apostrophe that won't be
-- interpreted as wiki italic markup
return "<span class=\"apostrophe\">'</span>"
end
--------------------------------------------------------------------------------
-- APOSTROPHE-S (possessive after italics)
--------------------------------------------------------------------------------
function p.apostrophe_s(frame)
-- Returns a properly formatted possessive 's that won't be
-- interpreted as wiki italic markup
return "<span class=\"apostrophe\">'s</span>"
end
--------------------------------------------------------------------------------
-- MATH (inline mathematical expression)
--------------------------------------------------------------------------------
function p.math(frame)
local args = getFrameArgs(frame)
local expr = getArg(args, 1)
if isEmpty(expr) then
return ''
end
local span = mw.html.create('span')
:addClass('texhtml')
:wikitext(expr)
return tostring(span)
end
--------------------------------------------------------------------------------
-- GALLERY (wrapper for MediaWiki gallery tag)
--------------------------------------------------------------------------------
function p.gallery(frame)
local args = getFrameArgs(frame)
local content = getArg(args, 1)
if isEmpty(content) then
return ''
end
return frame:extensionTag('gallery', content, {
mode = getArg(args, 'mode'),
widths = getArg(args, 'widths'),
heights = getArg(args, 'heights'),
caption = getArg(args, 'caption'),
})
end
-- A trait's reference images are independent slots, including sparse input.
function p.traitReferences(frame)
local args = getFrameArgs(frame)
local lines = {}
for index = 1, 8 do
local key = 'ref' .. index
local file = getArg(args, key)
if file then
local title = mw.title.new(file, 6)
if title and title.namespace == 6 and title.interwiki == '' then
local caption = getArg(args, key .. '_caption') or getArg(args, key .. '_subject') or ''
lines[#lines + 1] = title.prefixedText .. '|' .. caption
else
return '<strong class="error">Invalid reference image in ' .. key .. '.</strong>'
end
end
end
if #lines == 0 then return '' end
return frame:extensionTag('gallery', table.concat(lines, '\n'), {
mode = getArg(args, 'mode', 'nolines'),
widths = getArg(args, 'widths', '240'),
heights = getArg(args, 'heights', '200'),
})
end
-- Keep the template's missing/blank/default outputs distinct. Only evaluate
-- the selected result, so references in unused branches are not registered.
function p.yesno(frame)
local args = getFrameArgs(frame)
local value = args[1]
if value == nil then return args['¬'] or '' end
value = mw.ustring.lower(mw.text.trim(value))
if value == '¬' then return args['¬'] or '' end
if value == '' then return args.blank or args.no or '' end
local trueValues = { yes = true, y = true, t = true, ['true'] = true, on = true, ['1'] = true }
local falseValues = { no = true, n = true, f = true, ['false'] = true, off = true, ['0'] = true }
if trueValues[value] then return args.yes or 'yes' end
if falseValues[value] then return args.no or '' end
return args.def or args.yes or 'yes'
end
return p