Module:WPSHIPS utilities/sandbox
![]() | This is the module sandbox page for Module:WPSHIPS utilities (diff). |
![]() | This Lua module is used on approximately 100,000 pages. 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=nodab
in{{infobox ship begin}}
, excludes a disambiguator from the formatted name - |sclass=2 – for use with
{{DISPLAYTITLE}}
and with|infobox caption=yes
or|infobox caption=nodab
in{{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=yes
or|infobox caption=nodab
in{{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
require('Module:No globals')
local wpsu={}
--[[-------------------------< S H I P P R E F I X L I S T >-----------------------------------------------
This is a list of currently supported ship prefixes.
To add to this list the form is:
['prefix'] = true,
the trailing comma is important.
]]
local ship_prefix_list =
{
['ARA'] = true, -- Armada de la República Argentina
['ARC'] = true, -- Armada Nacional de la República de Colombia
['BNS'] = true, -- Bangladesh Navy Ship
['CCGS'] = true, -- Canadian Coast Guard Ship
['CFAV'] = true, -- Canadian Forces Auxiliary Vessel
['CS'] = true, -- Cable Ship
['CSS'] = true, -- Confederate States Ship
['FGS'] = true, -- Federal German Ship
['GTS'] = true, -- Gas Turbine Ship
['HDMS'] = true, -- His/Her Danish Majesty's Ship
['HMAS'] = true, -- Her/His Majesty's Australian Ship
['HMBS'] = true, -- Her/His Majesty's Britannic Ship (also: Bahamian, Bermudian, Burmese)
['HMC'] = true, -- Her/His Majesty's Cutter
['HMCS'] = true, -- Her/His Majesty's Canadian Ship (also Colonial)
['HMNZS'] = true, -- Her/His Majesty's New Zealand Ship
['HMQS'] = true, -- Her/His Majesty's Queensland Ship
['HMS'] = true, -- Her/His Majesty's Ship
['HMSAS'] = true, -- Her/His Majesty's South African Ship
['HMT'] = true, -- Her/His Majesty's Trawler
['HMVS'] = true, -- Her/His Majesty's Victorian Ship
['HNLMS'] = true, -- His/Her Netherlands Majesty’s Ship
['HNoMS'] = true, -- His/Her Norwegian Majesty's Ship
['HSwMS'] = true, -- His/Her Swedish Majesty's Ship
['HTMS'] = true, -- His Thai Majesty's Ship
['INS'] = true, -- Indian Naval Ship, Israeli Naval Ship
['KDM'] = true, -- Kongelige Danske Marine
['MF'] = true, -- Motor Ferry
['MS'] = true, -- Motor Ship
['MV'] = true, -- Motor Vessel
['NoCGV'] = true, -- Norwegian Coast Guard Vessel
['NRP'] = true, -- Navio da República Portuguesa
['ORP'] = true, -- Okręt Rzeczypospolitej Polskiej
['PS'] = true, -- Paddle Steamer
['RFA'] = true, -- Royal Fleet Auxiliary
['RNLB'] = true, -- Royal National Lifeboat
['RMAS'] = true, -- Royal Maritime Auxiliary Service
['RMS'] = true, -- Royal Mail Ship
['RV'] = true, -- Research Vessel
['SM'] = true, -- Seiner Majestät Unterseeboot
['SMS'] = true, -- Seiner Majestät Schiff
['SS'] = true, -- Screw Steamer or Steamship
['TCG'] = true, -- Türkiye Cumhuriyeti Gemisi
['TV'] = true, -- Training vessel
['USAFS'] = true, -- United States Air Force ship
['USAS'] = true, -- United States Army Ship
['USC&GS'] = true, -- United States Coast and Geodetic Survey
['USC&GSS'] = true, -- United States Coast and Geodetic Survey Ship
['USCGC'] = true, -- United States Coast Guard Cutter
['USLHT'] = true, -- United State Light House Tender
['USNS'] = true, -- United States Naval Ship
['USRC'] = true, -- United States Revenue Cutter
['USS'] = true, -- United States Ship
}
--[[--------------------------< N A T I O N A L I T Y >--------------------------------------------------------
Article titles for ships in navies that do not use a standardized prefix follow the title format:
<nationality> <ship type> <name> <(disambiguator)>
This is a list of nationalities.
To add to this list the form is:
['Nationality'] = true,
the trailing comma is important. Use the adjective form for nationality, always capitalize. Please insert nationalities in alphabetical order.
]]
local nationality_list =
{
['Albanian'] = true,
['American'] = true,
['Australian'] = true,
['Belgian'] = true,
['Brazilian'] = true,
['Bulgarian'] = true,
['Chilean'] = true,
['Chinese'] = true,
['Croatian'] = true,
['Danish'] = true,
['Dominican'] = true,
['Dutch'] = true,
['East Timorese'] = true,
['Egyptian'] = true,
['English'] = true,
['Finnish'] = true,
['French'] = true,
['German'] = true,
['Greek'] = true,
['Grenadan'] = true,
['Iranian'] = true,
['Italian'] = true,
['Japanese'] = true,
['Latvian'] = true,
['Libyan'] = true,
['Lithuanian'] = true,
['Maltese'] = true,
['Mexican'] = true,
['Nigerian'] = true,
['Ottoman'] = true,
['Peruvian'] = true,
['Portuguese'] = true,
['Romanian'] = true,
['Russian'] = true,
['Slovenian'] = true,
['Soviet'] = true,
['Spanish'] = true,
['Texan'] = true,
['Ukrainian'] = true,
['Vietnamese'] = true,
['United States'] = true,
}
--[[--------------------------< S H I P T Y P E >------------------------------------------------------------
Article titles for ships in navies that do not use a standardized prefix follow the title format:
<nationality> <ship type> <name> <(disambiguator)>
Article titles for ships may or may not be naval ships may follow the title format:
<name> <(disambiguator)>
where <(disambiguator)> may be some form of ship type, hull designator or pennant number, or year. This tool will
format ship names that contain a recognized ship type in <(disambiguator)>.
This list is used to <find ship> when the article title begins with a nationality. This is important because the tool
needs to know where the <ship type> ends and <name> begins so that it can properly place the italic markup. The search
will find an exact match (including case) for ship types that are 1 to 4 words long.
This list is also used to find ship type in <(disambiguator)>. The search is whole word; use the simplest form.
For example, because 'icebreaker' is defined, that ship type is sufficient to cause the tool to properly format:
Astrolabe (icebreaker)
Krassin (1917 icebreaker)
Taymyr (nuclear icebreaker)
Searches for ship type in <(disambiguator)> are whole word. When looking for 'ship', the tool will find
Auguste (ship)
Queen of Nations (clipper ship)
but will not find:
Sibir (steamship icebreaker) – the search for 'icebreaker' will
This is a list of ship types. When adding new ship types, do not be too specific: 'aircraft carrier' but not 'light aircraft carrier'
To add to this list the form is:
['ship type'] = true,
the trailing comma is important. At the time of this writing, a ship type may be one to four words, almost always lowercase.
Please insert ship types in alphabetical order.
]]
local ship_type_list =
{
['armoured cruiser'] = true,
['aircraft carrier'] = true,
['amphibious assault ship'] = true,
['Army ship'] = true, -- should be capitalized
['auxiliary cruiser'] = true,
['auxiliary raider'] = true,
['auxiliary'] = true,
['aviso'] = true,
['barge'] = true,
['barque'] = true,
['barquentine'] = true,
['battlecruiser'] = true,
['battleship'] = true,
['boat'] = true,
['brig sloop'] = true,
['brig-sloop'] = true,
['brig'] = true,
['brigantine'] = true,
['clipper'] = true,
['coast defense ship'] = true,
['coastal defence ship'] = true,
['coastal defense ship'] = true,
['communications ship'] = true,
['corvette'] = true,
['cruiser'] = true,
['cutter'] = true,
['deep submergence rescue vehicle'] = true,
['destroyer leader'] = true,
['destroyer'] = true,
['dragger'] = true,
['dredge'] = true,
['East Indiaman'] = true, -- should be capitalized
['escort ship'] = true,
['escort'] = true,
['ferry'] = true,
['ferryboat'] = true,
['fireboat'] = true,
['fleet oiler'] = true,
['floating battery'] = true,
['floating crane'] = true,
['fluyt'] = true,
['food supply ship'] = true,
['freighter'] = true,
['frigate'] = true,
['galleon'] = true,
['galley'] = true,
['gunboat'] = true,
['helicopter carrier'] = true,
['hospital ship'] = true,
['hovercraft'] = true,
['hydrofoil'] = true,
['icebreaker'] = true,
['Indiaman'] = true, -- should be capitalized
['ironclad'] = true,
['ketch'] = true,
['landing ship medium'] = true,
['lifeboat'] = true,
['lightship'] = true,
['log canoe'] = true,
['lugger'] = true,
['merchant cruiser'] = true,
['minehunter'] = true,
['minelayer'] = true,
['minelaying cruiser'] = true,
['minesweeper'] = true,
['missile boat'] = true,
['monitor'] = true,
['munition ship'] = true,
['naval ship'] = true,
['night fighter direction vessel'] = true,
['ocean liner'] = true,
['oiler'] = true,
['paddle steamer'] = true,
['patrol boat'] = true,
['patrol gunboat'] = true,
['patrol vessel'] = true,
['pinnace'] = true,
['pollution control vessel'] = true,
['privateer'] = true,
['protected cruiser'] = true,
['pusher'] = true,
['rescue ship'] = true,
['riverboat'] = true,
['ROV'] = true,
['sailboat'] = true,
['schooner'] = true,
['seaplane carrier'] = true,
['seaplane tender'] = true,
['ship of the line'] = true,
['ship'] = true,
['shipwreck'] = true,
['shore establishment'] = true, -- use stone frigate instead?
['showboat'] = true,
['sidewheeler'] = true,
['skipjack'] = true,
['sloop-of-war'] = true,
['sloop'] = true,
['smack'] = true,
['snagboat'] = true,
['speedboat'] = true,
['steam frigate'] = true,
['steam warship'] = true,
['steamboat'] = true,
['steamer'] = true,
['steamship'] = true,
['sternwheeler'] = true,
['stores lighter'] = true,
['submarine chaser'] = true,
['submarine rescue vehicle'] = true,
['submarine tender'] = true,
['submarine'] = true,
['submersible'] = true,
['supertanker'] = true,
['support ship'] = true,
['survey ship'] = true,
['tanker'] = true,
['target ship'] = true,
['tender'] = true,
['torpedo boat'] = true,
['torpedo gunboat'] = true,
['towboat'] = true,
['training cruiser'] = true,
['training ship'] = true,
['transport'] = true,
['trawler'] = true,
['trireme'] = true,
['tug'] = true,
['tugboat'] = true,
['vessel'] = true,
['warship'] = true,
['weather ship'] = true,
['whaler'] = true,
['whaleship'] = true,
['wherry'] = true,
['yacht'] = true,
['yawl'] = true,
}
--[[--------------------------< 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.
]]
local function is_set( var )
return not (var == nil or var == '');
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.
]]
local function sizeof_ship_type (frag, frag_len, nat_len)
local ship_type;
if 5 <= (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
if ship_type_list [ship_type] then
return 4;
end
end
if 4 <= (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
if ship_type_list [ship_type] then
return 3;
end
end
if 3 <= (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
if ship_type_list [ship_type] then
return 2;
end
end
if 2 <= (frag_len - nat_len) then -- must have at least two fragments after nationality for one-word ship type
if ship_type_list [frag[nat_len+1]] then -- one-word ship type
return 1;
end
end
return 0; -- 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
]]
local function sizeof_nationality (frag, frag_len)
local nat = '';
if not nationality_list [frag[1]] then -- if not a one-word nationality
if 2 <= frag_len - 2 then -- must have at least two fragments after nationality for minimal ship type and name
nat = table.concat (frag, ' ', 1, 2);
if nationality_list [nat] then -- is it a two-word nationality?
return 2; -- yes
else
return 0; -- no
end
end
return 0; -- not one-word and not enough fragments for two-word
end
return 1; -- one-word nationality
end
--[[-------------------------< 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 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
]]
function wpsu.ship_name_format(frame)
-- local pframe = frame:getParent() -- is this needed?
-- local args = {};
--
-- for k, v in pairs( pframe.args ) do
-- args[k] = v;
-- end
if not is_set (frame.args.name) then return '<span style="font-size:100%" class="error">Empty name</span>' end; -- return an empty string error message if there is no name
local fragments = {};
local name = '';
local name_sans_dab;
local dab;
local ship_type;
local nat_len;
local type_len;
local error_msg = '';
if frame.args.name:match('[%a%d]+%-class%s+%a+') then -- if a ship-class
fragments = mw.text.split (frame.args.name, '-class' ); -- split at -class
if '2' == frame.args.sclass then -- and if class not named for a member of the class
if 'off' == frame.args.adj then
return fragments[1] .. ' class'; -- for infobox caption do noun form <name> class (no hyphen, no ship type)
end
return frame.args.name; -- nothing to do so return original unformatted title
end
if 'off' == frame.args.adj then
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
name_sans_dab, dab = frame.args.name:match('^(.+)%s+(%b())%s*$'); -- not a ship class so try to format a ship name
if is_set (dab) then
dab = ' ' .. dab; -- insert a space
else
name_sans_dab = frame.args.name; -- because without a dab, the match returns nil
dab = ''; -- empty string for concatenation
end
fragments = mw.text.split (name_sans_dab, '%s' ); -- split into table of separate words
nat_len = sizeof_nationality (fragments, #fragments);
if 0 < nat_len then
type_len = sizeof_ship_type (fragments, #fragments, nat_len);
if 0 < type_len then
name = table.concat (fragments, ' ', 1, nat_len + type_len) .. " ''" .. table.concat (fragments, ' ', nat_len + type_len + 1) .. "''"; -- format name
else
error_msg = ' unrecognized ship type;';
end
elseif ship_prefix_list[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;';
end
if is_set (name) then
if 'none' ~= frame.args.dab then -- for |infobox caption=nodab
name = name .. dab; -- append the dab
end
return name; -- return the formatted name
end
if is_set (dab) then -- last chance, is there a ship type in the dab?
for key, _ in pairs (ship_type_list) do -- spin through the ship type list and see if there is a ship type (key) in the dab
if dab:find ('%f[%a]' .. key .. '%f[^%a]') then -- avoid matches that are not whole word
name = "''" .. table.concat (fragments, ' ') .. "''"; -- format the name
if 'none' ~= frame.args.dab then -- for |infobox caption=nodab
name = name .. dab; -- format name (dab)
end
return name; -- return formatted name
end
end
error_msg = error_msg .. ' no ship type in dab;';
end
if 'yes' == frame.args.showerrs then
return frame.args.name .. '<span style="font-size:100%" class="error">' .. error_msg .. '</span>'; -- return original un-formatted name with error message
else
return frame.args.name; -- return original un-formatted name
end
end
return wpsu;