Module:HF/Infobox/Jutsu

local Infobox = {}

-- Libraries and Global functions --

-- "High Frequency" functions local HF = require('Module:HF') -- Parses invocation and template parameters, trims whitespace, and removes blanks. local getArgs = require('Dev:Arguments').getArgs -- Generates lists local L = require('Dev:List') -- Language functions local language = mw.language.new('en')

-- Helper functions (local to not have to worry about namespaces) local arraymap = require('Module:HF/Infobox').arraymap local arrayTable = require('Module:HF/Infobox').arrayTable local base = require('Module:HF/Infobox').base local extra1 = require('Module:HF/Infobox').extra1

-- The page title of whatever page is calling the function local pageTitle = mw.title.getCurrentTitle.text

-- Convenient constants local stripLinkToTarget = '^%[*([^%[|]*)|?' local stripPageTitleToBase = "[^(]*" local basepattern = '^[^~]*' local extra1pattern = '^[^~]*~([^~]*)'

-- Local functions (used only in this Module) --

-- Replaces local function nameCheck ( target ) local nq = mw.smw.ask{ HF.Link(target:match(stripLinkToTarget)), '?Maintenance' } if type(nq) == 'table' and (	       nq[1]['Maintenance'] == 'Name'	        or (type(nq[1]['Maintenance']) == 'table' and table.concat(nq[1]['Maintenance']):match('Name'))	    ) then return true else return nil end end

-- -- Public functions (called from a Template or article) -- -- -- Creates the infobox main title function Infobox.titleJutsu(frame) local args = getArgs(frame) local out = {} if mw.title.getCurrentTitle.isContentPage == true then table.insert( out, HF.Category('Jutsu') ) local _editFormURL = mw.html.create('span') :css('float','right'):css('font-size','x-small') :wikitext( HF.Link('Special:FormEdit/Jutsu/' .. pageTitle, 'edit') ):allDone local editFormURL = tostring(_editFormURL) if args['english'] then mw.smw.set { ['English name'] = args['english'], ['Names'] = args['english'] }		end if args['kanji'] then mw.smw.set { ['Kanji name'] = args['kanji'], ['Names'] = args['kanji'] }		else mw.smw.set { ['Maintenance'] = 'Kanji' } end if args['romaji'] then mw.smw.set{ ['Romaji_name'] = args['romaji']:match(stripLinkToTarget), ['Names'] = args['romaji'] }		end if args['teams'] then local teams = mw.text.split( args['teams'], ',%s*' ) for _, v in ipairs(teams) do				mw.smw.set{ ['Team'] = mw.text.trim(v) } end end if args['image'] then local images = mw.text.split( args['image'], '\n') for _, image in ipairs(images) do				if type(image) == 'string' then mw.smw.set{ ['Picture'] = 'File:' .. image:match("[^:;]*") } end end else mw.smw.set{ ['Maintenance'] = 'Missing image' } end if args['unnamed jutsu'] == 'Yes' then mw.smw.set{ ['Maintenance'] = 'Name' } table.insert( out, ("%s"):format( pageTitle:match("[^(]*") ) )		else				table.insert( out, pageTitle:match("[^(]*") ) end local popup = frame:newParserValue(			" " ..			" "		) return table.concat( out ) .. popup:expand .. ( args['ref'] or '' ) .. editFormURL elseif mw.title.getCurrentTitle.namespace == 10 and not pageTitle:match('/testcases') then return nil else if args['unnamed jutsu'] == 'Yes' then table.insert( out, ("%s"):format( args['english'] or pageTitle:match("[^(]*") ) )		else			table.insert( out, args['english'] or pageTitle:match("[^(]*") ) end return table.concat( out ) .. ( args['ref'] or '' ) end end

