Difference between revisions of "Module:NVR"

From blackwiki
Jump to navigation Jump to search
blackwiki>RP88
(restore id parameter)
m (30 revisions imported)
 
(16 intermediate revisions by 3 users not shown)
Line 13: Line 13:
  
 
require('Module:No globals')
 
require('Module:No globals')
 +
local p = {}
  
local p = {}
+
--[[--------------------------< F O R W A R D  D E C L A R A T I O N S >--------------------------------------
 +
]]
 +
 
 +
local ships_data = {};
 +
local srv_craft_data = {};
 +
 
 +
local data = mw.loadData ('Module:NVR/data');
 +
ships_data = data.nvr_ships_id;
 +
srv_craft_data = data.nvr_srv_craft_id;
 +
 
 +
 
 +
--[[--------------------------< M A K E _ E R R O R _ M E S S A G E >------------------------------------------
  
-- =======================================
+
General purpose error message function to render error messages and categorization
-- === Private Functions =================
 
-- =======================================
 
  
--[[
 
Generate link to NVR database.
 
 
]]
 
]]
local function nvr_link( nvrid, oldid, supportship, title )
+
 
 +
local function make_error_message (output, prefix, item, suffix, srv_craft)
 +
local category = ''; -- for concatenation
 
 
local link = ''
+
if 0 == mw.title.getCurrentTitle().namespace then -- article namespace
local url_str = ''
+
category = '[[Category:WPSHIPS:Template_errors]]'; -- categorize only from article namespace
 +
end
 
 
if oldid then
+
table.insert (output, '<span style="font-size:100%" class="error">')
if supportship then
+
table.insert (output, prefix);
url_str = 'http://www.nvr.navy.mil/NVRSERVICECRAFT/DETAILS/' .. nvrid .. '.HTM'
+
table.insert (output, item);
else
+
table.insert (output, suffix);
url_str = 'http://www.nvr.navy.mil/NVRSHIPS/DETAILS/' .. nvrid .. '.HTM'
+
if srv_craft then
end
+
table.insert (output, ' ([[Template:NVR SC url#Error messages|help]])</span>');
 
else
 
else
url_str = 'http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_' .. nvrid .. '.HTML'
+
table.insert (output, ' ([[Template:NVR url#Error messages|help]])</span>');
 
end
 
end
 +
table.insert (output, category);
 +
return
 +
end
  
if (title == '') then
 
link = url_str
 
else
 
link = '[' .. url_str .. ' ' .. title .. ']'
 
end
 
 
    return link
 
