وحدة:Infobox ship
| Uses Lua: |
| هذه الوحدة تستخدم أنماط القوالب: |
Implements:
{{infobox ship}}{{infobox ship/image}}{{infobox ship/career}}{{infobox ship/characteristics}}{{infobox ship/class_overview}}{{infobox ship/service record}}
require('strict');
local utilities = require ('Module:WPSHIPS_utilities');
local infobox = require ('Module:Infobox').infobox;
local infobox_ship_flag = utilities._infobox_ship_flag;
local ship_name_format = utilities._ship_name_format;
local synonym_check = utilities._synonym_check;
local unbulleted_list = utilities._unbulleted_list;
local get_args = require ('Module:Arguments').getArgs;
local data = mw.loadData ('Module:Infobox_ship/data');
--[[--------------------------< L I N E _ I T E M S >-----------------------------------------------------------------------------
spin through <params_t> sequence. Get parameter name and matching infobox label. Look in <args_t> for parameter name. When parameter
name has a value, add infobox label and parameter value to the infobox table <infobox_ship_t>. <i> identifies where label and data
enumerators begin.
]]
local function line_items (args_t, params_t, infobox_ship_t, i, frame)
for _, v in ipairs (params_t) do -- v is a sequence table with parameter name and associated infobox label
if args_t[v[1]] then -- if parameter has a value
infobox_ship_t['label' .. i] = v[2]; -- add the label
infobox_ship_t['data' .. i] = unbulleted_list (args_t[v[1]]); -- and add the parameter value as data
i = i + 1; -- bump the enumerator
end
end
end
--[[--------------------------< A D D _ W A R N I N G >--------------------------------------------------------
for unknown parameters, add a message in the edit-preview message box
<template> is the name of the enclosing infobox ship or one of the subtemplates
<k> is the parameter name
<v> is the parameter value
]]
local function add_warning (template, k, v)
v = v:gsub (data.stripmarker, ''); -- suppress stripmarkers in the warning message
mw.addWarning (string.format (data.warning_fmt_str, data.warn_span_style, data.warn_code_style, template, template, data.warn_code_style, k, v));
end
--[[--------------------------< U N K N O W N _ P A R A M S _C H E C K >---------------------------------------
check parameters supplied in <template> against known parameters for that template. Emit preview warning when
a parameter is unknown.
Empty unknown parameters are not identified because Module:Arguments removes blank parameters by default.
]]
local function unknown_params_check (args_t, known_params_t, template)
local has_unknown_params = false;
for k, v in pairs (args_t) do
if 'string' == type (k) then
local param = k:gsub ('%d+$', '#'); -- for enumerated parameters, replace enumerator with '#'
if not known_params_t[param] then
add_warning (template, k, v); -- add warning message when <param> is not known for <template>
has_unknown_params = data.cat_this_namespace; -- add unknown params category when infobox is rendered; mainspace and draftspace only
end
else -- here when <k> not a string (likely a positional parameter)
add_warning (template, k, v); -- add warning message when <param> is not known for <template>
has_unknown_params = data.cat_this_namespace; -- add unknown params category when infobox is rendered; mainspace and draftspace only
end
end
return has_unknown_params;
end
--[[--------------------------< F I N A L _ R E N D E R I N G >------------------------------------------------
final rendering for the various subtemplates
]]
local function final_rendering (infobox_ship_t, frame, has_unknown_params, template)
if 'yes' ~= infobox_ship_t.child then -- when not 'yes', we are in stand-alone mode
infobox_ship_t.bodyclass = 'mainbox'; -- use basic infobox css for stand-alone mode
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Infobox ship/styles.css'}), -- apply templatestyles
infobox (infobox_ship_t), -- render the infobox
(has_unknown_params and data.categories_t.unknown) or '' -- add category for any unknown parameters
});
else
infobox_ship_t.label100 = '__1B0X_5H1P__';
infobox_ship_t.data100 = template
return frame:expandTemplate ({title='Infobox', args = infobox_ship_t}); -- return a rendering of this infobox
end
end
--[[--------------------------< D I S P L A Y T I T L E _ M A K E >--------------------------------------------
account for namespace when creating {{DIPSLAYSTYLE}} magic word
]]
local function DISPLAYTITLE_make (display_title)
local namespace_name = data.namespace_number ~= 0 and (data.namespace_name .. ':') or ''; -- no namespace prefix for articles in mainspace
return string.format ('{{DISPLAYTITLE:%s%s}}', namespace_name, display_title); -- construct magic word
end
--[[--------------------------< I N F O B O X _ S H I P _ B E G I N >------------------------------------------
fill infobox table parameters 'bodystyle' and 'title' (infobox caption); auto-article title formatting ({{DISPLAYTITLE}})
]]
local function infobox_ship_begin (args_t, infobox_ship_t, frame)
local name = mw.title.getCurrentTitle().text;
infobox_ship_t['bodyclass'] = 'mainbox';
if args_t.infobox_caption then
if 'yes' == args_t.infobox_caption then -- format article title as infobox caption
infobox_ship_t.title = ship_name_format ({name=name, adj='off', showerrs=args_t.showerrs, sclass=args_t.sclass});
elseif 'nodab' == args_t.infobox_caption then -- format article title without disambiguation as infobox caption
infobox_ship_t.title = ship_name_format ({name=name, dab='none', showerrs=args_t.showerrs});
else -- use value supplied in |infobox_caption= as infobox caption
infobox_ship_t.title = args_t.infobox_caption;
end
else
infobox_ship_t.title = ''; -- to allow for possible displaytitle concatenation
end
if args_t.display_title then
if 'ital' == args_t.display_title then -- use {{italic title}} template
infobox_ship_t.title = infobox_ship_t.title .. require ('Module:italic title')._main ({}); -- {{italic title}} without template overhead
elseif ('none' ~= args_t.display_title) then -- any value but 'none' use value in |display_title= for {{DISPLAYTITLE}} magic word
infobox_ship_t.title = infobox_ship_t.title .. frame:preprocess (DISPLAYTITLE_make (args_t.display_title));
end
else -- |display_title= empty or omitted, use article title
infobox_ship_t.title = infobox_ship_t.title .. frame:preprocess (DISPLAYTITLE_make (ship_name_format ({name=name, sclass=args_t.sclass})));
end
end
--[[--------------------------< I M A G E _ P A R A M S _ C H E C K >------------------------------------------
emit maint cat and warning message when:
- |image_caption= and/or |image_alt= have a value but |image= does not have a value.
- |image_size=300px
- |image= has extended image syntax
]]
local function image_params_check (args_t)
local image_warning_flag; -- flag; true when ibox has |image_alt= or |image_caption= but no |image=
local template_name = 'Infobox ship/image';
local image_link = args_t.image and args_t.image:match ('^%b[]'); -- get first wikilink in |image= if any
if image_link and (image_link:match ('%[%[%s*[Ff]ile:') or image_link:match ('%[%[%s*[Ii]mage:')) then -- check for |image= with extended image syntax
mw.addWarning (string.format (data.image_EIS_warning_fmt_str, data.warn_span_style, data.warn_code_style, template_name, template_name, data.warn_code_style)); -- extended image syntax found add warning
image_warning_flag = true;
end
if args_t.image_size and args_t.image_size:match ('300') then -- 300 is default size so this parameter/value pair superfluous
mw.addWarning (string.format (data.image_size_warning_fmt_str, data.warn_span_style, data.warn_code_style, template_name, template_name, data.warn_code_style)); -- add warning
image_warning_flag = true;
end
if not args_t.image and (args_t.image_caption or args_t.image_alt) then -- caption or alt without image is meaningless
mw.addWarning (string.format (data.image_missing_warning_fmt_str, data.warn_span_style, data.warn_code_style, template_name, template_name, data.warn_code_style, data.warn_code_style, data.warn_code_style, data.warn_code_style)); -- add warning
image_warning_flag = true;
end
return image_warning_flag;
end
--[[--------------------------< I N F O B O X _ S H I P _ I M A G E >------------------------------------------
{{#invoke:Infobox ship|infobox_ship_image}} – for stand-alone mode
Returns a child infobox for Infobox ship/image unless |child=no for a stand-alone rendering
images in {{infobox ship}} default to 300px; upright is ignored
]]
local function infobox_ship_image (frame)
local template_name = 'Infobox ship/image';
local args_t = get_args (frame);
local image_warning_flag = image_params_check (args_t) and data.cat_this_namespace; -- and categorize any warnings
local infobox_ship_t = {
child = args_t.child or 'yes'; -- default to child
image1 = require ('Module:InfoboxImage').InfoboxImage ({args = {'InfoboxImage', 'InfoboxImage', image=args_t.image, size=args_t.image_size, alt=args_t.image_alt, sizedefault = '300px'}}); -- upright='1' ignored
caption1 = args_t.image_caption;
}
local has_unknown_params = unknown_params_check (frame:getParent().args, data.known_infobox_ship_image_params_t, template_name); -- emit warning for all unknown parameters; even those that are empty
return table.concat ({
final_rendering (infobox_ship_t, frame, has_unknown_params, 'image'), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or '',
(image_warning_flag and data.categories_t.image_syntax) or '',
((not args_t.image) and (data.cat_this_namespace and data.categories_t.no_image)) or '',
});
end
--[[--------------------------< I N F O B O X _ S H I P _ C A R E E R >----------------------------------------
{{#invoke:Infobox ship|infobox_ship_career}} – for stand-alone mode
Returns a child infobox for Infobox ship/career unless |child=no for a stand-alone rendering
]]
local function infobox_ship_career (frame)
local template_name = 'Infobox ship/career';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes'; -- default to child
headerclass = 'country';
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
if not ('title' == args_t.hide_header) then -- |hide_header=title then no title bar
local spoof_t = {
child = 'yes', -- default to child
decat = 'yes', -- spoof infobox does not have data; don't categorize in Category:Articles using infobox templates with no data rows
header1 = 'History',
headerclass = "history",
}
infobox_ship_t.data1 = frame:expandTemplate ({title='Infobox', args = spoof_t}); -- return a rendering of this spoof infobox
i = i + 1;
end
if args_t.country and args_t.flag then
infobox_ship_t['header' .. i] = infobox_ship_flag (args_t.flag) .. '<span style="padding-left:1em">' .. args_t.country .. '</span>';
elseif args_t.country then
infobox_ship_t['header' .. i] = args_t.country;
elseif args_t.flag then
infobox_ship_t['header' .. i] = infobox_ship_flag (args_t.flag);
end
end
if infobox_ship_t['header' .. i] then
i = i + 1;
end
local error_flag;
error_flag = synonym_check (args_t, 'ship_stricken', 'ship_struck', error_flag); -- error if both synonymous parameters set
synonym_check (args_t, 'ship_honours', 'ship_honors', error_flag);
line_items (args_t, data.infobox_career_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (frame:getParent().args, data.known_infobox_ship_career_params_t, 'Infobox ship/career'); -- emit warning for all unknown parameters; even those that are empty
return table.concat ({
final_rendering (infobox_ship_t, frame, has_unknown_params, 'career'), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
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 >----------------------
{{#invoke:Infobox ship|infobox_ship_characteristics}} – for stand-alone mode
Returns a child infobox for Infobox ship/characteristics unless |child=no for a stand-alone rendering
]]
local function infobox_ship_characteristics (frame)
local template_name = 'Infobox ship/characteristics';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes', -- default to child
headerclass = 'general'
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
local header = 'General characteristics'; -- the default header
if args_t.header_caption then
header = header .. ' ' .. args_t.header_caption; -- concatenate |header_caption= onto default header
end
infobox_ship_t['header' .. i] = header; -- add the header
i = i + 1; -- bump the enumerator
end
local error_flag;
error_flag = synonym_check (args_t, 'ship_armour', 'ship_armor', error_flag); -- error if both synonymous parameters set
synonym_check (args_t, 'ship_draught', 'ship_draft', error_flag); -- when both set modify with error message and category
line_items (args_t, data.infobox_characteristics_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (frame:getParent().args, data.known_infobox_ship_characteristics_params_t, template_name); -- emit warning for all unknown parameters; even those that are empty
return table.concat ({
final_rendering (infobox_ship_t, frame, has_unknown_params, 'characteristics'), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
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 >------------------------
{{#invoke:Infobox ship|infobox_ship_class_overview}} – for stand-alone mode
Returns a child infobox for Infobox ship/class overview unless |child=no for a stand-alone rendering
]]
local function infobox_ship_class_overview (frame)
local template_name = 'Infobox ship/class overview';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes', -- default to child
headerclass = 'general'
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
infobox_ship_t['header' .. i] = 'Class overview'; -- add the header
i = i + 1; -- bump the enumerator
end
synonym_check (args_t, 'total_ships_cancelled', 'total_ships_canceled', nil); -- error if both synonymous parameters set
line_items (args_t, data.infobox_class_overview_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (frame:getParent().args, data.known_infobox_ship_class_overview_params_t, template_name); -- emit warning for all unknown parameters; even those that are empty
return table.concat ({
final_rendering (infobox_ship_t, frame, has_unknown_params, 'class overview'), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P _ S E R V I C E _ R E C O R D >------------------------
{{#invoke:Infobox ship|infobox_ship_service_record}} – for stand-alone mode
Returns a child infobox for Infobox ship/service record unless |child=no for a stand-alone rendering. This
function implements the ship-only portion of {{Infobox service record}}; does not know about |is_ship= and
|is_multi= parameters. Adds support for |hide_header= parameter
]]
local function infobox_ship_service_record (frame)
local template_name = 'Infobox ship/service record';
local args_t = get_args (frame);
args_t.hide_header= args_t.hide_header and args_t.hide_header:lower(); -- set to lowercase if set
local infobox_ship_t = {
child = args_t.child or 'yes', -- default to child
headerclass = 'general'
}
if args_t.infobox_caption then -- special case for |infobox_caption=
if 'yes' == infobox_ship_t.child then -- if not stand-alone
add_warning (template_name, 'infobox_caption', args_t.infobox_caption); --emit preview warning message
else
infobox_ship_t.title = args_t.infobox_caption; -- translate |infobox_caption= to |title= used by Module:Infobox
args_t.infobox_caption = nil; -- unset to avoid preview error message; no longer needed
end
end
local i = 1;
if 'yes' ~= args_t.hide_header then -- |hide_header=yes then no header
infobox_ship_t['header' .. i] = args_t.header_caption or args_t.label or 'Service record'; -- add the header; |label= is deprecated
i = i + 1; -- bump the enumerator
end
line_items (args_t, data.infobox_ship_service_record_params_t, infobox_ship_t, i, frame); -- go do all of the other infobox parameters
local has_unknown_params = unknown_params_check (frame:getParent().args, data.known_infobox_ship_service_record_params_t, template_name); -- emit warning for all unknown parameters; even those that are empty
return table.concat ({
final_rendering (infobox_ship_t, frame, has_unknown_params, 'service record'), -- return final rendering of this infobox
(has_unknown_params and data.categories_t.unknown) or ''
});
end
--[[--------------------------< I N F O B O X _ S H I P >------------------------------------------------------
{{#invoke:Infobox ship|infobox_ship}}
To discover when two child infoboxen are concatenated without a proper |sectionn= parameter between them, this
function looks for and counts the special secret |label100=__1B0X_5H1P__ and |data100=<template name>. Each child
appends the special secret parameters at final_rendering(). This function counts and deletes those special secret
parameters. If the count is:
0 – ok; parameter does not include a child infobox rendering
1 – ok; parameter holds only one child infobox
2+ – not ok
]]
local function infobox_ship (frame)
local args_t = get_args (frame);
local infobox_ship_t = {}; -- table that holds infobox parameters
infobox_ship_begin (args_t, infobox_ship_t, frame); -- fetch parameters that once belonged to obsolete {{infobox ship begin}}
for k, v in pairs (args_t) do -- copy infobox parameters from the frame into our local table
if 'string' == type (k) then -- must be string; positional parameters not supported
local enum = k:match ('section(%d+)'); -- <enum> gets a value when this parameter is |section<n>=
if enum then
infobox_ship_t['data'..enum] = v; -- translate |section<n> = to |data<n>=
else
infobox_ship_t[k] = v; -- assume that parameter name is one known to Module:Infobox
end
end
end
for k, v in pairs (infobox_ship_t) do -- look for malformed input (concatenated child infoboxen)
if k:find ('data', 1, true) then -- only look in values assigned to |datan= (née |sectionn=)
local name, count = v:gsub ('<tr><th scope=\"row\" class=\"infobox%-label\">__1B0X_5H1P__</th><td class=\"infobox%-data\">[%l ]+</td></tr>', ''); -- count special secret parameters
if 1 < count then -- more than one when parameter has concatenated child infoboxen
infobox_ship_t[k] = table.concat ({
string.format (data.error_messages_t.missing_section, k:match ('%d')), -- emit an error message; replaces the concatenated subtemplate
(data.cat_this_namespace and data.categories_t.missing_section) or '', -- and also categorize
});
else
infobox_ship_t[k] = name; -- delete special secret |label100=__1B0X_5H1P__ and |data100=<template name>
end
end
end
local has_unknown_params = unknown_params_check (frame:getParent().args, data.known_infobox_ship_params_t, 'Infobox ship'); -- emit warning for all unknown parameters; even those that are empty
return table.concat ({
frame:extensionTag ('templatestyles', '', {src='Module:Infobox ship/styles.css'}), -- apply template styles
infobox (infobox_ship_t), -- render the infobox
(has_unknown_params and data.categories_t.unknown) or '' -- add category for any unknown parameters
});
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
infobox_ship = infobox_ship,
infobox_ship_image = infobox_ship_image,
infobox_ship_career = infobox_ship_career,
infobox_ship_characteristics = infobox_ship_characteristics,
infobox_ship_class_overview = infobox_ship_class_overview,
infobox_ship_service_record = infobox_ship_service_record,
}