function Infobox.jutsuClassification(frame) local args = getArgs(frame) local classifications = type(args['jutsu classification']) == 'string' and mw.text.split( args['jutsu classification'], ',%s*' ) if type(classifications) == 'table' then local out = {} local icons = {} local kekkei = { ['kekkei mōra'] = true, ['kekkei tōta'] = true, ['kekkei genkai'] = true }		for _,classification in ipairs(classifications) do			if classification:match(extra1pattern) then if classification:match(basepattern):lower == 'hiden' then local options = { ['SemanticPropertyName'] = 'Clan', ['PrependText'] = 'Icon Type=Ninja clan', ['PrependTemplate'] = 'Infobox_icon', ['Print'] = 'none', ['Link'] = 'default' }					local clans = arrayTable( classification:match('^[^~]*~(.*)'), '~', options, frame ) table.insert( icons, table.concat( clans ) ) elseif kekkei[classification:match(basepattern):lower] then local options = { ['SemanticPropertyName'] = 'Kekkei Genkai', ['PrependText'] = 'Icon Type=Kekkei Genkai', ['PrependTemplate'] = 'Infobox_icon', ['Print'] = 'none', ['Link'] = 'default' }					local clans = arrayTable( classification:match('^[^~]*~(.*)'), '~', options, frame ) table.insert( icons, table.concat( clans ) ) end end if classification:match(basepattern) and #classification > 1 then mw.smw.set { ['Jutsu classification'] = classification:match(basepattern) } table.insert( out, HF.Link(classification:match(basepattern)) ) end end return table.concat( icons ) .. table.concat( out, ', ' ) else return nil end end

function Infobox.jutsuType(frame) local args = getArgs(frame) local options = { ['SemanticPropertyName'] = 'Chakra Nature', ['PrependText'] = 'Nature', ['PrependTemplate'] = 'Infobox_icon', ['Link'] = 'default' }	local values = arrayTable ( args['jutsu type'], ',%s*', options, frame ) return L.makeList( 'unbulleted', values ) end

function Infobox.jutsuRank(frame) local args = getArgs(frame) local array = mw.text.split( args['jutsu rank'], ',' ) local out = {} for _, v in ipairs( array ) do		table.insert( out, HF.Link('Jutsu rank::'..v, v..'-rank') ) end return table.concat( out, ',' ) end

function Infobox.jutsuClass(frame) local args = getArgs(frame) local options = { ['SemanticPropertyName'] = 'Jutsu class type', ['Link'] = 'none' }	local classes = arrayTable ( args['jutsu class type'], ',%s*', options, frame ) return table.concat( classes, ', ' ) end

function Infobox.jutsuRange(frame) local args = getArgs(frame) local ranges = { ['Short'] = 'Short range (0-5m)', ['Mid'] = 'Mid range (5-10m)', ['Long'] = 'Long range (10m+)', ['Short, Mid, Long'] = 'All ranges', ['Short, Mid'] = 'Short to Mid range (0-10m)', ['Mid, Long'] = 'Mid to Long range (5m+)', ['Short, Long'] = 'Short or Long range (0-5m or 10m+)' }	arrayTable ( args['jutsu range'], ',%s*', { ['SemanticPropertyName'] = 'Jutsu range' } ) return ranges[args['jutsu range']] or args['jutsu range']..'-range' end

function Infobox.jutsuParent(frame) local args = getArgs(frame) local options = { ['SemanticPropertyName'] = 'Parent', ['Link'] = 'Unnamed', ['UnnamedFormat'] = true }	local parents = arrayTable ( args['parent jutsu'], ',%s*', options ) return L.makeList( 'unbulleted', parents ) end

