Module:Card table/Processor/DefaultProcessor

From Yugipedia
< Module:Card table‎ | Processor
Revision as of 12:42, 23 January 2019 by Becasita (talk | contribs) (To test. Handler table.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
-- <pre>
--[=[Doc
@module ???
@description 
@author [[User:Becasita]]
@contact [[User talk:Becasita]]
@TODO add {{{decks}}} and {{{appears_in_av}}}
@TODO create a Message wrapper with format and transform(cb(string: this.message))
@TODO escape user input
]=]

local UTIL = require( 'Module:Util' );

local mwTextSplit  = mw.text.split;
local mwTextGsplit = mw.text.gsplit;

--[[Doc
@class DefaultProcessor
@description This class contains generic handlers for common
card table extensions parameters.
]]
local DefaultProcessor = {};
DefaultProcessor.__index = DefaultProcessor;

DefaultProcessor[ 'name' ] = function( ct, parameter, argument )
	local pagename = mw.title.getCurrentTitle().text;

	ct:Contents():Header()
		:setId( 'Card name' )
		:setContent( {
			pagename = pagename,
			displayName = argument or UTIL.removeDab( pagename ),
		} )
	;
end

DefaultProcessor[ 'alternative_names' ] = function( ct, parameter, argument )
	local altNames = mw.text.split( argument or '', '%s*[\n\*;]%s*' );

	ct:Contents():Rows():Set( 'Alternative names' )
		:setId( 'Card alternative names' )
		:setContent( {
			altNames = altNames,
		} )
	;
end

DefaultProcessor[ 'card_type' ] = function( ct, parameter, argument )
	local cardType = DATA.getCardType( argument );

	if cardType then
		ct:Contents():Rows():Set( 'Card type' )
			:setContent( {
				cardType = cardType,
			} )
		;
	else
		local message = ('Cannot find a Card Type (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'attribute' ] = function( ct, parameter, argument )
	local attribute = DATA.getAttribute( argument );

	if attribute then
		ct:Contents():Rows():Set( 'Attribute' )
			:setContent( {
				attribute = attribute,
			} )
		;
	-- TODO: self._flags.isMonster = true;
	else
		local message = ('Cannot find an Attribute (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'level' ] = function( ct, parameter, argument )
	local level = tonumber( argument );

	if level then
		ct:Contents():Rows():Set( 'Level' )
			:setContent( {
				level = level,
			} )
		;
	else
		local message = ('The Level (%s) must be a number, but instead was `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'rank' ] = function( ct, parameter, argument )
	local rank = tonumber( argument );

	if rank then
		ct:Contents():Rows():Set( 'Rank' )
			:setContent( {
				rank = rank,
			} )
		;
	else
		local message = ('The Rank (%s) must be a number, but instead was `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'property' ] = function( ct, parameter, argument )
	local property = DATA.getProperty( argument );

	if property then
		ct:Contents():Rows():Set( 'Property' )
			:setContent( {
				property = property,
			} )
		;
	else
		local message = ('Cannot find a Property (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'pendulum_effect_types' ] = function( ct, parameter, argument )
	local pendulumEffectTypes = {};

	for pendulumEffectTypesPart in mwTextGsplit( argument, '%s*,%s*' ) do
		local pendulumEffectType = DATA.getEffectType( pendulumEffectTypesPart );

		if pendulumEffectType then
			table.insert( pendulumEffectTypes, pendulumEffectType );
		else
			local message = ('Cannot find a Pendulum Effect Type (%s) for `%s`!'):format(
				UTIL.formatParameter( parameter ),
				pendulumEffectTypesPart
			);

			ct:error( message );
		end
	end

	if pendulumEffectTypes[ 1 ] then
		ct:Contents():Rows():GetOrSet( 'Effect types' )
			:setContent( {
				pendulumEffectTypes = pendulumEffectTypes,
			} )
		;
	else
		local message = ('Cannot find any Pendulum Effect Type (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'effect_types' ] = function( ct, parameter, argument )
	local effectTypes = {};

	for effectTypesPart in mwTextGsplit( argument, '%s*,%s*' ) do
		local effectType = DATA.getEffectType( effectTypesPart );

		if effectType then
			table.insert( effectTypes, effectType );
		else
			local message = ('Cannot find an Effect Type (%s) for `%s`!'):format(
				UTIL.formatParameter( parameter ),
				effectTypesPart
			);

			ct:error( message );
		end
	end

	if pendulumEffectTypes[ 1 ] then
		ct:Contents():Rows():GetOrSet( 'Effect types' )
			:setContent( {
				effectTypes = effectTypes,
			} )
		;
	else
		local message = ('Cannot find any Effect Type (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'pendulum_scale' ] = function( ct, parameter, argument )
	local pendulumScale = tonumber( argument );

	if pendulumScale then
		ct:Contents():Rows():Set( 'Pendulum Scale' )
			:setContent( {
				pendulumScale = pendulumScale,
			} )
		;
	else
		local message = ('The Pendulum Scale (%s) must be a number, but instead was `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'link_arrows' ] = function( ct, parameter, argument )
	local linkArrows = {};

	for linkArrrowsPart in mwTextGsplit( argument, '%s*,%s*' ) do
		local linkArrow = DATA.getEffectType( linkArrrowsPart );

		if linkArrow then
			table.insert( linkArrows, linkArrow );
		else
			local message = ('Cannot find a Link Arrow (%s) for `%s`!'):format(
				UTIL.formatParameter( parameter ),
				linkArrrowsPart
			);

			ct:error( message );
		end
	end

	if linkArrows[ 1 ] then
		ct:Contents():Rows():Set( 'Link Arrows' )
			:setContent( {
				linkArrows = linkArrows,
			} )
		;
	else
		local message = ('Cannot find any Link Arrow (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'types' ] = function( ct, parameter, argument )
	local types = {};

	for typesPart in mwTextGsplit( argument, '%s*/%s*' ) do
		local foundType = Data.getType( typesPart ); -- TODO: pass getType and the valid types as arg to this function.

		if foundType then
			table.insert( types, foundType );
		else
			local message = ('Cannot find a Type (%s) for `%s`!'):format(
				UTIL.formatParameter( parameter ),
				typesPart
			);

			ct:error( message );
		end
	end

	if types[ 1 ] then
		ct:Contents():Rows():Set( 'Types' )
			:setContent( {
				types = types,
			} )
		;

		ct:Contents():Rows():GetOrSet( 'Lore box' )
			:setContent( {
				types = types,
			} )
		;
	else
		local message = ('Cannot find any Type (%s) for `%s`!'):format(
			UTIL.formatParameter( parameter ),
			argument
		);

		ct:error( message );
	end
end

DefaultProcessor[ 'atk' ] = function( ct, parameter, argument )
	ct:Contents():Rows():GetOrSet( 'Stats' )
		:setContent( {
			atk = argument,
		} )
	;

	ct:Contents():Rows():GetOrSet( 'Lore box' )
		:setContent( {
			atk = argument,
		} )
	;
end

DefaultProcessor[ 'def' ] = function( ct, parameter, argument )
	ct:Contents():Rows():GetOrSet( 'Stats' )
		:setContent( {
			def = argument,
		} )
	;

	ct:Contents():Rows():GetOrSet( 'Lore box' )
		:setContent( {
			def = argument,
		} )
	;
end

DefaultProcessor[ 'summons' ] = function( ct, parameter, argument )
	local summons = mw.text.split( argument or '', '%s*[\n\*;]%s*' );
	
	ct:Contents():Rows():Set( 'Summons' )
		:setContent( {
			summons = summons,
		} )
	;
end

DefaultProcessor[ 'ritual_summons' ] = function( ct, parameter, argument )
	local ritualSummons = mw.text.split( argument or '', '%s*[\n\*;]%s*' );
	
	ct:Contents():Rows():Set( 'Ritual Summons' )
		:setContent( {
			ritualSummons = ritualSummons,
		} )
	;
end

DefaultProcessor[ 'summoned_by' ] = function( ct, parameter, argument )
	local summonedBy = mw.text.split( argument or '', '%s*[\n\*;]%s*' );
	
	ct:Contents():Rows():Set( 'Summoned by' )
		:setContent( {
			summonedBy = summonedBy,
		} )
	;
end

DefaultProcessor[ 'password' ] = function( ct, parameter, argument )
	ct:Contents():Rows():Set( 'Password' ) -- TODO: check length == 8 ? 
		:setContent( {
			password = argument,
		} )
	;
end

DefaultProcessor[ 'limitation_text' ] = function( ct, parameter, argument )
	-- TODO: this is triggered by "if token". On 'types', if token, DefaultProcessor[ 'limitation_text' ]( ct, 'limitation_text', 'cannot be used...' )
	ct:Contents():Rows():Set( 'Limitation text' )
		:setContent( {
			limitationText = argument,
		} )
	;
end

DefaultProcessor[ 'pendulum_effect' ] = function( ct, parameter, argument )
	ct:Contents():Rows():Set( 'Pendulum Effect' )
		:setContent( {
			pendulumEffect = argument,
		} )
	;

	ct:Contents():Rows():GetOrSet( 'Lore box' )
		:setContent( {
			pendulumEffect = argument,
		} )
	;
end

DefaultProcessor[ 'lore' ] = function( ct, parameter, argument )
	ct:Contents():Rows():Set( 'Lore' )
		:setContent( {
			lore = argument,
		} )
	;

	ct:Contents():Rows():GetOrSet( 'Lore box' )
		:setContent( {
			lore = argument,
		} )
	;
end

----------------------------------------
-- Non-English names, lores and effects:
do
	-- keys:
	-- Name
	-- Alternative names
	-- Translated name
	-- Romanized name
	-- Pendulum Effect
	-- Translated Pendulum Effect
	-- Lores
	-- Translated lores
	local LANGUAGES = DATA( 'language' );
	local ENGLISH_LANGUAGE = DATA.getLanguage( 'en' );
	local ROMANIZED_LANGUAGES = {
		[ DATA.getLanguage( 'ja' ).index ] = true,
	--	[ DATA.getLanguage( 'zh' ).index ] = true,
		[ DATA.getLanguage( 'ko' ).index ] = true,
	};

	local function processNonEnglishData( ct, language, key, parameter, argument )
		local data = ct:Contents():Sections():GetOrSet( 'Non-English data' );

		local languageData = data:getContent()[ language.index ] or {};

		languageData[ key ] = ( key == 'Alternative names'
			and mwTextSplit( argument, '%s*\n%s*' )
			or argument
		);

		data:setContent( {
			[language.index] = languageData,
		} );
	end

	for _, language in ipairs( LANGUAGES ) do
		if language.index ~= ENGLISH_LANGUAGE.index then
			DefaultProcessor[ table.concat{ language.index, '_name' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Name', parameter, argument );
			end
			DefaultProcessor[ table.concat{ language.index, '_alternative_names' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Alternative names', parameter, argument );
			end
			DefaultProcessor[ table.concat{ language.index, '_translated_name' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Translated name', parameter, argument );
			end

			if ROMANIZED_LANGUAGES[ language.index ] then
				DefaultProcessor[ table.concat{ language.index, '_romanized_name' } ] = function( ct, parameter, argument )
					return processNonEnglishData( ct, language, 'Romanized name', parameter, argument );
				end
			end

			DefaultProcessor[ table.concat{ language.index, '_pendulum_effect' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Pendulum Effect', parameter, argument );
			end
			DefaultProcessor[ table.concat{ language.index, '_translated_pendulum_effect' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Translated Pendulum Effect', parameter, argument );
			end

			DefaultProcessor[ table.concat{ language.index, '_lore' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Lore', parameter, argument );
			end
			DefaultProcessor[ table.concat{ language.index, '_translated_lore' } ] = function( ct, parameter, argument )
				return processNonEnglishData( ct, language, 'Translated lore', parameter, argument );
			end
		end
	end
end

DefaultProcessor[ '' ] = function( ct, parameter, argument )
	-- body
end

DefaultProcessor[ '' ] = function( ct, parameter, argument )
	-- body
end

DefaultProcessor[ '' ] = function( ct, parameter, argument )
	-- body
end

DefaultProcessor[ '' ] = function( ct, parameter, argument )
	-- body
end

---------------------
-- Search categories:
-- TODO add monster token logic later (or where appropriate)
do
	-- Search categories:
	local SEARCH_CATEGORIES = {
		'supports',
		'anti-supports',
		'archseries',
		'supports_archetypes',
		'anti-supports_archetypes',
		'related_to_archseries',
		'counter',
		'action',
		'stat_change',
		'm/s/t',
		'summoning',
		'attack',
		'banished',
		'life_points',
		'fm_for',
		'sm_for',
		'misc',

	};

	local function processSearchCategories( ct, parameter, argument )
		local values = mwTextSplit( argument, '%s*\n%s*' ); -- TODO: filter duplicates?

		-- TODO: check if should be added or not ??
		ct:Contents():Sections():GetOrSet( 'Search categories' )
			:setContent( {
				[parameter] = values,
			} )
		;
	end

	for _, searchCategory in ipairs( SEARCH_CATEGORIES ) do
		DefaultProcessor[ searchCategory ] = function( ct, parameter, argument )
			return processSearchCategories( ct, parameter, argument );
		end
	end
end

return DefaultProcessor;
-- </pre>