![]() | Help support Yugipedia by using our Chrome extension, which redirects links to the old Wikia/Fandom site to Yugipedia, ensuring you see the most up-to-date information. Firefox users don't worry—a similar Firefox add-on will be out soon. If you have any issues or find any bugs, be sure to let us know on Discord! |
Module:Set list
The above documentation is transcluded from Module:Set list/doc. (edit | history) Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages. Subpages of this module. |
-- <pre>
-- Module for {{Set list}},
-- to be used like {{#invoke:Set list|main}}.
-- @@@ for ideas.
-------------------
local SetList = {};
-----------------
-- Load modules:
-----------------
local getArgs = require( 'Module:Arguments' ).getArgs;
local getCardType = require( 'Module:Card type' ).main;
--------------
-- Load data:
--------------
local _D = {};
local data = mw.loadData( 'Module:Set list/data' );
local rg_list = data.rg_list; -- Region code table.
local region_list = data.region_list; -- Region name table.
local ln_list = data.ln_list; -- Language code table.
local language_list = data.language_list; -- Language name table.
local rarity_list = data.rarity_list; -- Rarity name table.
local abbr_list = data.abbr_list; -- Abbr disable codes table.
----------------------
-- Utility functions:
----------------------
-- mw functions:
local split = mw.text.split;
local HTML = mw.html.create;
-- Trim function:
-- Trims white space from front and tail of string.
-- If the input is only white space, returns nil.
local function _trim( s )
if s and not s:match( '^%s*$' ) then
return mw.text.trim( s ); -- If not nil nor empty.
end
end
-- Link function:
-- If a string is passed, links it;
-- uses a label, when given.
-- If a table is passed, links every instance of it;
-- uses a table of labels, respectively for each entry, when given.
local function _link( v, ... )
local labels = type( ... or nil ) == 'table' and ... or { ... }; -- Make sure it's a table.
local function __link( v, label )
return ('[[%s|%s]]'):format( v:gsub( '#', '' ), _trim( label ) or split( v, '%s*%(' )[1] );
end
if type( v ) == 'string' then
return __link( v, labels[1] );
elseif type( v ) == 'table' then
local t = {};
for key, value in ipairs( v ) do
table.insert( t, __link( value, labels[key] ));
end
return t;
else
return v; -- @@@ error()
end
end
-- Table count function:
-- Given a table, counts how many values it has.
local function _count( t ) -- @@@ error() for wrong type()
local counter = 0;
for key, value in pairs( t ) do
counter = counter + 1;
end
return counter;
end
local function _error( message, default, category ) -- @@@ input list of categories.
local err = HTML( 'div' ):css( 'padding-left', '1.6em' )
:tag( 'strong' ):addClass( 'error' ):wikitext( ('Error: %s'):format( message ) ):done()
:allDone();
local cat = ('[[Category:%s]]'):format( category or '((Set list)) transclusion to be checked' );
table.insert( _D.errors, table.concat( { tostring( err ), cat } ) );
return default or '';
end
-------------------------------
-- Getter/generator functions:
-------------------------------
-- Info function:
-- Handles region/language info and flags.
local function getInfo()
_D.rg = _D.args['region'] and _D.args['region']:lower() or _error( 'A «region» is always needed!', 'en' );
_D.region = region_list[_D.rg];
_D.ln = ln_list[_D.rg];
_D.language = language_list[_D.ln];
-- Flags:
_D.flags = {};
_D.flags.qty = _D.args['qty'] and true;
_D.flags.reprint = _D.args['print'] and true;
_D.flags.noAbbr = _D.args['abbr'] and abbr_list[_D.args['abbr']:lower()] and true;
_D.flags.column = _D.args['col'] and true;
_D.flags.notEnglish = _D.ln ~= 'en';
_D.flags.italics = ((_D.ln == 'ja') or (_D.ln == 'zh') or (_D.ln == 'ko')) and 'normal' or 'italic';
end
-- Local name function:
-- Returns the localized name.
local function getNameLocal( name )
if not mw.smw then
return _error( 'mw.smw module not found' );
end
local _page = name:gsub( '#', '' );
local _query = { ('[[%s]]'):format( _page ), ('?%s name='):format( _D.language ), limit = 1, mainlabel = '-' };
local query = mw.smw.ask( _query );
if not query or _count( query ) == 0 or _count( query[1] ) == 0 then
return;
end
return query[1][1];
end
-- Name function:
-- Returns two values:
-- The English name; the localized name.
local function getSetName( name )
local t = split( name, '%s*%(' );
local _name = _D.args['set'] or _trim( t[3] ) and table.concat( t, ' (', 1, 2 ) or t[1];
local _nameLocal = _D.flags['notEnglish'] and getNameLocal( _name );
return _name, _nameLocal;
end
-- Quotes function:
-- Wraps a name with quotes.
local function wrapQuotes( name, std )
if not _trim( name ) then
return ''; -- Return empty string.
end
return (std or (_D.ln ~= 'ja' and _D.ln ~= 'zh')) and table.concat( { '"', name, '"' } )
or table.concat( { '「', name, '」' } );
end
-- Rarity function:
-- Receives a string of rarities.
local function getRarity( s )
local t = s and split( s, ',' ) or {};
local rarities = {};
for _, rarity in ipairs( t ) do
_rarity = _trim( rarity:lower():gsub( ' rare$', '' ) );
if _rarity and rarity_list[_rarity] then
table.insert( rarities, _link( rarity_list[_rarity] ) );
end
end
return table.concat( rarities, '<br />' );
end
-- Page header function:
-- Builds page header (HTML).
local function getHeader( setName, setNameLocal )
local CSS = {
{ -- First «span» tag (set name).
['font-size'] = '120%',
['font-weight'] = 'bold',
['font-style'] = 'italic'
},
{ -- Second «span» tag (local set name).
['font-weight'] ='bold',
['font-style'] = _D.flags['italics']
}
};
local header = HTML( 'div' ):css( 'text-align', 'center' )
:tag( 'span' ):css( CSS[1] )
:wikitext( _link( setName, (setName:match( '%(2011%)' ) or setName:match( '%(series%)' )) and setName ) )
:done();
if _trim( setNameLocal ) then
header:tag( 'br' ):done()
:tag( 'span' ):css( CSS[2] )
:wikitext( setNameLocal )
:done();
end
header:tag( 'br' ):done()
:wikitext( _D.region )
:allDone();
return tostring( header );
end
-- Categories function:
-- Generates categories.
local function getCategory( ns )
-- @@@ Make it similar to _link.
return ('[[Category:%s %s]]'):format( _D.region, ns );
end
local function tracking( frameArgs )
local _parameters = {
1,
['region'] = 'region',
['set'] = 'set',
['abbr'] = 'abbr',
['rarity'] = 'rarity',
['qty'] = 'qty',
['print'] = 'print',
['col'] = 'col'
}
for key, value in pairs( frameArgs ) do
if not( _parameters[key] ) or not( _trim( value ) ) then
-- There are parameters not being used or used empty.
return _error( 'Instance of unsupported or empty parameters!' , nil, '((Set list)) transclusion with parameters to be checked' )
end
end
return '';
end
-----------------------
-- Set list functions:
-----------------------
-- Header entry function:
-- Builds the section header.
-- Fetches section info.
local function getSetListHeader( entry )
local _header = entry:match('header::(.-);')
or entry:match('header::(.+)' );
local _sectionNoAbbr = entry:match( 'abbr::(.-);')
or entry:match( 'abbr::(.+)' );
local _sectionRarityList = entry:match('rarity::(.-);')
or entry:match('rarity::(.+)' );
local _sectionQty = entry:match( 'qty::(.-);')
or entry:match( 'qty::(.+)' );
local _sectionReprint = entry:match( 'print::(.-);')
or entry:match( 'print::(.+)' );
local _sectionColumn = entry:match( 'col::(.-);')
or entry:match( 'col::(.+)' );
local sectionNoAbbr = _trim( _sectionNoAbbr ) and abbr_list[_trim( _sectionNoAbbr )] and true;
return _trim( _header ), sectionNoAbbr, _sectionRarityList, _sectionQty, _sectionReprint, _trim( _sectionColumn );
end
-- Card entry function:
-- Builds the card row.
local function getSetListCard( entry, sectionNoAbbr, sectionRarityList, sectionQty, sectionReprint, sectionColumn )
-- Intialize vars:
local _number, _name, _rarityList, _qty, _reprint;
local _nameAlt, _nameLocalAlt, _rarityAlt, _typeAlt, _description, _column;
-- General values (from args or section):
local noAbbr = sectionNoAbbr or _D.flags['noAbbr'];
local rarityList = sectionRarityList or _D.args['rarity'];
local qty = (sectionQty or _D.flags['qty']) and (
(
tonumber( sectionQty or _D.args['qty'] ) or sectionQty:match('%d%d-%-%d%d-') or _D.args['qty']:match('%d%d-%-%d%d-')
) or 1
);
local reprint = (sectionReprint or _D.args['print'])
and (
(
(
tonumber( sectionReprint or _D.args['print'] )
or ( sectionReprint or _D.args['print'] ):match( 'true' )
)
and 'Reprint'
) or (sectionReprint or _D.args['print'])
)
local column = sectionColumn or _D.args['col'];
-- Local values:
-- # Split info:
local valuesStandard = split( split( entry, '//' )[1] , ';');
local valuesAlternate = split( entry, '//' )[2];
-- # Deal with standard values:
if noAbbr then
_name = _trim( valuesStandard[1] );
_rarityList = _trim( valuesStandard[2] );
_qty = _trim( valuesStandard[3] );
_reprint = _trim( valuesStandard[4] );
else
_number = _trim( valuesStandard[1] );
_name = _trim( valuesStandard[2] );
_rarityList = _trim( valuesStandard[3] );
_qty = _trim( valuesStandard[4] );
_reprint = _trim( valuesStandard[5] );
end
-- # Deal with alternate values:
if valuesAlternate then
_nameAlt = valuesAlternate:match( 'name::(.-);')
or valuesAlternate:match( 'name::(.+)' );
_nameLocalAlt = valuesAlternate:match('name%-local::(.-);')
or valuesAlternate:match('name%-local::(.+)' );
_rarityAlt = valuesAlternate:match( 'rarity::(.-);')
or valuesAlternate:match( 'rarity::(.+)' );
_typeAlt = valuesAlternate:match( 'category::(.-);')
or valuesAlternate:match( 'category::(.+)' );
_description = valuesAlternate:match('description::(.-);')
or valuesAlternate:match('description::(.+)' );
_column = column and
(valuesAlternate:match(table.concat( { column:lower(), '::(.-);' } ))
or valuesAlternate:match(table.concat( { column:lower(), '::(.+)' } )));
end
-- Build table row:
-- # Initialize:
local row = HTML( 'tr' );
-- # Card number:
if not noAbbr then
row:tag( 'td' ):wikitext(
_number and (
(_number:match( '?' ) or not _name) and _number or _link( _number )
) or ' '
):done();
end
-- # Card name:
row:tag( 'td' )
:wikitext( _trim( table.concat( { _nameAlt or wrapQuotes( _link( _name, (_name or ''):match( 'Token %(' ) and _name ), true ), _description or '' }, ' ' ) ) )
:done();
-- # Card local name:
if _D.flags['notEnglish'] then
row:tag( 'td' ):attr( 'lang', _D.ln ):wikitext( _nameLocalAlt or _name and wrapQuotes( getNameLocal( _name ) ) ):done();
end
-- # Card rarity:
row:tag( 'td' ):wikitext( _rarityAlt or getRarity( _rarityList or rarityList ) ):done();
-- # Card type:
row:tag( 'td' ):wikitext( _typeAlt or _name and getCardType( _name ) ):done();
-- # Card qty:
if qty then
row:tag( 'td' ):wikitext( _qty and (tonumber( _qty ) or _qty:match('%d%d-%-%d%d-')) or qty or 1 ):done();
end
-- # Card print:
if reprint then
row:tag( 'td' ):wikitext( _reprint or reprint ):done();
end
-- # Extra column:
if column then
row:tag( 'td' ):wikitext( _column ):done();
end
row:allDone();
return tostring( row );
end
-- Wrap function.
-- Given HTML table rows,
-- wraps it with «table» tags and builds the table header.
local function wrapTable( header, t, noAbbr, qty, reprint, column )
local noAbbr = noAbbr or _D.flags['noAbbr'];
local qty = qty or _D.flags['qty'];
local reprint = reprint or _D.flags['reprint'];
local column = column or _D.flags['column'];
-- Build HTML table:
-- # Initialize:
local HTMLtableHeader = HTML( 'table' ):attr( 'id', header or 'Top_table' ):addClass( 'wikitable' ):addClass( 'sortable' ):addClass( 'card-list' ):addClass( 'set_list' );
local HTMLtableCaption = header and HTML( 'caption' ):wikitext( header ):done();
local HTMLtableRow = HTML( 'tr' );
-- # Card number:
if not noAbbr then
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( 'Card number' ):done();
end
-- # Card name:
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( _D.flags['notEnglish'] and 'English name' or 'Name' ):done();
-- # Card local name:
if _D.flags['notEnglish'] then
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( table.concat( { _D.language, ' name' } ) ):done();
end
-- # Card rarity:
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( 'Rarity' ):done();
-- # Card type:
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( 'Category' ):done();
-- # Card qty:
if qty then
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( 'Qty' ):done();
end
-- # Card print:
if reprint then
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( 'Print' ):done();
end
-- # Extra column:
if column then
HTMLtableRow:tag( 'th' ):attr( 'scope', 'col' ):wikitext( _trim( _D.args['col'] ) ):done();
end
HTMLtableRow:done(); -- Close the </tr>.
-- Concat everything:
local HTMLtable = (header and HTMLtableHeader:node( tostring( HTMLtableCaption ) ) or HTMLtableHeader)
:node( tostring( HTMLtableRow ) )
:node( table.concat( t ) ) -- Add the table content (all card rows).
:allDone(); -- Close table (</table>).
return tostring( HTMLtable );
end
-- Main set list function:
-- Designs the card table.
local function getSetList()
local sections = _D.args[1] and split( _D.args[1], '!:' ) or _error( 'No list info given!', { ';' } );
local SetListTable = {}; -- Contains list of processed sections.
for _, section in ipairs( sections ) do
local _section;
local sectionSetListTable = {}; -- Contains list of processed card entries.
local _header, _sectionNoAbbr, _sectionRarityList, _sectionQty, _sectionReprint; -- Store section info, applied to all section entries.
if not _trim( section ) then
-- Empty section; skip.
else
-- It's a section.
local entries = split( section, '\n' );
for index, entry in ipairs( entries ) do
if not _trim( entry ) then
-- Emtpy entry; skip.
elseif index == 1 and entry:match( 'header::' ) then
-- Contains header info.
_header, _sectionNoAbbr, _sectionRarityList, _sectionQty, _sectionReprint, _sectionColumn = getSetListHeader( entry );
else
-- Card info.
table.insert( sectionSetListTable, getSetListCard( entry, _sectionNoAbbr, _sectionRarityList, _sectionQty, _sectionReprint, _sectionColumn ) );
end
end
-- Process table for each section.
_section = wrapTable( _header, sectionSetListTable, _sectionNoAbbr, _sectionQty, _sectionReprint, _sectionColumn );
end
table.insert( SetListTable, _section );
end
return table.concat( SetListTable, '\n' );
end
-------------------
-- Main functions:
-------------------
-- Main function:
-- To be called through #invoke.
function SetList.main( frame )
_D.errors = {};
_D.args = getArgs( frame, { trim = true, removeBlanks = true, parentOnly = true } );
local PAGENAME = mw.title.getCurrentTitle().text; -- {{PAGENAME}}
local NAMESPACE = mw.title.getCurrentTitle().nsText; -- {{NAMESPACE}}
getInfo();
local _setName, _setNameLocal = getSetName( PAGENAME );
local header = getHeader( _setName, _setNameLocal );
local category = getCategory( NAMESPACE )
local setList = getSetList();
local track = tracking( frame:getParent().args );
-- Return value:
local ret = {};
if _trim( NAMESPACE ) then
if _count( _D.errors ) > 0 then
for key, value in ipairs( _D.errors ) do
table.insert( ret, value );
end
end
table.insert( ret, header );
table.insert( ret, category );
table.insert( ret, setList );
else
-- When on the set page.
return setList;
end
return table.concat( ret );
end
return SetList;
-- </pre>