function Infobox.jutsuMedia(frame) local args = getArgs(frame) local out = {} local mtypes = { ['Movie'] = 'Jutsu/NonCanon', ['Game'] = 'Jutsu/NonCanon', ['Game, Movie'] = 'Jutsu/NonCanon' }	local mq = mw.smw.ask { (HF.Link('Concept:%s')):format( mtypes[args['jutsu media']] or 'Jutsu/Canon' ), (HF.Link('Parent::%s')):format( mw.title.getCurrentTitle.prefixedText ), '?Appears in', '?Maintenance', ('userparam=%s'):format(args['jutsu media']), 'mainlabel=main', 'limit=200' }	local hasNCderivatives = mw.smw.ask { (HF.Link('Concept:%s')):format( 'Jutsu/NonCanon' ), (HF.Link('Parent::%s')):format( mw.title.getCurrentTitle.prefixedText ) }	if type(mq) == 'table' then for _, parent in ipairs(mq) do			local mainlink = (				   parent['Maintenance'] == 'Name'				    or ( type(parent['Maintenance']) == 'table' and table.concat(parent['Maintenance']):match('Name') )			   )				and ("%s"):format(					HF.Link( parent['main']:match(stripLinkToTarget), parent['main']:match('%[%[:?([^|]*)|?'):match(stripPageTitleToBase) )				)				or HF.Link(					parent['main']:match(stripLinkToTarget),					parent['main']:match('%[%[:?([^|]*)|?'):match(stripPageTitleToBase)				) local dq = mw.smw.ask { (HF.Link('Concept:%s')):format( mtypes[args['jutsu media']] or 'Jutsu/Canon' ), (HF.Link('Parent::%s')):format( parent['main']:match(stripLinkToTarget) ), ('userparam=%s'):format( args['jutsu media'] or 'Anime, Manga' ), 'mainlabel=main', 'named args=yes', 'limit=20' }			local derivatives = {} if type( dq ) == 'table' then for _, derived in ipairs(dq) do					local dlink = (					   derived['Maintenance'] == 'Name'					    or type(derived['Maintenance']) == 'table'				        and table.concat(derived['Maintenance']):match('Name')					    ) and ("%s"):format(						HF.Link( derived['main']:match(stripLinkToTarget), derived['main']:match('%[%[:?([^|]*)|?'):match(stripPageTitleToBase) )					)					or HF.Link(						derived['main']:match(stripLinkToTarget),						derived['main']:match('%[%[:?([^|]*)|?'):match(stripPageTitleToBase)					) table.insert( derivatives, dlink ) end table.insert( out, mainlink .. L.makeList( 'bulleted', derivatives ) ) else table.insert( out, mainlink ) end end return L.makeList( 'bulleted', out ) elseif type(hasNCderivatives) == 'table' then local t = mw.title.new( 'SearchByProperty', 'Special' ).prefixedText local q = mw.uri.buildQueryString{ ['property'] = 'Parent', ['value'] = mw.uri.encode(	           mw.title.getCurrentTitle.prefixedText,	            'WIKI'	            ) }       local searchlink = HF.ExternalLink(            tostring(mw.uri.fullUrl(t,q)),            'All derived jutsu'        ) return (' %s '):format( searchlink ) end end

function Infobox.jutsuRelated(frame) local args = getArgs(frame) return arraymap( args['related jutsu'], ',%s*', HF.Link('%s'), ', ' ) end

function Infobox.jutsuUsers(frame) local args = getArgs(frame) local out = {} -- Valid media types local mtypes = { anime = true, manga = true, novel = true, game = true, movie = true, ['movie canon'] = true } -- Divides users into actionable items (even if there's only one) local users = args['users'] and mw.text.split( args['users'], ',%s*' ) -- Checks if any user entries exist, and if they don't, return nil if type(users) ~= 'table' then return nil end -- For each user for _, user in ipairs( users ) do   -- checks if the entry is real or empty if type(user) == 'string' and #user < 1 then break end -- separates user name from media local prime, media = user:match('([^%~]*)%~?([^%~]*)') local link = HF.Link(     base( prime ):match(stripLinkToTarget),      base( prime ):match(stripLinkToTarget):match(stripPageTitleToBase)    ) link = nameCheck( prime ) == true and ("%s"):format( link ) or link

--- AdditionalInfo -- Puppetry handling local puppetry = user:match('puppet~(.*)$') if puppetry then puppetry = (' (Puppetry using %s)') :format(mw.text.listToText(mw.text.split(puppetry, '~'))) end -- "with" handling local with = user:match('with~([^%~]*)') and (' (with %s)'):format(user:match('with~([^%~]*)')) local AdditionalInfo = puppetry or with or ''

--- Media local Media = '' if media and mtypes[media:lower] and media:lower ~= 'movie canon' then Media = ('(%s only)') :format( language:ucfirst( media ) ) elseif media and media:lower == 'movie canon' then Media = '(Movie only)' end

--- Summons local cq = mw.smw.ask { (HF.Link('Contract::%s')):format( prime:match(stripLinkToTarget) ), 'mainlabel=main' }   local sl = {} if type(cq) == 'table' then for _, v in ipairs( cq ) do       table.insert( sl, v['main'] ) end end local Summons = ((#sl > 0)       and ( pageTitle == 'Summoning Technique' or pageTitle == 'Destruction Bug Host Technique' )) and ( ' (%s)' ):format( table.concat( sl, ", " ) ) or ''

-- SMW set local setmtype = ( media and mtypes[ media:lower ] ) and language:ucfirst( media:lower ) or 'null' mw.smw.set { ['User tech'] = prime .. ';' .. setmtype }

table.insert( out, link .. AdditionalInfo .. Summons .. Media ) end return L.makeList( 'bulleted', out ) end - -- Exported functions (used in this and other Modules) -- - -- None. - -- Output (send it back to whatever called it) -- - return Infobox