The module is primarily intended for use by the automated taxobox system. It supports the correct italicization of scientific names. Botanical (ICNafp) names may contain "connecting terms"; these must not be italicized. The hybrid symbol, ×, should also not be italicized. The module optionally wikilinks and abbreviates italicized names.
For non-virus taxa, italics are used at the rank of genus or below. The module does not decide whether a scientific name should be italicized. Use {{Is italic taxon}} for this purpose.
Usage
{{#invoke:TaxonItalics|main|TAXON_NAME}} – italicizes a taxon name
{{#invoke:TaxonItalics|main|TAXON_NAME|linked=yes}} – italicizes a taxon name, wikilinking the italicized output to the unchanged input
{{#invoke:TaxonItalics|main|TAXON_NAME|abbreviated=yes}} – italicizes a taxon name, abbreviating all but the last part to the first letter
{{#invoke:TaxonItalics|main|TAXON_NAME|dab=yes}} – italicizes a taxon name, treating any parenthesized part as a disambiguation term, and not italicizing it
The parameters can be combined. It can also be used via {{Taxon italics}}.
Aster ericoides var. ericoides → Aster ericoides var. ericoides
A. ericoides varietas ericoides → A. ericoides var. ericoides
A. e. subvar. ericoides → A. e. subvar. ericoides
Botanical names may contain only one infraspecific epithet; a string like "Fragaria vesca subsp. vesca f. semperflorens" is a classification, not a name, and is not handled by the module.
--[[=========================================================================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, as well as any string inside parentheses if dab is true. * 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.=============================================================================]]localp={}locall={}-- used to store purely local functions--connecting terms in three part names (e.g. Pinus sylvestris var. sylvestris)localcTerms3={--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)localcTerms2={--subg.subgenus="subg.",["subgen."]="subg.",["subg."]="subg.",subg="subg.",--supersect.supersection="supersect.",["supersect."]="supersect.",supersect="supersect.",--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. For the purpose of theparameters, see p.italicizeTaxonName().=============================================================================]]functionp.main(frame)localname=frame.args[1]or''locallinked=frame.args['linked']=='yes'localabbreviated=frame.args['abbreviated']=='yes'localdab=frame.args['dab']=='yes'returnp.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.=============================================================================]]functionl.abbreviate(str)localresult=""localhasParentheses=falselocalisQuoted=falseifmw.ustring.len(str)<2then--single character strings are left unchangedresult=strelse--skip over an opening parenthesis that could be present at the start of the stringifmw.ustring.sub(str,1,1)=="("thenhasParentheses=trueresult="("str=mw.ustring.sub(str,2,mw.ustring.len(str))elseifmw.ustring.sub(str,1,1)=='"'thenisQuoted=trueresult='"'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 stringifmw.ustring.sub(str,1,1)=="×"thenresult="×"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 stringifmw.ustring.sub(str,1,1)=="&"thenlocali,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 requiredifstr~=""thenresult=result..mw.ustring.sub(str,1,1).."."ifhasParenthesesthenresult=result..")"elseifisQuotedthenresult=result..'"'endendendreturnresultend--[[=========================================================================The function which does the italicization. Parameters: name (string) – the taxon name to be processed linked (boolean) – should a wikilink be generated? abbreviated (boolean) – should the first parts of the taxon name be reduced to capital letters? dab (boolean) – should any parenthesized part be treated as a disambiguation term and left unitalicized?=============================================================================]]functionp.italicizeTaxonName(name,linked,abbreviated,dab)name=mw.text.trim(name)-- if the name begins with '[', then assume formatting is presentifmw.ustring.sub(name,1,1)=='['thenreturnnameend-- 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 entitylocalitalMarker="''"name=string.gsub(mw.text.trim(name),"</?i>",italMarker)name=string.gsub(string.gsub(name,"×","×"),"×","×")name=string.gsub(name,"</?span.->","")-- remove any span markupname=string.gsub(name,"× ","× ")-- now italicize and abbreviate if requiredlocalresult=nameifname~=''thenifstring.sub(name,1,2)==italMarkerorstring.sub(name,-2)==italMarkerthen-- do nothing if the name already has italic markers at the start or endelsename=string.gsub(name,italMarker,"")-- first remove any internal italicslocalwords=mw.text.split(name," ",true)if#words==4andcTerms3[words[3]]then-- the third word of a four word name is a connecting term-- ensure the connecting term isn't italicizedwords[3]='<span style="font-style:normal;">'..cTerms3[words[3]]..'</span>'ifabbreviatedthenwords[1]=l.abbreviate(words[1])words[2]=l.abbreviate(words[2])endresult=words[1].." "..words[2].." "..words[3].." "..words[4]elseif#words==3andcTerms2[words[2]]then-- the second word of a three word name is a connecting term-- ensure the connecting term isn't italicizedwords[2]='<span style="font-style:normal;">'..cTerms2[words[2]]..'</span>'ifabbreviatedthenwords[1]=l.abbreviate(words[1])endresult=words[1].." "..words[2].." "..words[3]else-- not a name as above; only deal with abbreviationifabbreviatedthenif#words>1thenresult=l.abbreviate(words[1])fori=2,#words-1,1doresult=result.." "..l.abbreviate(words[i])endresult=result.." "..words[#words]endelseresult=nameendend-- deal with any hybrid symbol as it should not be italicizedresult=string.gsub(result,"×",'<span style="font-style:normal;">×</span>')-- deal with any parentheses as they should not be italicizedifdabthenresult=string.gsub(string.gsub(result,"%(",'<span style="font-style:normal;">('),"%)",')</span>')elseresult=string.gsub(string.gsub(result,"%(",'<span style="font-style:normal;">(</span>'),"%)",'<span style="font-style:normal;">)</span>')end-- any question marks surrounded by spans can have the spans joinedresult=string.gsub(result,'</span>%?<span style="font%-style:normal;">','?')-- add outside markupiflinkedthenifresult~=namethenresult="[["..name.."|"..italMarker..result..italMarker.."]]"elseresult=italMarker.."[["..name.."]]"..italMarkerendelseresult=italMarker..result..italMarkerendendendreturnresultend--[[=========================================================================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.=============================================================================]]functionp.hasCT(frame)returnp.hasConnectingTerm(frame.args[1]or'')endfunctionp.hasConnectingTerm(name)localwords=mw.text.split(name," ",true)if#words==4andcTerms3[words[3]]thenreturntrueelseif#words==3andcTerms2[words[2]]thenreturntrueelsereturnfalseendendreturnp