end
 
  
-- =======================================
+
--[[--------------------------< M A K E _ S H I P _ L I N K >--------------------------------------------------
-- === Public Functions ==================
 
-- =======================================
 
  
--[[
 
MakeShipLink
 
 
 
This function returns a link to a ship in the Naval Vessel Register.
 
This function returns a link to a ship in the Naval Vessel Register.
 
   
 
   
Line 61: Line 62:
 
   
 
   
 
Parameters
 
Parameters
     1, id: The 'file name' portion of the url path (typically the ship's hull designation) without the .HTM/.HTML extension.
+
     1, id: The ship's hull classification symbol
 
     2, title: A title or label for the link.
 
     2, title: A title or label for the link.
 
]]
 
]]
function p.MakeShipLink( frame )
+
 
-- if no argument provided than check parent template/module args
+
function p.MakeShipLink (frame)
local args = frame.args
+
local args = frame.args -- if no argument provided, check parent template/module args
 +
local output = {};
 +
 
 
if (args[1]==nil) and (args["id"]==nil) then
 
if (args[1]==nil) and (args["id"]==nil) then
args = frame:getParent().args  
+
args = frame:getParent().args;
 +
if (args[1]==nil) and (args["id"]==nil) then
 +
make_error_message (output, 'required parameter missing', '', '');
 +
return table.concat (output);
 +
end
 
end
 
end
 
 
local nvrid = args["id"] or args[1] or '';  
+
local hull = args["id"] or args[1] or '';
 +
local hull_designator; -- for use with |name= parameter rendering
 +
local hull_prefix;
 
local title = args["title"] or args[2] or '';
 
local title = args["title"] or args[2] or '';
 +
 +
if '' == title then -- to prevent external links that look like this: [1]
 +
title = nil;
 +
end
 +
 +
hull = mw.text.trim (hull):upper(); -- make sure that there is no leading/trailing whitespace and uppercase
 +
-- standardize so that we can recognize as many formats as possible
 +
hull_designator = hull:match ('^T%-') or ''; -- if there is a 'T-' prefix to the prefix, save a copy of it; empty string for concatenation else
 +
--error (hull_designator)
 +
hull = hull:gsub ('^T%-', ''); -- if hull classification symbol is T-XX-NNN, remove the 'T-'
 +
hull = hull:gsub ('(%a+)_(%d+)_%d+', '%1-%2'); -- if template has 'new' url identifier format (SSBN_659_1635); as of March 2019 this form not used at NVR
 +
hull = hull:gsub ('(%a+)[_ ]?(%d+)', '%1-%2'); -- if template has SSBN 659 or SSBN_659 or SSBN659 format
 +
hull_designator = hull_designator .. hull; -- copy for use with |name= parameter
 +
 +
if hull:match ('(%a+)%-%d+') then -- most common case
 +
hull_prefix = hull:match ('(%a+)[%-_]?%d+');
 +
elseif hull:match ('[%a+ %(%)]+%-%d+') then -- special one-off case for AFSB (I)-15
 +
hull_prefix = hull:match ('([%a+ %(%)]+)%-%d+')
 +
elseif hull:match ('^CONSTITUTION$') or hull:match ('^MAINE$') or hull:match ('^TEXAS$') then -- Constitution, Maine, and Texas
 +
hull_prefix = hull; -- do not have hull classification symbols; use their names
 +
else
 +
make_error_message (output, 'malformed hull classification symbol: ', hull, '');
 +
return table.concat (output);
 +
end
 +
 +
if not ships_data[hull_prefix] then -- is there a group for the hull number?
 +
make_error_message (output, 'unable to find group: [\'', hull_prefix, '\'] in [[Module:NVR/data]] nvr_ships_id');
 +
return table.concat (output);
 +
end
  
local output = p._MakeShipLink(nvrid, title)
+
if not ships_data[hull_prefix][hull] then -- is there a hull number
 +
make_error_message (output, 'unable to find hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_ships_id');
 +
return table.concat (output);
 +
end
  
return output
+
local nvr_id = ships_data[hull_prefix][hull][1]; -- try to fetch nvr id
 +
if not title and (args['name'] and '' ~= args['name']) then
 +
title = ships_data[hull_prefix][hull][2];
 +
if not title or '' == title then
 +
title = nil; -- ensure
 +
elseif 'no name' == title:lower() then -- new construction capital ships, and many service craft
 +
title = title .. ' (' .. hull_designator .. ')';
 +
elseif 'nh' == args['name'] then -- special keyword to render name and hull designator
 +
title = '\'\'' .. ships_data[hull_prefix][hull][2] .. '\'\' (' .. hull_designator .. ')';
 +
else
 +
title = '\'\'' .. ships_data[hull_prefix][hull][2] .. '\'\''; -- just the name
 +
end
 +
end
 +
 
 +
if (nil ~= nvr_id) and ('' ~= nvr_id) then -- there appears to be an identifier, so use it
 +
if title then -- if there is a title then make an external link from it
 +
table.insert (output, '['); -- opening bracket
 +
end
 +
table.insert (output, 'http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_'); -- create the url
 +
table.insert (output, nvr_id);
 +
table.insert (output, '.HTML');
 +
if title then
 +
table.insert (output, ' '); -- required space
 +
table.insert (output, title); -- title
 +
table.insert (output, ']'); -- and closing bracket
 +
end
 +
 +
else -- no identifier
 +
make_error_message (output, 'no identifier for hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_ships_id');
 +
end
 +
 +
return table.concat (output); -- and done
 
end
 
end
  
--[[
+
 
MakeServiceShipLink
+
--[[--------------------------< M A K E _ S E R V I C E _ C R A F T _ L I N K >--------------------------------
+
 
This function returns a link to a service ship in the Naval Vessel Register.
+
This function returns a link to a service craft in the Naval Vessel Register.
 
   
 
   
 
Usage:
 
Usage:
{{#invoke:NVR|MakeServiceShipLink|1=|title=}}
+
{{#invoke:NVR|MakeServiceCraftLink|1=|title=}}
{{#invoke:NVR|MakeServiceShipLink}} - uses the caller's parameters
+
{{#invoke:NVR|MakeServiceCraftLink}} - uses the caller's parameters
 
   
 
   
 
Parameters
 
Parameters
     1, id: The 'file name' portion of the url path (typically the ship's hull designation) without the .HTM/.HTML extension.  
+
     1, id: The 'file name' portion of the url path (typically the craft's hull designation) without the .HTM/.HTML extension.  
 
     2, title: A title or label for the link.
 
     2, title: A title or label for the link.
 
]]
 
]]
function p.MakeServiceShipLink( frame )
+
 
 +
function p.MakeServiceCraftLink( frame )
 
-- if no argument provided than check parent template/module args
 
-- if no argument provided than check parent template/module args
 
local args = frame.args
 
local args = frame.args
 +
local output = {};
 +
 
if (args[1]==nil) and (args["id"]==nil) then
 
if (args[1]==nil) and (args["id"]==nil) then
args = frame:getParent().args  
+
args = frame:getParent().args;
 +
if (args[1]==nil) and (args["id"]==nil) then
 +
make_error_message (output, 'required parameter missing', '', '', true);
 +
return table.concat (output);
 +
end
 
end
 
end
 
 
local nvrid = args["id"] or args[1] or '';  
+
local hull = args["id"] or args[1] or '';
 +
local hull_prefix;
 
local title = args["title"] or args[2] or '';
 
local title = args["title"] or args[2] or '';
 
local output = p._MakeServiceShipLink(nvrid, title)
 
 
return output
 
end
 
 
 
--[[
 
This function returns a link to a ship in the Naval Vessel Register.
 
 
Parameters
 
nvrid: The 'file name' portion of the url path (typically the ship's hull designation) without the .HTM/.HTML extension, as a string.
 
title: Title for link, set to '' for a bare link without a title.
 
]]
 
function p._MakeShipLink( nvrid, title )
 
local output = ''
 
 
 
title = mw.text.trim(title)
+
if '' == title then -- to prevent external links that look like this: [1]
 +
title = nil;
 +
end
 
 
-- if the id appears to be an old id, convert it to a new id, if possible.
+
hull = mw.text.trim (hull):upper(); -- make sure that there is no leading/trailing whitespace and uppercase
nvrid = mw.text.trim(mw.ustring.upper(nvrid))
+
-- standardize so that we can recognize as many formats as possible
 +
hull = hull:gsub ('(%a+)_(%d+)_%d+', '%1-%2'); -- if template has 'new' url identifier format (YT_807_4629)
 +
hull = hull:gsub ('(%a+)[_ ]?(%d+)', '%1-%2'); -- if template has YT 807 or YT_807 or YT807 format
 +
 
 +
if hull:match ('(%a+)%-%d+') then -- most common case
 +
hull_prefix = hull:match ('(%a+)%-%d+');
 +
elseif hull:match ('(%a+)%-%d+%a') then -- special cases for the various sections of floating dry docks;
 +
hull_prefix = hull:match ('(%a+)%-%d+%a'); -- each section has a single letter designator: AFDB-7F
 +
else
 +
make_error_message (output, 'malformed hull classification symbol: ', hull, '', true);
 +
return table.concat (output);
 +
end
 
 
if (nvrid == 'MAINE') then
+
if not srv_craft_data[hull_prefix] then -- is there a group for the hull number?
nvrid = '939'
+
make_error_message (output, 'unable to find group: [\'', hull_prefix, '\'] in [[Module:NVR/data]] nvr_srv_craft_id', true);
elseif (nvrid == 'MARCOS') then
+
return table.concat (output);
nvrid = '940'
+
end
elseif (nvrid == 'OLDIRON') then
+
 
nvrid = '1315'
+
if not srv_craft_data[hull_prefix][hull] then -- is there a hull number
elseif (nvrid == 'AFSB15') then
+
make_error_message (output, 'unable to find hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_srv_craft_id', true);
nvrid = 'AFSB_(I)_15'
+
return table.concat (output);
elseif (mw.ustring.find(nvrid, "^[A-Z]+[0-9]+$") ~= nil) then
 
nvrid = mw.ustring.gsub(nvrid, "^([A-Z]+)([0-9]+)$", "%1_%2", 1);
 
 
end
 
end
 
output = nvr_link(nvrid, false, false, title)
 
 
return output
 
end
 
  
--[[
+
local nvr_id = srv_craft_data[hull_prefix][hull][1]; -- try to fetch nvr id
This function returns a link to a service ship in the Naval Vessel Register.
 
  
Parameters
+
if (nil ~= nvr_id) and ('' ~= nvr_id) then -- there appears to be an identifier, so use it
nvrid: The 'file name' portion of the url path (typically the ship's hull designation) without the .HTM/.HTML extension, as a string.
+
if title then
title: Title for link, set to '' for a bare link without a title.
+
table.insert (output, '[');
]]
+
end
function p._MakeServiceShipLink( nvrid, title )
+
table.insert (output, 'http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_');
local output = ''
+
table.insert (output, nvr_id);
local oldid = false
+
table.insert (output, '.HTML');
+
if title then
title = mw.text.trim(title)
+
table.insert (output, ' ');
+
table.insert (output, title);
-- if the id appears to be an old id, convert it to a new id, if possible.
+
table.insert (output, ']');
nvrid = mw.text.trim(mw.ustring.upper(nvrid))
+
end
+
else -- no identifier
if (nvrid == 'AFDB7_1') then
+
make_error_message (output, 'no identifier for hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_srv_craft_id', true);
nvrid = 'AFDB_7'
 
elseif (nvrid == 'AFDB1_1') then
 
oldid = true
 
elseif (nvrid == 'AFDB1_3') then
 
oldid = true
 
elseif (nvrid == 'AFDB1_4') then
 
oldid = true
 
elseif (nvrid == 'AFDB7_2') then
 
oldid = true
 
elseif (mw.ustring.find(nvrid, "^[A-Z]+[0-9]+$") ~= nil) then
 
nvrid = mw.ustring.gsub(nvrid, "^([A-Z]+)([0-9]+)$", "%1_%2", 1);
 
 
end
 
end
 
 
output = nvr_link(nvrid, oldid, true, title)
+
return table.concat (output);
 
return output
 
 
end
 
end
  
 
return p
 
return p

Latest revision as of 08:04, 27 September 2020


Summary

This module generates links to ships in the Naval Vessel Register (nvr.navy.mil) database. Intended to be used by:

NVR have adopted a file naming convention based on a ship's hull classification symbol with an appended underscore and some number of digits. The extra digits do not seem to follow an identifiable pattern so the former rules-based system used here no longer works.

To get round the 'new' file format, this version of the module adopts a brute-force mechanism by using a local database that maps a ship's hull classification symbol to its associated NVR file name. The database is two large Lua tables maintained at Module:NVR/data.

Using this module from templates

MakeShipLink

This function returns a link to a ship's page at the Naval Vessel Register website.

Usage:

{{#invoke:NVR|MakeShipLink|id=|title=}}
{{#invoke:NVR|MakeShipLink}} — uses the calling template's parameters

Parameters:

1 or id — the ship's case-insensitive hull classification symbol in one of five forms:
  1. SSBN-659 – the preferred format because it matches the format for hull classification symbols generally used for US Navy ships throughout Wikipedia
  2. SSBN 659
  3. SSBN659
  4. SSBN_659
  5. SSBN_659_1635 – the NVR file name format as of September 2017
There are exceptions. There are three ships listed at the NVR website that do not have hull classification symbols. These are: USS Constitution, USS Maine, and USS Texas. For these three ships, use the ship's name for this parameter. The code word OLDIRON, previously used to identify Constitution is no longer supported.
2 or title — A title or label for the link.

Examples:

{{#invoke:NVR|MakeShipLink|DDG_1000}} produces http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_DDG_1000.HTML
{{#invoke:NVR|MakeShipLink|constitution}} produces http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_1315.HTML
{{#invoke:NVR|MakeShipLink|maine|USS ''Maine''}} produces USS Maine

MakeServiceCraftLink

This function returns a link to a service craft in the Naval Vessel Register.

Usage:

{{#invoke:NVR|MakeServiceCraftLink|id=|title=}}
{{#invoke:NVR|MakeServiceCraftLink}} — uses the calling template's parameters

Parameters: Parameters:

1 or id — the ship's case-insensitive hull classification symbol in one of five forms:
  1. YTB-760 – the preferred format because it matches the format for hull classification symbols generally used for US Navy ships throughout Wikipedia
  2. YTB 760
  3. YTB760
  4. YTB_760
  5. YTB_760_5292 – the NVR file name format as of September 2017
There are exceptions. NVR has separate pages for some single and some multiple sections of some floating drydocks. For these, this module adopts a convention similarly used by NVR where each section is distinguished by a letter designator; that letter must be appended to the hull classification symbol used in this parameter; see the examples
2 or title — A title or label for the link.

Examples:

{{#invoke:NVR|MakeServiceCraftLink|AFDB-7F}} produces http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_AFDB_7_1549.HTML
{{#invoke:NVR|MakeServiceCraftLink|ytb-760}} produces Natick

--[[  
 
This module generates links to ships in the Naval Vessel Register (nvr.navy.mil) database.  
It is used by Template:NVR_url and Template:NVR_SC_url
 
Please do not modify this code without applying the changes first at Module:NVR/sandbox and testing 
at Module:NVR/sandbox/testcases and Module talk:NVR/sandbox/testcases.
 
Authors and maintainers:
* User:RP88
 
]]

require('Module:No globals')
local p = {}

--[[--------------------------< F O R W A R D   D E C L A R A T I O N S >--------------------------------------
]]

local ships_data = {};
local srv_craft_data = {};

local data = mw.loadData ('Module:NVR/data');
	ships_data = data.nvr_ships_id;
	srv_craft_data = data.nvr_srv_craft_id;


--[[--------------------------< M A K E _ E R R O R _ M E S S A G E >------------------------------------------

General purpose error message function to render error messages and categorization

]]

local function make_error_message (output, prefix, item, suffix, srv_craft)
	local category = '';														-- for concatenation
	
	if 0 == mw.title.getCurrentTitle().namespace then							-- article namespace
		category = '[[Category:WPSHIPS:Template_errors]]';						-- categorize only from article namespace
	end
	
	table.insert (output, '<span style="font-size:100%" class="error">')
	table.insert (output, prefix);
	table.insert (output, item);
	table.insert (output, suffix);
	if srv_craft then
		table.insert (output, ' ([[Template:NVR SC url#Error messages|help]])</span>');
	else
		table.insert (output, ' ([[Template:NVR url#Error messages|help]])</span>');
	end
	table.insert (output, category);
	return
end


--[[--------------------------< M A K E _ S H I P _ L I N K >--------------------------------------------------

This function returns a link to a ship in the Naval Vessel Register.
 
Usage:
{{#invoke:NVR|MakeShipLink|1=|title=}}
{{#invoke:NVR|MakeShipLink}} - uses the caller's parameters
 
Parameters
    1, id: The ship's hull classification symbol
    2, title: A title or label for the link.
]]

function p.MakeShipLink (frame)
	local args = frame.args														-- if no argument provided, check parent template/module args
	local output = {};

	if (args[1]==nil) and (args["id"]==nil) then
		args = frame:getParent().args;
		if (args[1]==nil) and (args["id"]==nil) then
			make_error_message (output, 'required parameter missing', '', '');
			return table.concat (output);
		end
	end
	
	local hull = args["id"] or args[1] or '';
	local hull_designator;														-- for use with |name= parameter rendering
	local hull_prefix;
	local title = args["title"] or args[2] or '';
	
	if '' == title then															-- to prevent external links that look like this: [1]
		title = nil;
	end
	
	hull = mw.text.trim (hull):upper();											-- make sure that there is no leading/trailing whitespace and uppercase
																				-- standardize so that we can recognize as many formats as possible
	hull_designator = hull:match ('^T%-') or '';								-- if there is a 'T-' prefix to the prefix, save a copy of it; empty string for concatenation else
--error (hull_designator)
	hull = hull:gsub ('^T%-', '');												-- if hull classification symbol is T-XX-NNN, remove the 'T-'
	hull = hull:gsub ('(%a+)_(%d+)_%d+', '%1-%2');								-- if template has 'new' url identifier format (SSBN_659_1635); as of March 2019 this form not used at NVR
	hull = hull:gsub ('(%a+)[_ ]?(%d+)', '%1-%2');								-- if template has SSBN 659 or SSBN_659 or SSBN659 format
	hull_designator = hull_designator .. hull;									-- copy for use with |name= parameter

	if hull:match ('(%a+)%-%d+') then											-- most common case
		hull_prefix = hull:match ('(%a+)[%-_]?%d+');
	elseif hull:match ('[%a+ %(%)]+%-%d+') then									-- special one-off case for AFSB (I)-15
		hull_prefix = hull:match ('([%a+ %(%)]+)%-%d+')
	elseif hull:match ('^CONSTITUTION$') or hull:match ('^MAINE$') or hull:match ('^TEXAS$') then	-- Constitution, Maine, and Texas
		hull_prefix = hull;														-- do not have hull classification symbols; use their names
	else
		make_error_message (output, 'malformed hull classification symbol: ', hull, '');
		return table.concat (output);
	end
	
	if not ships_data[hull_prefix] then											-- is there a group for the hull number?
		make_error_message (output, 'unable to find group: [\'', hull_prefix, '\'] in [[Module:NVR/data]] nvr_ships_id');
		return table.concat (output);
	end

	if not ships_data[hull_prefix][hull] then									-- is there a hull number
		make_error_message (output, 'unable to find hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_ships_id');
		return table.concat (output);
	end

	local nvr_id = ships_data[hull_prefix][hull][1];							-- try to fetch nvr id
	if not title and (args['name'] and '' ~= args['name']) then
		title = ships_data[hull_prefix][hull][2];
		if not title or '' == title then
			title = nil;														-- ensure
		elseif 'no name' == title:lower() then									-- new construction capital ships, and many service craft
			title = title .. ' (' .. hull_designator .. ')';
		elseif 'nh' == args['name'] then										-- special keyword to render name and hull designator
			title = '\'\'' .. ships_data[hull_prefix][hull][2] .. '\'\' (' .. hull_designator .. ')';
		else
			title = '\'\'' .. ships_data[hull_prefix][hull][2] .. '\'\'';		-- just the name
		end
	end

	if (nil ~= nvr_id) and ('' ~= nvr_id) then									-- there appears to be an identifier, so use it
		if title then															-- if there is a title then make an external link from it
			table.insert (output, '[');											-- opening bracket
		end
		table.insert (output, 'http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_');	-- create the url
		table.insert (output, nvr_id);
		table.insert (output, '.HTML');
		if title then
			table.insert (output, ' ');											-- required space
			table.insert (output, title);										-- title
			table.insert (output, ']');											-- and closing bracket
		end
		
	else																		-- no identifier
		make_error_message (output, 'no identifier for hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_ships_id');
	end
	
	return table.concat (output);												-- and done
end


--[[--------------------------< M A K E _ S E R V I C E _ C R A F T _ L I N K >--------------------------------

This function returns a link to a service craft in the Naval Vessel Register.
 
Usage:
{{#invoke:NVR|MakeServiceCraftLink|1=|title=}}
{{#invoke:NVR|MakeServiceCraftLink}} - uses the caller's parameters
 
Parameters
    1, id: The 'file name' portion of the url path (typically the craft's hull designation) without the .HTM/.HTML extension. 
    2, title: A title or label for the link.
]]

function p.MakeServiceCraftLink( frame )
	-- if no argument provided than check parent template/module args
	local args = frame.args
	local output = {};

	if (args[1]==nil) and (args["id"]==nil) then
		args = frame:getParent().args;
		if (args[1]==nil) and (args["id"]==nil) then
			make_error_message (output, 'required parameter missing', '', '', true);
			return table.concat (output);
		end
	end
	
	local hull = args["id"] or args[1] or '';
	local hull_prefix;
	local title = args["title"] or args[2] or '';
	
	if '' == title then															-- to prevent external links that look like this: [1]
		title = nil;
	end
	
	hull = mw.text.trim (hull):upper();											-- make sure that there is no leading/trailing whitespace and uppercase
																				-- standardize so that we can recognize as many formats as possible
	hull = hull:gsub ('(%a+)_(%d+)_%d+', '%1-%2');								-- if template has 'new' url identifier format (YT_807_4629)
	hull = hull:gsub ('(%a+)[_ ]?(%d+)', '%1-%2');								-- if template has YT 807 or YT_807 or YT807 format

	if hull:match ('(%a+)%-%d+') then											-- most common case
		hull_prefix = hull:match ('(%a+)%-%d+');
	elseif hull:match ('(%a+)%-%d+%a') then										-- special cases for the various sections of floating dry docks;
		hull_prefix = hull:match ('(%a+)%-%d+%a');								-- each section has a single letter designator: AFDB-7F
	else
		make_error_message (output, 'malformed hull classification symbol: ', hull, '', true);
		return table.concat (output);
	end
	
	if not srv_craft_data[hull_prefix] then										-- is there a group for the hull number?
		make_error_message (output, 'unable to find group: [\'', hull_prefix, '\'] in [[Module:NVR/data]] nvr_srv_craft_id', true);
		return table.concat (output);
	end

	if not srv_craft_data[hull_prefix][hull] then								-- is there a hull number
		make_error_message (output, 'unable to find hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_srv_craft_id', true);
		return table.concat (output);
	end

	local nvr_id = srv_craft_data[hull_prefix][hull][1];						-- try to fetch nvr id

	if (nil ~= nvr_id) and ('' ~= nvr_id) then									-- there appears to be an identifier, so use it
		if title then
			table.insert (output, '[');
		end
		table.insert (output, 'http://www.nvr.navy.mil/SHIPDETAILS/SHIPSDETAIL_');
		table.insert (output, nvr_id);
		table.insert (output, '.HTML');
		if title then
			table.insert (output, ' ');
			table.insert (output, title);
			table.insert (output, ']');
		end
	else																		-- no identifier
		make_error_message (output, 'no identifier for hull classification symbol: [\'', hull, '\'] in [[Module:NVR/data]] nvr_srv_craft_id', true);
	end
	
	return table.concat (output);
end

return p