Difference between revisions of "Module:Card type"

From Yugipedia
Jump to: navigation, search
(Build _redirect, even though it's not being practically implemented yet. Manage input better, to allow this module to be used with other modules. Rename some vars. Add comments.)
(Trying to make this more efficient. Deal with colored Egyptian Gods. Set up for other cards.)
Line 40: Line 40:
 
     local labels = type( ... or nil ) == 'table' and ... or  { ... };  --  Make sure it's a table.
 
     local labels = type( ... or nil ) == 'table' and ... or  { ... };  --  Make sure it's a table.
 
     local function __link( v, label )
 
     local function __link( v, label )
         return '[['..v..'|'..(_trim( label ) or split( v, ' %(' )[1])..']]';
+
         return ('[[%s|%s]]'):format( v, (_trim( label ) or split( v, ' %(' )[1]) );
 
     end
 
     end
 
     if type( v ) == 'string' then
 
     if type( v ) == 'string' then
Line 89: Line 89:
 
--  Error function:
 
--  Error function:
 
--  Generates error messages and categories.
 
--  Generates error messages and categories.
function _error( message )
+
function _error( message ) -- @@@ input list of categories.
 
     local _error = mw.html.create( 'div' )
 
     local _error = mw.html.create( 'div' )
                     :tag( 'strong' ):addClass( 'error' ):wikitext( 'Error: '..message ):done()
+
                     :tag( 'strong' ):addClass( 'error' ):wikitext( ('Error: %s'):format( message ) ):done()
 
                 :allDone();
 
                 :allDone();
     local cat = ('[[Category:%s]]'):format( 'Pages with script errors' )..
+
     local cat = '[[Category:Pages with script errors]][[Category:((Card type)) transclusions to be checked]]';
                ('[[Category:%s]]'):format( '((Card type)) transclusions to be checked' );
+
     return ('%s\n%s'):format( tostring( _error ), cat ); -- @@@ or error()
     return tostring( _error )..cat -- @@@ or error()
 
 
end
 
end
  
Line 192: Line 191:
 
     local primary = _show( card, 'Primary type' );
 
     local primary = _show( card, 'Primary type' );
 
     if not _trim( primary ) then
 
     if not _trim( primary ) then
         return _error( 'On «_monster»; No primary type available!' );
+
         return card:match( '(original)' ) and _link( 'Monster Card' )  --  For Egyptian Gods.
 +
            or _error( 'On «_monster»; No primary type available!' );
 
     end
 
     end
 
     if primary:match('Token') then
 
     if primary:match('Token') then
Line 224: Line 224:
 
     end
 
     end
 
      
 
      
     return _show( card, 'Property (short)', true )..' '.._link( 'Spell Card' );
+
     return ('%s %s'):format( _show( card, 'Property (short)', true ), _link( 'Spell Card' ) );
 
end
 
end
 
--@@@ may be merged, depending on what I want to do later.
 
--@@@ may be merged, depending on what I want to do later.
Line 236: Line 236:
 
     end
 
     end
 
      
 
      
     return _show( card, 'Property (short)', true )..' '.._link( 'Trap Card' );
+
     return ('%s %s'):format( _show( card, 'Property (short)', true ), _link( 'Spell Card' ) );
 
end
 
end
  
Line 265: Line 265:
 
         return _error( 'On «_type»; Non-standard card type!' );
 
         return _error( 'On «_type»; Non-standard card type!' );
 
     end
 
     end
 +
end
 +
 +
function _class( card )
 +
 
 +
  return
 
end
 
end
  
Line 299: Line 304:
 
     --  «args» for the args table;
 
     --  «args» for the args table;
 
     --  «argsN» for the number or arguments;
 
     --  «argsN» for the number or arguments;
    --  «_card» for the card to be processed;
 
    --  «track» for tracking stuff;
 
 
     local args = getArgs( frame, { trim = true, parentOnly = true } ); -- Args table.
 
     local args = getArgs( frame, { trim = true, parentOnly = true } ); -- Args table.
 
      
 
      

Revision as of 20:01, 28 August 2017

--  <pre>
--  Module for {{Card type}}.
--  Can also be used through other modules.
--  @@@ for ideas. 
local CardType = {};

---------------------
--  External modules:
---------------------
local getArgs = require( 'Dev:Arguments' ).getArgs;

---------
--  Data:
---------
local data              = mw.loadData( 'Module:Card type/data' );
local abilities         = data.abilities;
local monsterCardTypes  = data.monsterCardTypes;

------------------
--  Aux functions:
------------------
--  mw functions:
local split = mw.text.split;

--  Trim function:
--  Trims white space from front and tail of string.
--  If the input is only white space, returns nil.
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.
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, (_trim( label ) or split( v, ' %(' )[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

--  Unlink function:
--  If a string is passed, unlinks
--  and returns the page name (not the label).
--  If a table is passed, unlinks every instance of it
--  and returns the table with the page names for each respective entry.
function _unlink( v )
    local function __unlink( v )
        return _trim( v ) and (v:match( '%[%[:?(.-)[|%]]' ) or _trim( v ));
    end
    if type( v ) == 'string' then
        return __unlink( v );
    elseif type( v ) == 'table' then
        local t = {};
        for key, value in ipairs( v ) do
            table.insert( t, __unlink( value ));
        end
        return t;
    else
        return v;
    end
end

--  Table count function:
--  Given a table, counts how many valuee it has.
function _count( t ) -- @@@ error() for wrong type()
    local counter = 0;
    for key, value in pairs( t ) do
        counter = counter + 1;
    end
    return counter;
end

--  Error function:
--  Generates error messages and categories.
function _error( message ) -- @@@ input list of categories.
    local _error = mw.html.create( 'div' )
                    :tag( 'strong' ):addClass( 'error' ):wikitext( ('Error: %s'):format( message ) ):done()
                :allDone();
    local cat = '[[Category:Pages with script errors]][[Category:((Card type)) transclusions to be checked]]';
    return ('%s\n%s'):format( tostring( _error ), cat ); -- @@@ or error()
end

function _redirect( card )
    local pagename = _trim( _show( card, 'Page name' ) );
    return pagename ~= card and pagename;
end

--  Show function:
--  Similar to #show parser function.
--  Returns table with the results.
function _show( page, property, link )
    --  At this point, SMW is enabled and «page» is formatted properly (as pagename).
    local result =  mw.smw.ask{ _link( page ), ('?%s='):format( property ), mainlabel = '-' };
    
    if not result or _count( result ) == 0 or _count( result[1] ) == 0 then
        return;
    end
    
    local show = type( result[1][1] ) == 'string' and result[1] or result[1][1];

    return table.concat( link and show or _unlink( show ), '\n' );
end

-------------------
--  Main functions:
-------------------
--  Monster card type function:
--  Only one allowed per card.
--  «Pendulum» is not included here.
function _monsterCardType( t )
    for key, value in ipairs( t ) do
        if monsterCardTypes[_trim( value:lower():gsub( ' monster', '' ) )] then
            return value;
        end
    end
end

--  Ability function:
--  Only one allowed per card.
function _ability( t )
    for key, value in ipairs( t ) do
        if abilities[_trim( value:lower():gsub( ' monster', '' ) )] then
            return value;
        end
    end
end

--  Effect function:
--  Misleading name; checks for Effect/Normal Monster. 
function _effect( t )
    for key, value in ipairs( t ) do
        if value:match('Effect') then
            return 'Effect Monster';
        elseif value:match('Normal') then
            return 'Normal Monster';
        end
    end
end

--  Full card type function (for monsters only):
--  Given every value a monster can have,
--  Concatenates them and returns.
function _full( pendulum, monsterCardType, tuner, ability, effect )
    --  Effect <Ability> Tuner <Monster card type> Pendulum
    --  Build backwards.
    local cardType = {};
    local notLast  = false;
    if pendulum then
        table.insert( cardType, 1, _link( 'Pendulum Monster' ));
        notLast = true;
    end
    if monsterCardType then
        table.insert( cardType, 1, _link( monsterCardType, notLast and monsterCardType:gsub( ' [Mm]onster', '' ) ) );
        notLast = true;
    end
    if tuner then
        table.insert( cardType, 1, _link( 'Tuner monster' , notLast and 'Tuner' ) );
        notLast = true;
    end
    if ability then
        table.insert( cardType, 1, _link( ability, notLast and ability:gsub( ' [Mm]onster', '' ) ) );
        notLast = true;
    end
    if effect and not ability then
        table.insert( cardType, 1, _link( effect, notLast and effect:gsub( ' [Mm]onster', '' ) ) );
    end

    return table.concat( cardType, ' ' ) -- @@@ [[Tuner Synchro]], unlink.
end

--  Monster card function:
--  Fetches monster card type, ability, Pendulum, Tuner, Token.
--  Prints full card type.
function _monster( card )
    local primary = _show( card, 'Primary type' );
    if not _trim( primary ) then
        return card:match( '(original)' ) and _link( 'Monster Card' )   --  For Egyptian Gods.
            or _error( 'On «_monster»; No primary type available!' );
    end
    if primary:match('Token') then
        return _link( 'Token Monster', 'Token' );
    end
    
    --  Primary type:
    local primaryTable    = split( primary, '\n' );
    local monsterCardType = _monsterCardType( primaryTable );
    local pendulum        = primary:match('Pendulum');
    local effect          = _effect( primaryTable );
    
    --  Secondary type:
    local secondary       = _trim( _show( card, 'Secondary type' ) );
    local secondaryTable  = secondary and split( secondary, '\n' );
    local ability         = secondary and _ability( secondaryTable );
    local tuner           = secondary and secondary:match('Tuner');
    
    --  Full monster card type:
    local full = _full( pendulum, monsterCardType, tuner, ability, effect );
    return full;
end

--  Spell card function:
--  Fetches property,
--  Prints full card type.
function _spell( card )
    local _property = _show( card, 'Property' );
    if not _trim( _property ) then
        return _error( 'On «_spell»; No property available!' )
    end
    
    return ('%s %s'):format( _show( card, 'Property (short)', true ), _link( 'Spell Card' ) );
end
--@@@ may be merged, depending on what I want to do later.
--  Trap card function:
--  Fetches property,
--  Prints full card type.
function _trap( card )
    local _property = _show( card, 'Property' );
    if not _trim( _property ) then
        return _error( 'On «_trap»; No property available!' )
    end
    
    return ('%s %s'):format( _show( card, 'Property (short)', true ), _link( 'Spell Card' ) );
end

function _counter()
    return _link( 'Counter' );
end

--  Type function:
--  Processes the card, to figure out the actual card type:
--  Monster, Spell, Trap, other.
--  (where «other» can be Tip, Strategy, etc..) 
function _type( card )
    local _cardType = _show( card, 'Card type' );
    if not _trim( _cardType ) then
        return _error( 'On «_type»; No card type available!' );
    end
    
    _cardType = _cardType:lower();
    if _cardType:match('monster') then
        return _monster( card );
    elseif _cardType:match('spell') then
        return _spell( card );
    elseif _cardType:match('trap') then
        return _trap( card );
    elseif _cardType:match('counter') then -- @@@ tip/strategy/nongame??NoSMW/FAQ??
        return _counter();
    else
        return _error( 'On «_type»; Non-standard card type!' );
    end
end

function _class( card )
   
   return 
end

--  _main function, to be exported:
--  Processes a string, the card name.
--  Looks for errors (if empty).
--  Else, figures the card type.
function _main( s )
    local _card = _unlink( s );
    if not _card then
        return _error( 'Empty value!' );
    end
    local _page = _card:gsub( '#', '' );
    -- @@@ check if it's from the actual game( Class 1: Official )
    local redirect = _redirect( _page ); -- @@@cat + text
    
    return _type( _page )
end

--  Main function:
--  Processes input;
--  if it's a frame (used externally, through {{Card type}},
--  fetch value, throws errors regarding the number of arguments; Then sends it to _main.
--  Else, (if it's a string (should be, if used through other modules!))
--  Send it to _main directly.
function CardType.main( frame )
    if not mw.smw then
        return _error( 'mw.smw module not found' );
    end
    if type( frame ) == 'string' then
        --  If used through other modules.
        return _main( frame );
    end
    --  «args» for the args table;
    --  «argsN» for the number or arguments;
    local args = getArgs( frame, { trim = true, parentOnly = true } ); -- Args table.
    
    local argsN = _count( args );
    if argsN > 1 then
        return _error( 'Too many arguments! Use only one!' );
    elseif argsN < 1 then
        return _error( 'No arguments! Use one!' );
    end
    
    return _main( args[1] );
end

return CardType;
--  </pre>