Difference between revisions of "Module:TaxonItalics/sandbox"
Jump to navigation
Jump to search
blackwiki>Peter coxhead (escaped -) |
blackwiki>Peter coxhead (different handling of local functions) |
||
| Line 21: | Line 21: | ||
local p = {} | local p = {} | ||
| − | -- local functions | + | local l = {} -- used to store purely local functions |
| − | |||
| − | |||
| − | |||
| − | |||
--connecting terms in three part names (e.g. Pinus sylvestris var. sylvestris) | --connecting terms in three part names (e.g. Pinus sylvestris var. sylvestris) | ||
| Line 97: | Line 93: | ||
closing parenthesis to be included. | closing parenthesis to be included. | ||
=============================================================================]] | =============================================================================]] | ||
| − | function abbreviate(str) | + | function l.abbreviate(str) |
local result = "" | local result = "" | ||
local hasParentheses = false | local hasParentheses = false | ||
| Line 157: | Line 153: | ||
words[3] = '<span style="font-style:normal;">' .. cTerms3[words[3]] .. '</span>' | words[3] = '<span style="font-style:normal;">' .. cTerms3[words[3]] .. '</span>' | ||
if abbreviated then | if abbreviated then | ||
| − | words[1] = abbreviate(words[1]) | + | words[1] = l.abbreviate(words[1]) |
| − | words[2] = abbreviate(words[2]) | + | words[2] = l.abbreviate(words[2]) |
end | end | ||
result = words[1] .. " " .. words[2] .. " " .. words[3] .. " " .. words[4] | result = words[1] .. " " .. words[2] .. " " .. words[3] .. " " .. words[4] | ||
| Line 166: | Line 162: | ||
words[2] = '<span style="font-style:normal;">' .. cTerms2[words[2]] .. '</span>' | words[2] = '<span style="font-style:normal;">' .. cTerms2[words[2]] .. '</span>' | ||
if abbreviated then | if abbreviated then | ||
| − | words[1] = abbreviate(words[1]) | + | words[1] = l.abbreviate(words[1]) |
end | end | ||
result = words[1] .. " " .. words[2] .. " " .. words[3] | result = words[1] .. " " .. words[2] .. " " .. words[3] | ||
| Line 173: | Line 169: | ||
if abbreviated then | if abbreviated then | ||
if #words > 1 then | if #words > 1 then | ||
| − | result = abbreviate(words[1]) | + | result = l.abbreviate(words[1]) |
for i = 2, #words-1, 1 do | for i = 2, #words-1, 1 do | ||
| − | result = result .. " " .. abbreviate(words[i]) | + | result = result .. " " .. l.abbreviate(words[i]) |
end | end | ||
result = result .. " " .. words[#words] | result = result .. " " .. words[#words] | ||
| Line 208: | Line 204: | ||
or page title. | or page title. | ||
=============================================================================]] | =============================================================================]] | ||
| − | function isItalic(frame, name, taxonName, rank, virus) | + | function l.isItalic(frame, name, taxonName, rank, virus) |
local res = false | local res = false | ||
if name == taxonName then | if name == taxonName then | ||
| Line 236: | Line 232: | ||
local rank = frame.args[3] or '' | local rank = frame.args[3] or '' | ||
local virus = frame.args[4] or 'no' | local virus = frame.args[4] or 'no' | ||
| − | return doItalicizeIfRequired(frame, taxoboxName, taxonName, rank, virus) | + | return l.doItalicizeIfRequired(frame, taxoboxName, taxonName, rank, virus) |
end | end | ||
| Line 242: | Line 238: | ||
Local utility function to do the italicization of a taxobox name. | Local utility function to do the italicization of a taxobox name. | ||
=============================================================================]] | =============================================================================]] | ||
| − | function doItalicizeIfRequired(frame, taxoboxName, taxonName, rank, virus) | + | function l.doItalicizeIfRequired(frame, taxoboxName, taxonName, rank, virus) |
local res = taxoboxName | local res = taxoboxName | ||
| − | if isItalic(frame, taxoboxName, taxonName, rank, virus) then | + | if l.isItalic(frame, taxoboxName, taxonName, rank, virus) then |
res = p.italicizeTaxonName(taxoboxName, false, false) | res = p.italicizeTaxonName(taxoboxName, false, false) | ||
end | end | ||
| Line 258: | Line 254: | ||
local rank = frame.args[3] or '' | local rank = frame.args[3] or '' | ||
local virus = frame.args[4] or 'no' | local virus = frame.args[4] or 'no' | ||
| − | return doIsItalicTitle(frame, pageName, taxonName, rank, virus) | + | return l.doIsItalicTitle(frame, pageName, taxonName, rank, virus) |
end | end | ||
| Line 264: | Line 260: | ||
Local utility function that actually determines if the title should be italic. | Local utility function that actually determines if the title should be italic. | ||
=============================================================================]] | =============================================================================]] | ||
| − | function doIsItalicTitle(frame, pageName, taxonName, rank, virus) | + | function l.doIsItalicTitle(frame, pageName, taxonName, rank, virus) |
local res = '' | local res = '' | ||
pageName = frame:expandTemplate{ title = 'Template:PAGENAMEBASE', args = { pageName } } | pageName = frame:expandTemplate{ title = 'Template:PAGENAMEBASE', args = { pageName } } | ||
| − | if isItalic(frame, pageName, taxonName, rank, virus) then | + | if l.isItalic(frame, pageName, taxonName, rank, virus) then |
res = 'yes' | res = 'yes' | ||
end | end | ||
Revision as of 13:06, 8 April 2019
Documentation for this module may be created at Module:TaxonItalics/sandbox/doc
--[[=========================================================================
Italicize a taxon name appropriately by invoking italicizeTaxonName.
The algorithm used is:
* If the name has italic markup at the start or the end, do nothing.
* Else
* Remove (internal) italic markup.
* If the name is made up of four words and the third word is a
botanical connecting term, de-italicize the connecting term and add italic
markup to the outside of the name.
* Else if the name is made up of three words and the second word is a
botanical connecting term or a variant of "cf.", de-italicize the
connecting term and add italic markup to the outside of the name.
* Else just add italic markup to the outside of the name.
The module also:
* Ensures that the hybrid symbol, ×, and parentheses are not italicized
* Has an option to abbreviate all parts of taxon names other than the last
to the first letter (e.g. "Pinus sylvestris var. sylvestris" becomes
"P. s. var. sylvestris").
* Has an option to wikilink the italicized name to the input name.
=============================================================================]]
local p = {}
local l = {} -- used to store purely local functions
--connecting terms in three part names (e.g. Pinus sylvestris var. sylvestris)
local cTerms3 = {
--subsp.
subspecies = "subsp.",
["subsp."] = "subsp.",
subsp = "subsp.",
["ssp."] = "subsp.",
ssp = "subsp.",
--var.
varietas = "var.",
["var."] = "var.",
var = "var.",
--subvar.
subvarietas = "subvar.",
["subvar."] = "subvar.",
subvar = "subvar.",
--f.
forma = "f.",
["f."] = "f.",
f = "f.",
--subf.
subforma = "subf.",
["subf."] = "subf.",
subf = "subf."
}
--connecting terms in two part names (e.g. Pinus sect. Pinus)
local cTerms2 = {
--subg.
subgenus = "subg.",
["subg."] = "subg.",
subg = "subg.",
--sect.
section = "sect.",
["sect."] = "sect.",
sect = "sect.",
--subsect.
subsection = "subsect.",
["subsect."] = "subsect.",
subsect = "subsect.",
--ser.
series = "ser.",
["ser."] = "ser.",
ser = "ser.",
--subser.
subseries = "subser.",
["subser."] = "subser.",
subser = "subser.",
--cf.
cf = "cf.",
["cf."] = "cf.",
["c.f."] = "cf."
}
--[[=========================================================================
Main function to italicize a taxon name appropriately.
=============================================================================]]
function p.main(frame)
local name = frame.args[1] or ''
local linked = frame.args['linked'] == 'yes'
local abbreviated = frame.args['abbreviated'] == 'yes'
return p.italicizeTaxonName(name, linked, abbreviated)
end
--[[=========================================================================
Utility local function to abbreviate an input string to its first character
followed by ".".
Both "×" and an HTML entity at the start of the string are skipped over in
determining first character, as is an opening parenthesis, which causes a
closing parenthesis to be included.
=============================================================================]]
function l.abbreviate(str)
local result = ""
local hasParentheses = false
if mw.ustring.len(str) < 2 then
--single character strings are left unchanged
result = str
else
--skip over an opening parenthesis that could be present at the start of the string
if mw.ustring.sub(str,1,1) == "(" then
hasParentheses = true
result = "("
str = mw.ustring.sub(str,2,mw.ustring.len(str))
end
--skip over a hybrid symbol that could be present at the start of the string
if mw.ustring.sub(str,1,1) == "×" then
result = "×"
str = mw.ustring.sub(str,2,mw.ustring.len(str))
end
--skip over an HTML entity that could be present at the start of the string
if mw.ustring.sub(str,1,1) == "&" then
local i,dummy = mw.ustring.find(str,";",2,plain)
result = result .. mw.ustring.sub(str,1,i)
str = mw.ustring.sub(str,i+1,mw.ustring.len(str))
end
--if there's anything left, reduce it to its first character plus ".",
--adding the closing parenthesis if required
if str ~= "" then
result = result .. mw.ustring.sub(str,1,1) .. "."
if hasParentheses then result = result .. ")" end
end
end
return result
end
--[[=========================================================================
The function which does the italicization.
=============================================================================]]
function p.italicizeTaxonName(name, linked, abbreviated)
local italMarker = "''"
-- begin by tidying the input name: trim; replace any use of the HTML
-- italic tags by Wikimedia markup; replace any alternatives to the hybrid
-- symbol by the symbol itself; prevent the hybrid symbol being treated as
-- a 'word' by converting a following space to the HTML entity
name = string.gsub(mw.text.trim(name), "</?i>", italMarker)
name = string.gsub(string.gsub(name, "×", "×"), "×", "×")
name = string.gsub(name, "</?span.->", "") -- remove any span markup
name = string.gsub(name, "× ", "× ")
-- now italicize and abbreviate if required
local result = name
if name ~= '' then
if string.sub(name,1,2) == "''" or string.sub(name,-2) == "''" then
-- do nothing if the name already has italic markers at the start or end
else
name = string.gsub(name, "''", "") -- first remove any internal italics
local words = mw.text.split(name, " ", true)
if #words == 4 and cTerms3[words[3]] then
-- the third word of a four word name is a connecting term
-- ensure the connecting term isn't italicized
words[3] = '<span style="font-style:normal;">' .. cTerms3[words[3]] .. '</span>'
if abbreviated then
words[1] = l.abbreviate(words[1])
words[2] = l.abbreviate(words[2])
end
result = words[1] .. " " .. words[2] .. " " .. words[3] .. " " .. words[4]
elseif #words == 3 and cTerms2[words[2]] then
-- the second word of a three word name is a connecting term
-- ensure the connecting term isn't italicized
words[2] = '<span style="font-style:normal;">' .. cTerms2[words[2]] .. '</span>'
if abbreviated then
words[1] = l.abbreviate(words[1])
end
result = words[1] .. " " .. words[2] .. " " .. words[3]
else
-- not a name as above; only deal with abbreviation
if abbreviated then
if #words > 1 then
result = l.abbreviate(words[1])
for i = 2, #words-1, 1 do
result = result .. " " .. l.abbreviate(words[i])
end
result = result .. " " .. words[#words]
end
else
result = name
end
end
-- deal with any hybrid symbol as it should not be italicized
result = string.gsub(result, "×", '<span style="font-style:normal;">×</span>')
-- deal with any parentheses as they should not be italicized
result = string.gsub(string.gsub(result,"%(",'<span style="font-style:normal;">(</span>'),"%)",'<span style="font-style:normal;">)</span>')
-- any question marks surrounded by spans can have the spans joined
result = string.gsub(result,'</span>%?<span style="font%-style:normal;">','?')
-- add outside markup
if linked then
if result ~= name then
result = "[[" .. name .. "|" .. italMarker .. result .. italMarker .. "]]"
else
result = italMarker .. "[[" .. name .. "]]" .. italMarker
end
else
result = italMarker .. result .. italMarker
end
end
end
return result
end
--[[=========================================================================
Local utility function to determine whether to italicize a taxobox name
or page title.
=============================================================================]]
function l.isItalic(frame, name, taxonName, rank, virus)
local res = false
if name == taxonName then
local italicRank = frame:expandTemplate{ title = 'Template:Is italic taxon', args = { rank, virus=virus } }
if italicRank == 'yes' then
res = true
end
else
rank = string.lower(rank)
if (rank == 'species') and string.match(taxonName, '^'..name) then
res = true
end
end
return res
end
--[[=========================================================================
Function to italicize a taxobox name. It should be italicized if:
* the rank is one that is italicized, AND
* the taxobox name is the same as the taxon name, OR
* the rank is species or below and the taxobox name is the same as the genus
name
=============================================================================]]
function p.italicizeIfRequired(frame)
local taxoboxName = frame.args[1] or ''
local taxonName = frame.args[2] or ''
local rank = frame.args[3] or ''
local virus = frame.args[4] or 'no'
return l.doItalicizeIfRequired(frame, taxoboxName, taxonName, rank, virus)
end
--[[=========================================================================
Local utility function to do the italicization of a taxobox name.
=============================================================================]]
function l.doItalicizeIfRequired(frame, taxoboxName, taxonName, rank, virus)
local res = taxoboxName
if l.isItalic(frame, taxoboxName, taxonName, rank, virus) then
res = p.italicizeTaxonName(taxoboxName, false, false)
end
return res
end
--[[=========================================================================
Function to determine if a page title should be italicized
=============================================================================]]
function p.isItalicTitle(frame)
local pageName = frame.args[1] or ''
local taxonName = frame.args[2] or ''
local rank = frame.args[3] or ''
local virus = frame.args[4] or 'no'
return l.doIsItalicTitle(frame, pageName, taxonName, rank, virus)
end
--[[=========================================================================
Local utility function that actually determines if the title should be italic.
=============================================================================]]
function l.doIsItalicTitle(frame, pageName, taxonName, rank, virus)
local res = ''
pageName = frame:expandTemplate{ title = 'Template:PAGENAMEBASE', args = { pageName } }
if l.isItalic(frame, pageName, taxonName, rank, virus) then
res = 'yes'
end
return res
end
return p