Module:TaxonItalics/sandbox explained

--

local p = local l = -- used to store purely local functions

--connecting terms in three part names (e.g. Pinus sylvestris var. sylvestris)local cTerms3 = --connecting terms in two part names (e.g. Pinus sect. Pinus)local cTerms2 =

--

Main function to italicize a taxon name appropriately. For the purpose of theparameters, see p.italicizeTaxonName.

function p.main(frame) local name = frame.args[1] or local linked = frame.args['linked']

'yes' local abbreviated = frame.args['abbreviated']

'yes' local dab = frame.args['dab']

'yes' return p.italicizeTaxonName(name, linked, abbreviated, dab)end

--

Utility local function to abbreviate an input string to its first characterfollowed by ".".Both "×" and an HTML entity at the start of the string are skipped over indetermining first character, as is an opening parenthesis and an opening ",which cause a matching closing character to be included.

function l.abbreviate(str) local result = "" local hasParentheses = false local isQuoted = 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)) elseif mw.ustring.sub(str,1,1)

'"' then isQuoted = 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 or quote if required if str ~= "" then result = result .. mw.ustring.sub(str,1,1) .. "." if hasParentheses then result = result .. ")" elseif isQuoted then result = result .. '"' end end end return resultend

--function p.italicizeTaxonName(name, linked, abbreviated, dab) name = mw.text.trim(name) -- if the name begins with '[', then assume formatting is present if mw.ustring.sub(name,1,1) == '[' then return name end -- otherwise begin by replacing any use of the HTML italic tags -- by Wikimedia markup; replace any entity 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 local italMarker = "''" name = string.gsub(mw.text.trim(name), "</?i>", italMarker) name = string.gsub(string.gsub(name, "&#215;", "×"), "&times;", "×") name = string.gsub(name, "</?span.->", "") -- remove any span markup name = string.gsub(name, "× ", "×&#32;") -- now italicize and abbreviate if required local result = name if name ~= '' then if string.sub(name,1,2) == italMarker or string.sub(name,-2) == italMarker then -- do nothing if the name already has italic markers at the start or end else name = string.gsub(name, italMarker, "") -- 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] = '

' .. cTerms3[words[3]] .. '' 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] = '

' .. cTerms2[words[2]] .. '' if abbreviated then words[1] = l.abbreviate(words[1]) end result = words[1] .. " " .. words[2] .. " " .. words[3] elseif abbreviated then -- not a name as above; only deal with abbreviation 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 -- deal with any hybrid symbol as it should not be italicized result = string.gsub(result, "×", '×') -- deal with any parentheses as they should not be italicized if dab then result = string.gsub(string.gsub(result,"%(",'('),"%)",')') else result = string.gsub(string.gsub(result,"%(",'('),"%)",')') end -- any question marks surrounded by spans can have the spans joined result = string.gsub(result,'%?','?') -- add outside markup if linked then if result ~= name then result = "" .. italMarker .. result .. italMarker .. "" else result = italMarker .. "" .. name .. "" .. italMarker end else result = italMarker .. result .. italMarker end end end return resultend

--

Utility function used by other modules to check if a connecting term ispresent in a name. The value of name is assumed to be plain text.

function p.hasCT(frame) return p.hasConnectingTerm(frame.args[1] or )end function p.hasConnectingTerm(name) local words = mw.text.split(name, " ", true) return (#words

4 and cTerms3[words[3]]) or (#words

3 and cTerms2[words[2]])end return p