Module:Particles

MyWikiBiz, Author Your Legacy — Friday November 15, 2024
Revision as of 05:17, 16 July 2021 by Zoran (talk | contribs) (Pywikibot 6.4.0)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

This module was used to replace {{Subatomic particle}} in List of baryons to remove that article from Category:Pages where post-expand include size is exceeded. Prior to the replacement, half of the article was not displayed correctly.

Usage

These items are built-in to the module:

Item Result
/ " / "
+ " + "
or " or "
seen " (seen) "
_word1_word2 " word1 word2" Template:Green
(text) "(text)" Template:Green
br "<br />" Template:Green

Any other item must an identifier for a particle (not case sensitive). If an item is not recognized, an error message is displayed. Each identifier is defined in Module:Particles/data.

Any br item divides the result into lines, and each line is enclosed in a nowrap span. If there are no br items, the result is a single line enclosed in a nowrap span.

Examples

Wikitext Result
{{#invoke:particles|nolink|Proton+}}
p+
{{#invoke:particles|link|Sigma*+|(1385)}}
Σ∗+
(1385)
{{#invoke:particles|link|Up quark|Up quark|Down quark}}
u

u

d
{{#invoke:particles|link|Proton|/|Proton+|/|Nucleon+}}
p
/
p+
/
N+
{{#invoke:particles|link|Charmed lambda+|+|Kaon-|+|Pion+|+|Pion+|seen}}
Λ+
c
+
K
+
π+
+
π+
(seen)
{{#invoke:particles|link|Lambda0|+|Pion+|or|br|Sigma+|+|Pion0|or|br|Sigma0|+|Pion+}}
Λ0
+
π+
or


Σ+
+
π0
or


Σ0
+
π+
{{#invoke:particles|link|Lambda0|+|Pion+|_any_text|br|Sigma+|+|Pion0|_more_text|br|Sigma0|+|Pion+}}
Λ0
+
π+
any text


Σ+
+
π0
more text


Σ0
+
π+

Modules

The following modules are used:


-- Low-overhead version of {{Subatomic particle|...}} to avoid exceeding
-- template include size at [[List of baryons]].

local particleTable, supsub

local function stripToNil(text)
	-- If text is a string, return its trimmed content, or nil if empty.
	-- Otherwise return text (which may, for example, be nil).
	if type(text) == 'string' then
		text = text:match('(%S.-)%s*$')
	end
	return text
end

local BREAK = "__BR__"

-- A group is a list of one or more particles with optional separating text.
-- Some items are defined with special meanings:
--   Parameter       Output
--    /               " / "
--    +               " + "
--    or              " or "
--    seen            " (seen) "
--    _word1_word2    " word1 word2" (wordN is any text)
--    (text)          "(text)" (text is any text)
--    br              "<br />" (and separates the group into logical lines)
-- Each logical line in the final text is in a nowrap span.
local Group
Group = {
	add = function (self, item)
		if item ~= nil then
			if item == BREAK then
				self:purgeCurrent()
			else
				self.nrCurrent = self.nrCurrent + 1
				self.current[self.nrCurrent] = item
			end
		end
	end,
	new = function ()
		return setmetatable({
			nrCurrent = 0,
			current = {},
			nrLines = 0,
			lines = {},
		}, Group)
	end,
	purgeCurrent = function (self)
		if self.nrCurrent > 0 then
			self.nrLines = self.nrLines + 1
			self.lines[self.nrLines] =
				'<span style="white-space:nowrap;">' ..
				table.concat(self.current) ..
				'</span>'
			self.nrCurrent = 0
			self.current = {}
		end
	end,
	text = function (self)
		self:purgeCurrent()
		return table.concat(self.lines, '<br />')
	end,
}
Group.__index = Group

local keyitems = {
	['/']    = " / ",
	['+']    = " + ",
	['or']   = " or ",
	['seen'] = " (seen) ",
	['br']   = BREAK,
}

local function expand(item, wantLink)
	-- Return text after expanding given item.
	-- Throw an error if item is not recognized.
	local function quit(reason)
		reason = reason or 'has an invalid definition'
		error('Particle "' .. item .. '" ' .. reason, 0)
	end
	local function su(sup, sub, align)
		local options = {
			align = align,
			lineHeight = '1.0em',
		}
		return supsub(sup, sub, options)
	end
	local kw = keyitems[item]
	if kw then
		return kw
	end
	if item:sub(1, 1) == '_' then
		return item:gsub('_', ' ')
	end
	if item:sub(1, 1) == '(' and item:sub(-1) == ')' then
		return item  -- no space wanted
	end
	local particle = particleTable[item:lower()] or quit('is not defined')
	local prefix, suffix
	if wantLink then
		prefix = '[[' .. (particle.link or quit('has no link defined')) .. '|'
		suffix = ']]'
	else
		prefix = ''
		suffix = ''
	end
	local symbol = particle[1] or quit('has no symbol defined')
	if particle.anti then
		symbol = '<span style="text-decoration:overline;">' .. symbol .. '</span>'
	end
	return
		prefix ..
		su(particle.TL, particle.BL, 'r') ..
		symbol ..
		su(particle.TR, particle.BR, 'l') ..
		suffix
end

local function main(frame, wantLink)
	-- Arguments are passed using #invoke in an article to avoid double-expansion.
	local sandbox = frame:getTitle():find('sandbox', 1, true) and '/sandbox' or ''
	particleTable = mw.loadData('Module:Particles/data' .. sandbox).particles
	supsub = require('Module:Su')._main
	local group = Group.new()
	for _, arg in ipairs(frame.args) do
		arg = stripToNil(arg)
		if arg then
			group:add(expand(arg, wantLink))
		end
	end
	return group:text()
end

local function link(frame)
	return main(frame, true)
end

local function nolink(frame)
	return main(frame, false)
end

return {
	link = link,
	nolink = nolink,
}