Module:WPSHIPS utilities
To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them.
ship_name_format
This function attempts to apply appropriate formatting to unformatted ship names. The formats supported are:
- <(prefix)> <name> <(disambiguator)> where:
- <(prefix)> (optional) – one from a list of defined prefixes commonly used for ships (ARA, HMS, USS, etc.); rendered in upright font
- <name> – the ship's proper name; rendered in italic font
- <(disambiguator)> (optional) – typically the ship's hull or pennant number, or other disambiguator; always contained in parentheses; rendered in upright font
- <name> <(disambiguator)> where:
- <name> – the ship's proper name; rendered in italic font
- <(disambiguator)> (required) – the ship's hull or pennant number or a recognized ship-type descriptor; always contained in parentheses; rendered in upright font
- hull and pennant numbers take two basic forms
- uppercase letters, possibly followed by a space or hyphen, followed by digits (SSBN-659, R07, ON 688)
- digits, possibly followed by a space or hyphen, followed by uppercase letters (401B)
- hull and pennant numbers take two basic forms
- <nationality> <ship type> <name> <(disambiguator)> where:
- <nationality> – one- or two- word nation name in adjectival form (Dutch, East Timorese, French, Ottoman, etc.); rendered in upright font
- <ship type> – one from a list of one- to four-word phrases that describes a ship's type (aviso, brig sloop, landing ship medium, ship of the line); rendered in upright font
- <name> – the ship's proper name; rendered in italic font
- <(disambiguator)> (optional) – typically the ship's hull or pennant number, or other disambiguator; always contained in parentheses; rendered in upright font
The function will also attempt to render ship-class names when the name is in the form:
- <name>-class <ship type> where:
- <name> – the class' proper name; rendered in italic font according to the setting of
|sclass= - <ship type> – a phrase that describes a ship's type; rendered in upright font
- <name> – the class' proper name; rendered in italic font according to the setting of
Lists
The function relies on three lists to accomplish its task. These lists are:
ship_prefix_list– a list of commonly used ship prefixes initially taken from{{ship prefix}}; these are usually, but not always wholly uppercasenationality_list– a list of nation names in their adjectival form; these are always capitalized; always one or two wordsship_type_list– a list ship-type descriptor phrases; these are usually, but not always wholly lowercase; always one to two words
To add to any of these lists, the form is:
['addition'] = true,
the trailing comma is important. See the instructions that accompany each list for limitations and implementation details.
Usage
The minimal form is:
{{#invoke:WPSHIPS_utilities|ship_name_format|name=}}
Parameters
The function requires one parameter and supports several optional parameters.
- |name= – (required) the name to format
- |dab=none – for use with
|infobox caption=nodabin{{infobox ship begin}}, excludes a disambiguator from the formatted name - |sclass=2 – for use with
{{DISPLAYTITLE}}and with|infobox caption=yesor|infobox caption=nodabin{{infobox ship begin}}, when the class is not named for a member of the class; causes the class name to be rendered in upright font - |adj=off – for use in ship-class articles with
|infobox caption=yesor|infobox caption=nodabin{{infobox ship begin}}, formats the class name in its noun form and excludes the ship type phrase and disambiguator - |showerrs=yes – debug tool; not currently supported in any templates;
Wrapper template
- {{Ship name format }} is a wrapper template to make it easier for editors to label ships in the main body of articles or as input to templates or modules. It supports the same parameters as the module.
- In most cases, {{ship }} is preferred over using this wrapper template or this module.
- It is useful to set the DISPLAYTITLE of redirects, disambiguation pages, or other pages named after ships which do not use one of the other "ships" templates such as {{Infobox ship begin }} to do this. Example:
{{DISPLAYTITLE:{{ship_name_format|name={{FULLPAGENAME}}}}}} - Other templates and modules should not transclude this template, instead they should call the module directly.
- Wikipedia pages should not transclude this template many times, as it may cause the page to exceed Wikipedia's template limits. Those pages should invoke the module directly.
wpsu.navsource()
This function is the driver for {{navsource}}. The function assembles an external wikilink from known fragments and positional parameter {{{1}}}. A ship name provided in positional parameter {{{2}}} is formatted using ship_name_format(). New with this implementation of {{navsource}} is the addition of |showerrs=. The {{#invoke:}} in the template defaults to |showerrs=yes which can be overridden by setting |showerrs=no in the template.
wpsu.hnsa()
Similar to {{navsource}}, this code supports {{hnsa}} by attempting to construct a link to a ship article at the Historic Naval Ships Association website.
The template has the form:
{{hnsa|<page>|<name>}}
where:
- <page> is the name of the page from the url
http://hnsa.org/hnsa-ships/<page> - <name> (optional) is the name of the ship; if left blank, the template uses the current page title; if a ship name, it is formatted using
do_ship_name_format()
from which this code produces:
[http://hnsa.org/hnsa-ships/<page> <name>] at Historic Naval Ships Association
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.
require('strict') localget_args=require('Module:Arguments').getArgs; localstyles=require('Module:WPMILHIST Infobox style');-- infobox css localdata=mw.loadData('Module:WPSHIPS utilities/data'); localnamespace=mw.title.getCurrentTitle().namespace;-- used for categorization --[[--------------------------< E R R O R _ M A P _ T >-------------------------------------------------------- ]] localerror_map_t={-- [1] is error message; [2] is error category synonymous={'has synonymous parameter','Category:Pages using infobox ship with synonymous parameters'}; missing={'missing required parameter: %s','Category:WPSHIPS: sclass and sclass2 errors'}, format={'invalid format code: %s. Should be 0–5, or blank','Category:WPSHIPS: sclass and sclass2 errors'}, missing_name={'missing name','Category:WPSHIPS: Template Ship parameter errors'}, missing_dab={'missing disambiguator','Category:WPSHIPS: Template Ship parameter errors'}, missing_prefix={'missing prefix','Category:WPSHIPS: Template Ship parameter errors'}, invalid_control={'invalid control parameter: %s','Category:WPSHIPS: Template Ship parameter errors'}, } --[[--------------------------< E R R O R _ M S G _ M A K E >-------------------------------------------------- assembles an error message from message text and category in <error_map_t>. creates a help link to the category page; categorizes only main and template namespaces. <no_cat> disables categorization for those templates that support it; to disable categorization set <no_cat> true ]] localfunctionerror_msg_make(msg_idx,template,detail,no_cat,link_template_name) localout={}; localcategory; table.insert(out,'<span style=\"font-size: 100%; font-style: normal;\" class=\"error\">Error: ');--TODO: simplify? iftemplatethen iflink_template_namethen table.insert(out,table.concat({'{{[[Template:',template,'|',template,']]}} '})); else table.insert(out,table.concat({'{{',template,'}} '}));-- TODO: get template names for synonymous parameter errors end end table.insert(out,string.format(error_map_t[msg_idx][1],detail));-- build error message from base + <detail> table.insert(out,table.concat({' ([[:',error_map_t[msg_idx][2],'|help]])'}));-- help text on category pages; TODO: help text on template pages also? table.insert(out,'</span>'); if(0==namespaceor10==namespace)andnotno_catthen-- categorize in article space (and template space to take care of broken usages) table.insert(out,table.concat({'[[',error_map_t[msg_idx][2],']]'})); end returntable.concat(out);-- make a big string and done end --[[--------------------------< I S _ S E T >------------------------------------------------------------------ Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string. ]] localfunctionis_set(var) returnnot(var==nilorvar==''); end --[[--------------------------< S I Z E O F _ S H I P _ T Y P E >---------------------------------------------- Returns the size in words of ship type. Inputs are the fragment table, the number of elements in the fragment table, and the number of words that make up nationality. The number of fragments (words) in a ship name dictate the possible sizes of ship type. If nationality takes one fragment, and ship type takes four fragments, then the minimum number of fragments in a composite ship name is: 5 = 1 (nationality) + 3 (ship type) + 1 (ship name) (same as 4 fragments (words) after nationality) This function starts at the longest possible series of fragments that might be ship type. This order is important becuase some ship types might begin with similar fragments: 'ship' and 'ship of the line'. Starting with the least possible series of fragments (1) would find 'ship' and make 'of the line' part of the italicized name. Returns 0 if there is no recognizable ship type. ]] localfunctionsizeof_ship_type(frag,frag_len,nat_len) localship_type; if5<=(frag_len-nat_len)then-- must have at least five fragments after nationality for four-word ship type ship_type=table.concat(frag,' ',nat_len+1,nat_len+4);-- four-word ship type ifdata.ship_type_t[ship_type]then return4; end end if4<=(frag_len-nat_len)then-- must have at least four fragments after nationality for three-word ship type ship_type=table.concat(frag,' ',nat_len+1,nat_len+3);-- three-word ship type ifdata.ship_type_t[ship_type]then return3; end end if3<=(frag_len-nat_len)then-- must have at least three fragments after nationality for two-word ship type ship_type=table.concat(frag,' ',nat_len+1,nat_len+2);-- two-word ship type ifdata.ship_type_t[ship_type]then return2; end end if2<=(frag_len-nat_len)then-- must have at least two fragments after nationality for one-word ship type ifdata.ship_type_t[frag[nat_len+1]]then-- one-word ship type return1; end end return0;-- no recognizable ship type end --[[--------------------------< S I Z E O F _ N A T I O N A L I T Y >------------------------------------------ This function the size (in words) of the nationality from the fragments table. Nationality may be one or two words that occupy the first one or two positions in the table. Returns the number of words that identify the nationality: 1 for French or German, etc. 2 for United States; 0 when table doesn't have a recognizable nationality ]] localfunctionsizeof_nationality(frag,frag_len) localnat=''; ifnotdata.nationality_t[frag[1]]then-- if not a one-word nationality if2<=frag_len-2then-- must have at least two fragments after nationality for minimal ship type and name nat=table.concat(frag,' ',1,2); ifdata.nationality_t[nat]then-- is it a two-word nationality? return2;-- yes else return0;-- no end end return0;-- not one-word and not enough fragments for two-word end return1;-- one-word nationality end --[[-------------------------< D O _ S H I P _ N A M E _ F O R M A T >----------------------------------------- This function applies correct styling to ship and ship-class names. These names are, for example, ship-article titles used by templates {{navsource}}, {{Infobox ship begin}}, where the article title is to be rendered with proper styling. This function requires one argument: |name= (required): a name is required; if missing or empty, this function returns an error message (may or may not be visible depending on where it is used) used in {{infobox ship begin}} to provide a value for {{DISPLAYTITLE:}} and to provide a value for |infobox caption= {{#invoke:WPSHIPS_utilities|ship_name_format|name={{PAGENAME}}}} Optional arguments to support {{infobox ship begin}}: |dab=none – displays ship name without parenthetical disambiguator; use when |infobox caption=nodab |sclass=2 – for ship classes only; displays class name without italics (parameter name is loosely similar to {{slcass2}} which does the same thing); use when |infobox caption=class |adj=off – for ship classes only; displays class name as a noun (no hyphen, no ship type); use when |infobox caption=class Arguments are passed in a table. to call this function locally: do_ship_name_format ({['name=name'], ['dab']=dab, ['sclass']=sclass, ['adj']=adj, ['showerrs']=showerrs}) or args = {['name=name'], ['dab']=dab, ['sclass']=sclass, ['adj']=adj, ['showerrs']=showerrs}; do_ship_name_format (args) The function returns the formatted name or, if unable to format the name, the original name and an unformatted error message. ]] localfunctiondo_ship_name_format(args) localname_sans_dab;-- the ship or class name without a trailing parenthetical dab localdab;-- the dab stripped from the name localfragments={};-- a table of words that make up name_sans_dab localship_type;-- a word or phrase that describes a ship localtype_len;-- the number of words that describe a ship localnat_len;-- the number of words used to specify a ship's nationality localname='';-- the reassembles and formatted ship name localerror_msg='';-- a repository for error messages if any -- args.name = mw.text.decode (args.name); -- replace html entities in title with their characters; doesn't work for & and & in prefix args.name=args.name:gsub("'","\'");-- replace html appostrophe with the character -- args.name = args.name:gsub ("&", "&"); -- args.name = args.name:gsub ("&", "&"); -- args.name = args.name:gsub ("&", "&"); ifargs.name:match('.+%-class%s+%a+')then-- if a ship-class fragments=mw.text.split(args.name,'-class');-- split at -class if'2'==args.sclassthen-- for DISPLAYTITLE and infobox caption when class not named for a member of the class if'off'==args.adjthen returnfragments[1]..' class';-- for infobox caption do noun form <name> class (no hyphen, no ship type) end returnargs.name;-- nothing to do so return original unformatted name end if'off'==args.adjthen return"''"..fragments[1].."'' class";-- for infobox caption do noun form <name> class (no hyphen, no ship type) end return"''"..fragments[1].."''-class"..fragments[2];-- and return formatted adjectival name end -- not a ship class so try to format a ship name name_sans_dab,dab=args.name:match('^(.+)%s+(%b())%s*$');-- split name into name_sans_dab and dab ifis_set(dab)then dab=' '..dab;-- insert a space for later reassembly else name_sans_dab=args.name;-- because without a dab, the string.match returns nil dab='';-- empty string for concatenation end fragments=mw.text.split(name_sans_dab,'%s');-- split into a table of separate words nat_len=sizeof_nationality(fragments,#fragments);-- get the number of words in the ship's nationality if0<nat_lenthen-- if not zero we have a valid nationality type_len=sizeof_ship_type(fragments,#fragments,nat_len);-- get the number of words in the ship type if0<type_lenthen-- if not zero, ship type is valid; nationality and type not italics, the rest is name name="''"..table.concat(fragments,' ',nat_len+type_len+1).."''";-- format name if'none'==args.dabthen-- for |infobox caption=nodab returnname;-- return the formatted name without the nationality or ship type or dab end name=table.concat(fragments,' ',1,nat_len+type_len).." "..name;-- assemble everything but dab else error_msg=' unrecognized ship type;';-- valid nationality, invalid ship type end elseifdata.ship_prefix_t[fragments[1]]then-- if the first fragment is a ship prefix name=table.remove(fragments,1);-- fetch it from the table name=name.." ''"..table.concat(fragments,' ').."''";-- assemble formatted name else error_msg=' no nationality or prefix;';-- invalid nationality and first word in ship name not a valid prefix end ifis_set(name)then-- name will be set if we were able to format it if'none'==args.dabthen-- for |infobox caption=nodab returnname;-- return the formatted name without the dab end returnname..dab;-- return the formatted name with the dab end ifis_set(dab)then ifdab:match('%(%u+[%- ]?%d+%)')or-- one or more uppercase letters, optional space or hyphen, one or more digits dab:match('%(%d+[%- ]?%u+%)')or-- one or more digits, optional space or hyphen, one or more uppercase letters dab:match('%(%u[%u%-]*%-%d+%)')or-- one or more uppercase letters with hyphens, a hyphen, one or more digits (e.g., T-AO-157) dab:match('%([12]%d%d%d%)')then-- four digits representing year in the range 1000–2999 name="''"..table.concat(fragments,' ').."''";-- format the name if'none'==args.dabthen-- for |infobox caption=nodab returnname;-- return the formatted name without the dab end returnname..dab;-- return the formatted name with the dab end -- last chance, is there a ship type in the dab? forkey,_inpairs(data.ship_type_t)do-- spin through the ship type list and see if there is a ship type (key) in the dab ifdab:find('%f[%a]'..key..'%f[^%a]')then-- avoid matches that are not whole word name="''"..table.concat(fragments,' ').."''";-- format the name if'none'==args.dabthen-- for |infobox caption=nodab returnname;-- return the formatted name without the dab end returnname..dab;-- return the formatted name with the dab end end error_msg=error_msg..' no ship type in dab;'; if'none'==args.dabthen-- for |infobox caption=nodab returntable.concat(fragments,' '),error_msg;-- return the unformatted name without the dab, and an error message end end returnargs.name,error_msg;-- return original un-formatted name with unformatted error message if any end --[[-------------------------< S H I P _ N A M E _ F O R M A T >----------------------------------------------- This function is the external interface to do_ship_name_format(). The function requires one parameter: |name= (required): a name is required; if missing or empty, this function returns an error message (may or may not be visible depending on where it is used) used in {{infobox ship begin}} to provide a value for {{DISPLAYTITLE:}} and to provide a value for |infobox caption= {{#invoke:WPSHIPS_utilities|ship_name_format|name={{PAGENAME}}}} Optional parameters to support {{infobox ship begin}}: |dab=none – displays ship name without parenthetical disambiguator; use when |infobox caption=nodab |sclass=2 – for ship classes only; displays class name without italics (parameter name is loosely similar to {{slcass2}} which does the same thing); use when |infobox caption=class |adj=off – for ship classes only; displays class name as a noun (no hyphen, no ship type); use when |infobox caption=class Other optional parameters: |showerrs=yes – marginally useful; can display error messages if the module invocation is not buried in a template Values from the above parameters are placed in a table and that table passed as an argument in the call to do_ship_name_format(). do_ship_name_format() returns two strings: a name and an error message. If do_ship_name_format() could format the name, it returns the formatted name and an empty string for the error message. If it could not format the name, do_ship_name_format() returns the original name and an error message. Formatting of the error message, in response to |showerrs=yes is the responsibility of the calling function. ]] localfunctionship_name_format(frame) localname='';-- destination of the formatted ship name localerror_msg='';-- destination of any error message ifnotis_set(frame.args.name)then-- if a ship name not provided if'yes'==frame.args.showerrsthen-- and we're supposed to show errors error_msg='<span style="font-size:100%; font-weight:normal" class="error">Empty name</span>';-- return an empty string error message if there is no name end else name,error_msg=do_ship_name_format(frame.args);-- get formatted name and error message ifis_set(error_msg)and'yes'==frame.args.showerrsthen-- if appropriate, show error message error_msg='<span style="font-size:100%; font-weight:normal" class="error">'..error_msg..'</span>'; else error_msg='';-- for concatenation end end returnname..error_msg;-- return name and error message end --[[--------------------------< H N S A >---------------------------------------------------------------------- Similar to {{navsource}}, this code supports {{hnsa}} by attempting to construct a link to a ship article at the the Historic Nava Ships Association website. The template has the form: {{hnsa|<page>|<name>}} where: <page> is the name of the page at http://hnsa.org/hnsa-ships/<page> <name> (optional) is the name of the ship; if left blank, the template uses the current page title; if a ship name, it is formatted from which this code produces: [http://hnsa.org/hnsa-ships/<page> <name>] at Historic Naval Ships Association ]] localfunctionhnsa(frame) localpframe=frame:getParent()-- get arguments from calling template frame localship_name=''; localerror_msg=''; localarticle_title=mw.title.getCurrentTitle().text;-- fetch the article title ifnotis_set(pframe.args[1])then return'<span style="font-size:100%; font-weight:normal" class="error">missing hsna page</span>'; end localfmt_params={['name']='',['showerrs']=nil}; ifis_set(pframe.args.showerrs)then-- if showerrs set in template, override showerrs in #invoke: fmt_params.showerrs=pframe.args.showerrs;-- template value else fmt_params.showerrs=frame.args.showerrs;-- invoke value end ifis_set(pframe.args[2])then fmt_params.name=pframe.args[2]; else fmt_params.name=article_title;-- use article title end ship_name,error_msg=do_ship_name_format(fmt_params); ifis_set(error_msg)andis_set(pframe.args[2])then-- if unable to format the name localescaped_name=pframe.args[2]:gsub("([%(%)%.%-])","%%%1");-- escape some of the Lua magic characters ifpframe.args[2]==article_titleor-- is name same as article title? nil~=article_title:find('%f[%a]'..escaped_name..'%f[%s]')or-- is name a word or words substring of article title? nil~=article_title:find('%f[%a]'..escaped_name..'$')then-- is name a word or words substring that ends article title? ship_name="''"..pframe.args[2].."''";-- non-standard 'name'; perhaps just the name without prefix and dab; error_msg='';-- unset because we think we have a name end end ifis_set(error_msg)and'yes'==fmt_params.showerrsthen error_msg='<span style="font-size:100%; font-weight:normal" class="error">'..error_msg..'</span>'; else error_msg='';-- unset so it doesn't diplay end localoutput={ '[http://www.hnsa.org/hnsa-ships/', pframe.args[1], '/ ', ship_name, '] at Historic Naval Ships Association', error_msg, } returntable.concat(output); end --[[--------------------------< N A V S O U R C E >------------------------------------------------------------ This version of the template {{navsource}} was added as a test vehicle for do_ship_name_format(). ]] localfunctionnavsource(frame) localpframe=frame:getParent()-- get arguments from calling template frame localship_name=''; localerror_msg=''; localarticle_title=mw.title.getCurrentTitle().text;-- fetch the article title ifnotis_set(pframe.args[1])then return'<span style="font-size:100%; font-weight:normal" class="error">missing navsource URLcode</span>'; end localfmt_params={['name']='',['showerrs']=nil}; ifis_set(pframe.args.showerrs)then-- if showerrs set in template, override showerrs in #invoke: fmt_params.showerrs=pframe.args.showerrs;-- template value else fmt_params.showerrs=frame.args.showerrs;-- invoke value end ifis_set(pframe.args[2])then fmt_params.name=pframe.args[2]; else fmt_params.name=article_title;-- use article title end ship_name,error_msg=do_ship_name_format(fmt_params); ifis_set(error_msg)andis_set(pframe.args[2])then-- if unable to format the name localescaped_name=pframe.args[2]:gsub("([%(%)%.%-])","%%%1");-- escape some of the Lua magic characters ifpframe.args[2]==article_titleor-- is name same as article title? nil~=article_title:find('%f[%a]'..escaped_name..'%f[%s]')or-- is name a word or words substring of article title? nil~=article_title:find('%f[%a]'..escaped_name..'$')then-- is name a word or words substring that ends article title? ship_name="''"..pframe.args[2].."''";-- non-standard 'name'; perhaps just the name without prefix and dab; error_msg='';-- unset because we think we have a name end end ifis_set(error_msg)and'yes'==fmt_params.showerrsthen error_msg='<span style="font-size:100%; font-weight:normal" class="error">'..error_msg..'</span>'; else error_msg='';-- unset so it doesn't diplay end localoutput={ '[http://www.navsource.net/archives/', pframe.args[1], '.htm Photo gallery] of ', ship_name, ' at NavSource Naval History', error_msg, } returntable.concat(output); end --[[--------------------------< _ S H I P >-------------------------------------------------------------------- This is a possible replacement for the template {{ship}}. It has better error detection and handling. ]] localfunction_ship(prefix,name,dab,control,unlinked_prefix,unlinked_whole,template,no_cat) localerror_msg=''; localcategory=''; ifnotis_set(control)then control='';-- if not provided, ensure that control is empty string for comparisons elseifcontrol:find('%-')then-- shortcut for |link=no when using a format control parameter ...|SSBN-659|-6}} same as ...|SSBN-659|6|link=no}} unlinked_whole=true;-- set the unlinked flag control=control:match('%d');-- strip out the hyphen end -- dispose of error conditions straight away ifnotis_set(name)then-- this is the only required parameter error_msg=error_msg_make('missing_name',template,'',no_cat,true); elseifnotis_set(dab)and('1'==controlor'3'==controlor'5'==control)then-- dab required when control value set to expect it error_msg=error_msg_make('missing_dab',template,'',no_cat,true); elseifnotis_set(prefix)and('5'==controlor'6'==control)then-- prefix required when control value set to expect it error_msg=error_msg_make('missing_prefix',template,'',no_cat,true); elseif'4'==controlthen-- displaying only the prefix error_msg=error_msg_make('invalid_control',template,control,no_cat,true); elseifis_set(control)then if('number'~=type(tonumber(control)))or(1~=control:len())or(1>tonumber(control)or6<tonumber(control))then-- control must be a single-digit number 1 through 6 error_msg=error_msg_make('invalid_control',template,control,no_cat,true); end elseifnotis_set(prefix)andunlinked_prefixthen-- prefix required when |up=yes error_msg=error_msg_make('missing_prefix',template,'',no_cat,true); end ifis_set(error_msg)then returnerror_msg; end locallink_name; locallink=''; ifis_set(prefix)then link=prefix..' '..name;-- begin assembling the article name (link) portion of the wikilink else link=name; end ifis_set(dab)then link=link..' ('..dab..')';-- wrap dab in parentheses end localtarget_object=mw.title.new(link).redirectTarget;-- if <link> points to a redirect iftarget_objectthen link=target_object.fullText;-- get the target title to avoid linking through the redirect end name="''"..name.."''";-- name is always italicized so do it now if'1'==controlthen link_name=dab;-- special case when displaying only the dab, don't wrap in parentheses end ifis_set(dab)then-- for all other cases that display dab if'5'==controlthen dab=" \'\'"..dab.."\'\'";-- for prefix with dab display HMS A1. italicize the dab else dab=' ('..dab..')';-- except for dab-only, all others display with parentheses end end ifnotis_set(control)then-- when control not set: prefix, name, and dab ifis_set(prefix)then link_name=prefix..' '..name..dab; else link_name=name..dab; end else-- when control is not 1 or none if'2'==controlthen-- name only link_name=name; elseif'3'==controlthen-- name and dab link_name=name..dab; elseif'5'==controlthen-- prefix and dab link_name=prefix..dab; elseif'6'==controlthen-- prefix and name link_name=prefix..' '..name; end end if'5'~=controland'6'~=controlandis_set(control)then unlinked_prefix=false;-- no prefix so don't try to unlink it end ifunlinked_wholethen returnlink_name;-- no linking desired so done elseifunlinked_prefixandis_set(prefix)then-- when there is a prefix to unlink link_name=link_name:gsub('^.- ','',1);-- remove the prefix and nbsp returnprefix..' [['..link..'|'..link_name..']]';-- add prefix and nbsp to front and done else return'[['..link..'|'..link_name..']]';-- construct the wikilink and done end end --[[--------------------------< S H I P >---------------------------------------------------------------------- This is a possible replacement for the template {{ship}}. It has better error detection and handling. This function is the externally accessible entry point for template {{ship}}, {{HMS}}, {{USS}}, etc {{#invoke:WPSHIPS_utilities|ship|_template=<template name>}} {{#invoke:WPSHIPS_utilities|ship_pre|prefix=<prefix>|_template=<template name>}} Parameters in the module frame are: there are no module frame parameters Parameters in the template frame are: {{{1|}}} – prefix (HMS, USS, Japanese submarine, etc) {{{2|}}} – ship's name (required) {{{3|}}} – disambiguator (year, hull or pennant number, etc) {{{4|}}} – format control (1, 2, 3, 5, 6; 4 not allowed) |wl= – when set to 'no', rendering is not wikilinked |up= – when set to 'yes' prefix (if rendered) is not linked ]] localfunctionship(frame)-- this version not supported from the template yet localargs_t=get_args(frame); localprefix=args_t[1]or'';-- fetch positional parameters into named variables for readability localname=args_t[2]or'';-- stripped of leading and trailing whitespace localdab=args_t[3]or'';-- empty positional parameters are nil so convert nil to empty string localcontrol=args_t[4]; localunlinked_prefix='yes'==args_t.up;-- make boolean: true when |up=yes localunlinked_whole='no'==args_t.wl;-- make boolean: true when |wl=no localno_cat='yes'==args_t['no-tracking'];-- make boolean: true when |no-tracking=yes return_ship(prefix,name,dab,control,unlinked_prefix,unlinked_whole,'Ship',no_cat); end --[[--------------------------< S H I P _ P R E F I X _ T E M P L A T E S >------------------------------------ This is a possible replacement for the template prefix templates {{USS}}, {{HMS}}, etc. It has better error detection and handling. This function is the externally accessible entry point for those templates {{#invoke:WPSHIPS_utilities|ship_prefix_templates|prefix=<prefix>|template=<template name>}} Parameters in the module frame are: |_prefix= – (required) _prefix (HMS, USS, Japanese submarine, etc) |_template= template name for error messages; optional when |prefix= same as template name Parameters in the template frame are: {{{1|}}} – ship's name (required) {{{2|}}} – disambiguator (year, hull or pennant number, etc) {{{3|}}} – format control (1, 2, 3, 5, 6; 4 not allowed) |wl= – when set to 'no', rendering is not wikilinked |up= – when set to 'yes' prefix (if rendered) is not linked ]] localfunctionship_prefix_templates(frame)-- this version not supported from the templates yet localargs_t=get_args(frame); localprefix=args_t.prefixor'';-- fetch positional parameters into named variables for readability localname=args_t[1]or'';-- stripped of leading and trailing whitespace localdab=args_t[2]or'';-- empty positional parameters are nil so convert nil to empty string localcontrol=args_t[3]; localunlinked_prefix='yes'==args_t.up;-- make boolean: true when |up=yes localunlinked_whole='no'==args_t.wl;-- make boolean: true when |wl=no localno_cat='yes'==args_t['no-tracking'];-- make boolean: true when |no-tracking=yes return_ship(prefix,name,dab,control,unlinked_prefix,unlinked_whole,args_t.template_nameorprefix,no_cat); end --[[--------------------------< L I S T _ E R R O R >---------------------------------------------------------- Assembles an error message, the original parameter value and, if appropriate a category. The error message precedes the existing value of the parameter. If the first non-whitespace character in the parameter is a '*', set prefix to a '*' and sep to '\n'. For line-break lists, set prefix to empty string and sep to '<br />'. Category is appended to the end of the returned value only for pages in article space. Inputs: prefix – a string of characters that precede the error message span; typically '' and '*' message – the error message to be displayed; goes inside the span sep – a string of characters that separates the span from the parameter value; typically '\n' and '<br />' param_val – the unmodified parameter value showerrs – a boolean, true to display the error message text ]] localfunctionlist_error(prefix,message,sep,param_val,showerrs) localerr_msg='%s<span style="font-size:100%%" class="error">list error: %s ([[:Category:WPSHIPS:Infobox list errors|help]])</span>%s%s%s'; localcategory=''; if0==mw.title.getCurrentTitle().namespacethen-- only categorize pages in article space category='[[Category:WPSHIPS:Infobox list errors]]'; end iftrue==showerrsthen returnstring.format(err_msg,prefix,message,sep,param_val,category);-- put it all together else returnparam_val..category; end end --[[--------------------------< U N B U L L E T E D _ L I S T >------------------------------------------------ Mediawiki:Common.css imposes limitations on plain, unbulleted lists. The template {{plainlist}} does not render this correctly: {{plainlist| *Item 1 *Item 2 **Item 2a ***Item 2a1 **Item 2b *Item 3}} The above renders without proper indents for items marked ** and ***. If the list is not wrapped in {{plainlist}} then the above list is rendered with bullets which is contrary to the Infobox ship usage guide. This code translates a bulleted list into an html unordered list: <ul style="list-style:none; margin:0;"> <li>Name 1</li> <li>Name 2</li> <ul style="list-style:none"> <li>Subname 2a</li> <ul style="list-style:none"> <li>Subname 2a1</li> </ul> <li>Subname 2b</li> </ul> <li>Name 3</li> </ul> There are rules: 1. The parameter value must begin with a splat but may have leading and trailing whitespace. 2. Each list item after the first must begin on a new line just as is required by normal bulleted lists. 3. When adding a sublevel, the number of splats may increase by one and never more. This is illegal: *item ***item When any of these rules are violated, unbulleted_list() returns the original text and adds the article to Category:WPSHIPS:Infobox list errors. Error messaging in this function is somewhat sketchy so they are disabled. After initial adoption, better error messaging could/should be implemented. This function receives the content of one parameter: {{#invoke:WPSHIPS utilities|unbulleted_list|{{{param|}}}}} ]] localfunction_unbulleted_list(param) localshowerrs=true;-- set to false to hide error messages localList_item_otag='<li style="padding-left: .4em; text-indent: -.4em;">';-- hanging indent markup; everything moves right with padding-left; first line moved left by neg indent ifnil==param:match('^%s*%*')then-- parameter value must begin with a splat (ignoring leading white space) ifparam:match('<[%s/]*[Bb][Rr][%s/]*>')then-- if the parameter value has a list using variants of <br /> tag returnlist_error('','<br /> list','<br />',param,showerrs);-- return an error message with maintenance category elseifparam:match('<div style="clear:')then returnlist_error('','{{clear}} list','<br />',param,showerrs);-- return an error message with maintenance category elseifparam:match('.+\n%*')then-- if the parameter value has text followed by an unordered list returnlist_error('','mixed text and list','<br />',param,showerrs);-- return an error message with maintenance category end returnparam;-- return the parameter as is end localitem_table=mw.text.split(mw.text.trim(param),'\n');-- trim white space from end then make a table of bulleted items by splitting on newlines if1==#item_tablethen-- if only one bulleted item, no need for a list return(item_table[1]:gsub('^%*%s*',''));-- trim off the splat and any following white space and done end ifitem_table[1]:match('^%*%*+')then-- if first list item uses more than one splat, that's an error returnlist_error('*','too many * at start of list','\n',param,showerrs);-- return an error message with maintenance category end localhtml_table={};-- table to hold the html output locallevel=1;-- used to indicate when a new <ul> is required localsplats=0;-- number of splats that start each item in the list localitem='';-- the item text table.insert(html_table,'<ul style="list-style:none; margin:0;">')-- this for first <ul> tag; sets no bullets and no indent for_,vinipairs(item_table)do splats,item=v:match('(%*+)%s*(.*)');-- split the item into splats and item text ifnil==splatsthen-- nil if there is an extra line between items returnlist_error('*','list item missing markup','\n',param,showerrs);-- return an error message with maintenance category elseif''==itemthen returnlist_error('*','empty list item','\n',param,showerrs);-- return an error message with maintenance category elseifitem:match('^[;:]')then-- if the list item is mixed unordered list / description list markup (*:) returnlist_error('*','mixed list type','\n',param,showerrs);-- return an error message with maintenance category end splats=splats:len();-- change string of splats into a number indicating how many splats there are ifsplats==levelthen-- if at the same level as previous item table.insert(html_table,List_item_otag..item..'</li>'); elseifsplats==level+1then-- number of splats can only increase by one level=splats;-- record the new level table.insert(html_table,'<ul style="list-style: none">');-- add a new sublist table.insert(html_table,List_item_otag..item..'</li>');-- and the item elseifsplats<levelthen-- from three splats to one splat for example whilesplats<leveldo table.insert(html_table,'</ul>');-- close each sub <ul> until level and splats match level=level-1; end table.insert(html_table,List_item_otag..item..'</li>');-- add the item else-- jumping more than one level up – one splat to three splats for example – is an error returnlist_error('*','too many asterisks','\n',param,showerrs);-- return an error message with maintenance category end end while0<leveldo table.insert(html_table,'</ul>');-- close each <ul> until level counted down to zero level=level-1; end returntable.concat(html_table,'\n');-- return the list as a string end --[[--------------------------< U N B U L L E T E D _ L I S T >------------------------------------------------ external entry point ]] localfunctionunbulleted_list(frame) return_unbulleted_list(frame.args[1]) end --[=[-------------------------< _I N F O B O X _ S H I P _ F L A G >-------------------------------------------- Output of {{shipboxflag|USA}}: [[File:Flag of the United States.svg|100x35px|alt=|link=]] Image syntax: [[File:Name|Type|Border|Location|Alignment|Size|link=Link|alt=Alt|Caption]] This function standardizes the size of flag images in the infobox ship career header by simply overwriting the Size parameter value in the Image wikilink with |100x28px. This size leave a 1px gap between the top and bottom of the flag image and the header edge. A similar left-side gap of 2px is supplied by {{infobox ship career}}. ]=] localfunction_infobox_ship_flag(image) ifimage:match('|[%s%dx]+px%s*')then-- is there a size positional parameter? image=image:gsub('|[%s%dx]+px%s*','%|100x28px');-- overwrite it with |100x28px else return'<span style="font-size:100%" class="error">malformed flag image</span>' end returnimage;-- return the modified image end --[=[-------------------------< I N F O B O X _ S H I P _ F L A G >-------------------------------------------- external entry point ]=] localfunctioninfobox_ship_flag(frame) ifnotis_set(frame.args[1])then-- if |Ship flag= not set return'';-- return empty string end return_infobox_ship_flag(frame.args[1]);-- return the modified image end --[=[-------------------------< C I T E _ D A N F S _ T I T L E >---------------------------------------------- This function attempts to render a DANFS article title in more or less proper (per Wikipedia) format for the template {{cite danfs}}. DANFS titles typically take one of four forms: <ship name> <disambiguator> <hull number> <ship name> <hull number> <ship name> <disambiguator> <ship name> Here, we extract the various parts, italicize the ship name and reassemble for use by the cite danfs |title= parameter. To call this function: |title={{#invoke:WPSHIPS utilities|cite_danfs_title|{{{title}}}}} ]=] localfunctioncite_danfs_title(frame) localname; localdisambiguator; localhullnum; ifnotis_set(frame.args[1])then-- if |title= not set return'';-- return empty string end name,disambiguator,hullnum=frame.args[1]:match('(.-)( [XVI]+)( %([^%)]+%))$'); ifnot(nameanddisambiguatorandhullnum)then disambiguator='';-- empty string for concatenation name,hullnum=frame.args[1]:match('(.-)( %([^%)]+%))$'); ifnot(nameandhullnum)then hullnum='';-- empty string for concatenation name,disambiguator=frame.args[1]:match('(.-)( [XVI]+)$'); ifnot(nameanddisambiguator)then disambiguator=''; name=frame.args[1];-- just a name or something we don't recognize end end end returntable.concat({"''",name,"''",disambiguator,hullnum});-- reassemble and done end --[[--------------------------< S Y N O N Y M _ C H E C K >---------------------------------------------------- support function for infoboxen functions there are a handful of infoboxen parameters that are synonymous pairs. This function is called to see if both of the parameters in a synonymous pair have been assigned a value. When both have assigned values, each gets an error message appended to it. Most of the synonymous pairs are UK Emglish v US English so the variable names <args_t> table of template parameters and values <uk_param> UK English parameter name <us_param> US English parameter name <error_flag> boolean that this function sets true when both of a pair are set; controls addition of maint category ]] localfunctionsynonym_check(args_t,uk_param,us_param,error_flag) ifargs_t[uk_param]andargs_t[us_param]then args_t[uk_param]=args_t[uk_param]..' '..error_msg_make('synonymous');-- both are set so append error message with category args_t[us_param]=args_t[us_param]..' '..error_msg_make('synonymous',nil,nil,true);-- but append error message without category returntrue;-- inform the calling function that it needs to emit maint category end returnerror_flag;-- no match so return unmodified <error_flag> end --[[--------------------------< L I N E _ I T E M S >---------------------------------------------------------- support function for infoboxen functions This function handles all infobox ship parameters that are 'line items' (label followed by value) because all of these sorts of parameters are rendered with exacty the same formatting. params_t{} is a table of tables where the params_t{} keys are the template's parameter names. The params_t{} values are sequences where [1] is an index number that defines where in the rendering the label/value pair is positioned and [2] is the label that will be rendered when the parameter has a value. This indexing is used because params_t{} is not a sequence and because pairs() does not necessarily return the 'next' k/v pair. This function spins through params_t{} and writes html for parameters that have assigned values into temp_t{} according to the 'index' value in the associated sequance table. When parameters are missing or empty, this function writes an empty string into the associated location in lines_t{} so that lines_t{} can be concatenated into a string value that is returned to the calling function. args_t is the arguments table from the template frame. ]] localfunctionline_items(args_t,params_t) locallines_t={};-- a sequence table of rendered label/value html lines; one for each key in params_t{} fork,vinpairs(params_t)do-- k is templat e parameter name; v is a sequence table with index and associated label localtemp_t={}-- initialize/reinitialize for next line item ifnotargs_t[k]then-- if no assigned value then lines_t[v[1]]='';-- set to empty string for concatenation else table.insert(temp_t,'<tr style="vertical-align:top;"><td style="font-weight: bold">');-- open the line item row and cell table.insert(temp_t,v[2]);-- add parameter's label text table.insert(temp_t,'</td><td>');-- close that cell and open the parameter value cell table.insert(temp_t,_unbulleted_list(args_t[k]));-- add the parameter's value; formatted as unordered list if appropriate table.insert(temp_t,'</td></tr>\n');-- close that cell and this row end lines_t[v[1]]=table.concat(temp_t);-- concatenate and put the line item in the lines sequence table at the index position end returntable.concat(lines_t);-- make a big string of line items and done end --[[--------------------------< I S _ E M P T Y _ I B O X _ T E M P L A T E >---------------------------------- temporary(?) code to add Category:WPSHIPS: articles with empty infobox templates when empty infobox templates are encountered. A template is empty when no parameters have assigned values or when the only parameter with an assigned value is |Hide header= when 'empty', returns the category name; nil else ]] localfunctionis_empty_ibox_template(args_t) locali=0; fork,vinpairs(args_t)do i=i+1; end if((1==i)andargs_t['Hide header'])or(0==i)then return'[[Category:WPSHIPS: articles with empty infobox templates]]'; end end --[[--------------------------< I N F O B O X _ S H I P _ C A R E E R >---------------------------------------- implements {{Infobox ship career}} {{#invoke:WPSHIPS utilities|infobox_ship_career}} ]] localfunctioninfobox_ship_career(frame) localargs_t=get_args(frame);-- get a table of all parameters in the template call localerr_cat=is_empty_ibox_template(args_t);-- look for and identify empty templates iferr_catthen returnerr_cat;-- template is empty so return the category and done end localhtml_out_t={};-- html table text goes here localerror_flag=false;-- controls emission of maint category when synonymous parameters are both set args_t['Hide header']=args_t['Hide header']andargs_t['Hide header']:lower();-- set to lowercase if set error_flag=synonym_check(args_t,'Ship stricken','Ship struck',error_flag);-- error if both synonymous parameters set error_flag=synonym_check(args_t,'Ship honours','Ship honors',error_flag); if'yes'~=args_t['Hide header']then-- |Hide header=yes then no header ifnot('title'==args_t['Hide header'])then-- |Hide header=title then no title bar table.insert(html_out_t,'<tr><th colspan="2" '); table.insert(html_out_t,styles.header_bar);-- style from WPMILHIST table.insert(html_out_t,'>History</th></tr>\n'); end ifargs_t['Ship country']andargs_t['Ship flag']then table.insert(html_out_t,'<tr><th height="30" colspan="2" style="background-color:#B0C4DE;color:inherit;text-align:left;padding-left:2px;vertical-align:middle;font-size:110%;">'); table.insert(html_out_t,_infobox_ship_flag(args_t['Ship flag'])); table.insert(html_out_t,'<span style="padding-left:1em">'); table.insert(html_out_t,args_t['Ship country']); table.insert(html_out_t,'</span>'); table.insert(html_out_t,'</th></tr>\n'); elseifargs_t['Ship country']then table.insert(html_out_t,'<tr><th height="30" colspan="2" style="background-color:#B0C4DE;color:inherit;text-align:center;vertical-align:middle;font-size:110%;">'); table.insert(html_out_t,args_t['Ship country']); table.insert(html_out_t,'</th></tr>\n'); elseifargs_t['Ship flag']then table.insert(html_out_t,'<tr><th height="30" colspan="2" style="background-color:#B0C4DE;color:inherit;padding-left:2px;">'); table.insert(html_out_t,_infobox_ship_flag(args_t['Ship flag'])); table.insert(html_out_t,'</th></tr>\n'); end end table.insert(html_out_t,line_items(args_t,data.infobox_career_params_t));-- add all of the rest of the template's html --mw.logObject (table.concat (html_out_t)); returntable.concat(html_out_t);-- make a big string and done end --[[--------------------------< I N F O B O X _ S H I P _ C H A R A C T E R I S T I C S >---------------------- implements {{Infobox ship characteristics}} {{#invoke:WPSHIPS utilities|infobox_ship_characteristics}} ]] localfunctioninfobox_ship_characteristics(frame) localargs_t=get_args(frame);-- get a table of all parameters in the template call localerr_cat=is_empty_ibox_template(args_t);-- look for and identify empty templates iferr_catthen returnerr_cat;-- template is empty so return the category and done end localhtml_out_t={};-- html table text goes here localerror_flag=false;-- controls emission of maint category when synonymous parameters are both set args_t['Hide header']=args_t['Hide header']andargs_t['Hide header']:lower();-- set to lowercase if set error_flag=synonym_check(args_t,'Ship armour','Ship armor',error_flag);-- error if both synonymous parameters set error_flag=synonym_check(args_t,'Ship draught','Ship draft',error_flag); if'yes'~=args_t['Hide header']then-- |Hide header=yes then no header table.insert(html_out_t,'<tr><th colspan="2" '); table.insert(html_out_t,styles.header_bar);-- style from WPMILHIST table.insert(html_out_t,'>General characteristics'); ifargs_t['Header caption']then table.insert(html_out_t,' '); table.insert(html_out_t,args_t['Header caption']); end table.insert(html_out_t,'</th></tr>\n'); end table.insert(html_out_t,line_items(args_t,data.infobox_characteristics_params_t));-- add all of the rest of the template's html --mw.logObject (table.concat (html_out_t)); returntable.concat(html_out_t);-- make a big string and done end --[[--------------------------< I N F O B O X _ S H I P _ C L A S S _ O V E R V I E W >------------------------ implements {{Infobox ship class overview}} {{#invoke:WPSHIPS utilities|infobox_ship_class_overview}} ]] localfunctioninfobox_ship_class_overview(frame) localargs_t=get_args(frame);-- get a table of all parameters in the template call localerr_cat=is_empty_ibox_template(args_t);-- look for and identify empty templates iferr_catthen returnerr_cat;-- template is empty so return the category and done end localhtml_out_t={};-- html table text goes here args_t['Hide header']=args_t['Hide header']andargs_t['Hide header']:lower(); if'yes'~=args_t['Hide header']then-- |Hide header=yes then no header table.insert(html_out_t,'<tr><th colspan="2" '); table.insert(html_out_t,styles.header_bar);-- style from WPMILHIST table.insert(html_out_t,'>Class overview</th></tr>\n'); end table.insert(html_out_t,line_items(args_t,data.infobox_class_overview_params_t));-- add all of the rest of the template's html --mw.logObject (table.concat (html_out_t)); returntable.concat(html_out_t);-- make a big string and done end --[[--------------------------< I S _ P L I M S O L L _ F I L E N A M E >-------------------------------------- validate cite plimsoll |filename=<filename> <filename> format is: YYvssss.pdf where YY - least significant two digits of four-digit first year in a two-year range 30 -> 1930–1931 allowed values are all integers between and including 30–45 v - a single lowercase letter 'a' or 'b' 'a' -> volume I 'b' -> volume II ssss - scan number begins with 0001 odd numbered scans have English headings even numbered scans have French headings {{#invoke:WPSHIPS utilities|is_plimsoll_filename|{{{filename}}}}} ]] localfunctionis_plimsoll_filename(frame) localargs_t=get_args(frame);-- get a table of all parameters in the invoke localyear,volume,scan; ifargs_t[1]then-- this to avoid script errors when args_t[1] missing year,volume,scan=args_t[1]:match('(%d%d)(%l)(%d%d%d%d)%.[Pp][Dd][Ff]');-- get the various parts end ifnotyearthenreturnnilend-- nil when no match so we're done year=tonumber(year); scan=tonumber(scan); if(30>year)or(45<year)thenreturnnilend ifnot(('a'==volume)or('b'==volume))thenreturnnilend if(1>scan)thenreturnnilend returntrue; end --[[--------------------------< S E T _ P L I M S O L L _ D A T E >-------------------------------------------- create two-year range from first two digits in |filename=<filename> 30 -> 1930–1931 {{#invoke:WPSHIPS utilities|set_plimsoll_date|{{{filename}}}}} ]] localfunctionset_plimsoll_date(frame) localargs_t=get_args(frame);-- get a table of all parameters in the invoke ifnotargs_t[1]then returnnil; end localyear=args_t[1]:match('(%d%d)%l%d%d%d%d');-- get the intial year year=1900+tonumber(year);-- make it a four-digit year returnstring.format('%d–%d',year,year+1);-- and then add one for the second year in the range end --[[--------------------------< S E T _ P L I M S O L L _ S U B T I T L E >-----------------------------------1 used in {{cite plimsoll}} return appropriate subtitle string given |subtitle=<keyword> {{#invoke:WPSHIPS utilities|set_plimsoll_subtitle|{{{subtitle}}}}} ]] localfunctionset_plimsoll_subtitle(frame) localsubtitle=get_args(frame)[1];-- get the subtitle parameter ifnotsubtitlethen returnnil; end ifnotdata.subtitles_t[subtitle]then return': '..subtitle;-- not predefined so return whatever |subtitle= holds with leading ': ' end return': '..data.subtitles_t[subtitle];-- return predefined subtitle with leading ': ' end --[[--------------------------< S E T _ P L I M S O L L _ U R L >---------------------------------------------- create plimsoll url from |filename=<filename> {{#invoke:WPSHIPS utilities|set_plimsoll_url|{{{filename}}}}} ]] localfunctionset_plimsoll_url(frame) localargs_t=get_args(frame);-- get a table of all parameters in the invoke ifargs_t[1]then returnstring.format('https://plimsoll.southampton.gov.uk/shipdata/pdfs/%s/%s', args_t[1]:match('(%d%d)%l%d%d%d%d'),-- get the year path portion from <filename> args_t[1]);-- append <filename> onto the end, and done end end --[[--------------------------< S C L A S S >------------------------------------------------------------------ implements {{sclass}} and {{sclass2}} {{#invoke:WPSHIPS utilities|sclass}} ]] localfunctionsclass(frame) localargs_t=get_args(frame); localparent=frame:getParent(); localtemplate=parent:getTitle():gsub('^Template:',''):lower();-- get the name of the template that called this module (includes namespace so strip that) localclass_name=args_t[1];-- names to make it easier to understand localship_type=args_t[2]; localformat=args_t[3]; localship_type_dab=args_t[4]; localclass_name_dab=args_t[5]; localno_cat='yes'==args_t['no-cat'];-- make a boolean ifnotclass_namethen-- when omitted, abandon with error message returnerror_msg_make('missing',template,'class name',no_cat); end ifnotship_typethen-- when omitted, abandon with error message returnerror_msg_make('missing',template,'ship type',no_cat); end ifformatthen iftonumber(format)then-- if <format> has a value that is a number format=tonumber(format);-- make it a number for comparisons if5<formatthen-- is <format> outside of allowed range returnerror_msg_make('format',template,format,no_cat); end else-- <format> could not be converted to a number returnerror_msg_make('format',template,format,no_cat); end end localout_t={};-- output goes here table.insert(out_t,'[[');-- open the wikilink table.insert(out_t,class_name);-- build the wikilink to the class article table.insert(out_t,'-class '); table.insert(out_t,ship_type);-- add ship type ifclass_name_dabthen-- when class article is disambiguated table.insert(out_t,' (');-- add the disambiguator table.insert(out_t,class_name_dab); table.insert(out_t,')'); end table.insert(out_t,'|'); if'sclass'==template:gsub('/sandbox','')then-- strip '/sandbox' if present; class named for a member of the class table.insert(out_t,'\'\'');-- class name is italicized table.insert(out_t,class_name); table.insert(out_t,'\'\''); else table.insert(out_t,class_name);-- class name is a common attribute; plain text end ifnotformator(3==format)then-- when format is omitted, same as format #3 table.insert(out_t,'-class]] [[');-- open ship-type wikilink ifship_type_dabthen-- when ship-type article is disambiguated table.insert(out_t,ship_type);-- add ship type table.insert(out_t,' (');-- and the disambiguator table.insert(out_t,ship_type_dab); table.insert(out_t,')|');-- dab is not displayed so insert a pipe and end table.insert(out_t,ship_type);-- add ship type table.insert(out_t,']]');-- close ship-type wikilink end if0==formatthen-- no separate ship-type wikilink table.insert(out_t,'-class]]'); end if1==formatthen-- no separate ship-type wikilink table.insert(out_t,'-class '); table.insert(out_t,ship_type); table.insert(out_t,']]'); end if2==formatthen-- ship-type is not wikilinked table.insert(out_t,'-class]] '); table.insert(out_t,ship_type); end if4==formatthen-- noun form; no ship type table.insert(out_t,' class]]'); end if5==formatthen-- class name only; no '-class' annotation table.insert(out_t,']]'); end returntable.concat(out_t); end --[[--------------------------< E X P O R T S >---------------------------------------------------------------- ]] return{ cite_danfs_title=cite_danfs_title,-- external entry points for templates and invokes hnsa=hnsa, infobox_ship_career=infobox_ship_career, infobox_ship_characteristics=infobox_ship_characteristics, infobox_ship_class_overview=infobox_ship_class_overview, infobox_ship_flag=infobox_ship_flag, is_plimsoll_filename=is_plimsoll_filename, navsource=navsource, sclass=sclass, set_plimsoll_subtitle=set_plimsoll_subtitle, set_plimsoll_date=set_plimsoll_date, set_plimsoll_url=set_plimsoll_url, ship=ship,-- experiment ship_prefix_templates=ship_prefix_templates,-- experiment ship_name_format=ship_name_format, unbulleted_list=unbulleted_list, _infobox_ship_flag=_infobox_ship_flag,-- external entry points from another module _ship_name_format=do_ship_name_format, _synonym_check=synonym_check, _unbulleted_list=_unbulleted_list, }