Module:Sandbox/Abcboy/Langtable

Documentation for this module may be created at Module:Sandbox/Abcboy/Langtable/doc

local p = {}

local data = require("Module:Sandbox/Abcboy/Langtable/data").data
local note_group = "note"

-- Returns the code for the start of the row,
-- with the appropriate class for core game languages.
function langtable_row(language)
	return '|- class="name-' .. language.code .. '"'
end

-- Returns a cell that links to the language's page.
function langtable_lang(language, count)
	local arr = { "| " }
	
	-- Add rowspan if there are multiple names in this language.
	if count >= 2 then
		table.insert(arr, 'rowspan="' .. count .. '" | ')
	end
	
	-- Link to the page corresponding to this language, or the language's name if it has no page.
	if language.page ~= nil then
		table.insert(arr, "[[Pokémon in " .. language.page .. "|" .. language.name .. "]]")
	else 
		table.insert(arr, language.name)
	end
	
	return table.concat(arr, "")
end

-- Returns cells with the name, romanization, meaning, and note as applicable.
function langtable_name(language, index, name, romanization, meaning, note)
	local arr = {}
	
	-- Wrap the name in a span to mark it as the appropriate language.
	-- If the language is written right-to-left, mark the direction explicitly.
	-- Append romanizations in italics or any notes, if present.
	-- Finally, add the cell for the name.
	local cell = { "| <span " }
	if language.rtl then
		table.insert(cell, 'dir="rtl" ')
	end
	table.insert(cell, 'lang="' .. language.code .. '">' .. name .. "</span>")
	if romanization ~= nil and romanization ~= "" then
		table.insert(cell, " ''" .. romanization .. "''")
	end
	if note ~= nil then
		table.insert(cell, note)
	end
	table.insert(arr, table.concat(cell, ''))
	
	-- Add the cell for the meaning.
	if meaning ~= nil then
		table.insert(arr, "| " .. meaning)
	end
	return table.concat(arr, '\n')
end

-- Makes a ref tag containing the text in the provided note.
function langtable_note(frame, note)
	if note == nil or note == "" then
		return nil
	end
	return frame:extensionTag("ref", note, { group = note_group } )
end

function p._langtable(frame, args)
	-- Check if the reference group for notes should be named something else.
	if args.note_group ~= nil and args.note_group ~= '' then
		note_group = args.note_group
	end

	-- Check if a meaning is specified for any language.
	-- If there is one, then we need to show the "Meaning" column.
	local has_meaning = false
	for arg, _ in pairs(args) do
		if arg:sub(-#"_m") == "_m" then
			has_meaning = true
			break
		end
	end
	
	-- Make the table header row, with the "Meaning" column if needed.
	local arr = {"! Language", "! Name"}
	if has_meaning then
		table.insert(arr, '! Meaning')	
	end
	
	-- Make the table body rows for each name in each language.
	for _, language in ipairs(data) do
		-- Check that parameters are used correctly.
		-- Either a single name ("en") or multiple names ("en_1", "en_2", ...) can be provided,
		-- but "en" and "en_1", "en_2", ... shouldn't be provided at the same time.
		local code = language.code
		if args[code] ~= nil and args[code .. '_1'] ~= nil then
			error('Both "' .. code .. '" and "' .. code .. '_1" were provided as arguments', 0)
		end
		if args[code .. '_1'] ~= nil and args[code .. '_2'] == nil then
			error('Argument "' .. code .. '_1" was provided without the corresponding argument "' .. code .. '_2"', 0)
		end
		if args[code .. '_1'] == nil and args[code .. '_2'] ~= nil then
			error('Argument "' .. code .. '_2" was provided without the corresponding argument "' .. code .. '_1"', 0)
		end
		
		-- Only one name in this language
		if args[code] ~= nil and args[code] ~= "" then
			local index = 1
			local name = args[code]
			local romanization = args[code .. '_r']
			local meaning = args[code .. '_m']
			local note = langtable_note(frame, args[code .. '_n'])
			if has_meaning and meaning == nil then
				meaning = ''
			end
			table.insert(arr, langtable_row(language))
			table.insert(arr, langtable_lang(language, 1))
			table.insert(arr, langtable_name(language, index, name, romanization, meaning, note))

		-- Multiple names in this language
		elseif args[code .. '_1'] ~= nil and args[code .. '_1'] ~= "" then
			-- Count how many names were provided
			local count = 1
			while args[code .. '_' .. count] ~= nil and args[code .. '_' .. count] ~= "" do
				count = count + 1
			end
			count = count - 1
			
			for index = 1, count, 1 do
				local name = args[code .. '_' .. index]
				local romanization = args[code .. '_' .. index .. '_r']
				local meaning = args[code .. '_' .. index .. '_m']
				local note = langtable_note(frame, args[code .. '_' .. index .. '_n'])
				if has_meaning and meaning == nil then
					meaning = ''
				end
				table.insert(arr, langtable_row(language))
				if index == 1 then
					table.insert(arr, langtable_lang(language, count))
				end
				table.insert(arr, langtable_name(language, index, name, romanization, meaning, note))
			end
		end
	end
	return table.concat(arr, '\n')
end

function p.langtable(frame)
	local templateArgs = frame:getParent().args
	return p._langtable(frame, templateArgs)
end

return p