Zelda Wiki

Want to contribute to this wiki?
Sign up for an account, and get started!

Come join the Zelda Wiki community Discord server!

READ MORE

Zelda Wiki
Advertisement
This is the main module for the following templates:
local p = {}

local utilsArg = require("Module:UtilsArg")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsTable = require("Module:UtilsTable")

local data = require("Module:Script/Data")

function p.Main(frame)
	local frameArgs = utilsTable.clone(frame:getParent().args)
	if frameArgs[2] then
		frameArgs[2] = string.upper(frameArgs[2])
	end
	local args, err = utilsArg.parse(frameArgs, p.Templates.Script)
	local errCategories = err and utilsMarkup.categories(err.categories) or ""
	return p.transliterate(args) .. errCategories
end

function p.transliterate(args)
	local scriptId = args.scriptId
	local chars = args.text
	local size = args.size
	
	local script = data[scriptId or ""]
	if not script then
		return ""
	end
	local fileFormat = script.fileFormat
	local defaultSize = script.defaultSize and "x"..script.defaultSize.."px" or nil
	local charset = utilsTable.invert(script.charset)
	local spaceBetween = script.spaceBetween
	
	local result = ""
	local isMultiline = false
	for i, char in ipairs(chars or {}) do
		if charset[char] then
			local filename = string.format(fileFormat, char, char)
			local file = utilsMarkup.file(filename, {
				size = size or defaultSize,
				caption = char,
				link = "",
			})
			local span = mw.html.create("span")
				:attr({
					class = "tooltip",
					title = char,
				})
				:wikitext(file)
			result = result .. tostring(span)
		elseif char ~= "\n" or i < #chars then -- print every other character as-is. Ignore trailing newlines
			result = result .. char
		end
		if char == "\n" and i < #chars then
			isMultiline = true
		end
		-- This is not a great solution for spacing. 
		-- Probably what would be ideal is to upload a space file as a part of each character set.
		-- This would allow the spacing to be tailored apprioriately to each script and would also scale better at different sizes.
		if spaceBetween then
			result = result .. "&thinsp;"
		end
	end
	if isMultiline then
		result = mw.getCurrentFrame():extensionTag("poem", result)
	end
	return result
end

function p.Data(frame)
	local scriptIds = utilsTable.keys(data)
	table.sort(scriptIds)
	
	local result = ""
	for _, scriptId in ipairs(scriptIds) do
		result = result .. utilsMarkup.heading(3, utilsMarkup.code(scriptId))
		local html = mw.html.create("div")
		html:css({
			["display"] = "flex",
			["flex-wrap"] = "wrap",
			["align-items"] = "flex-end",
		})
		for _, char in ipairs(data[scriptId].charset) do
			local script = data[scriptId]
			local filename = string.format(script.fileFormat, char, char)
			local file = utilsMarkup.file(filename, {
				size = script.defaultSize and "x"..script.defaultSize.."px"
			})
			html:tag("div")
				:css({
					["text-align"] = "center",
					["flex"] = "1 1 40px",
					["margin-top"] = "20px",
				})
				:wikitext(file .. "\n----\n" .. mw.text.nowiki(char))
				:done()
		end
		result = result .. tostring(html) .."\n\n"
	end
	return result
end

p.Schemas = {
	Data = {
		type = "map",
		required = true,
		desc = "Key value pairs defining in-game scripts, where the key corresponds to the <code>scriptId</code> parameter of [[Template:Script]].",
		keyPlaceholder = "scriptId",
		keys = {
			type = "string",
		},
		values = {
			type = "record",
			properties = {
				{
					name = "fileFormat",
					type = "string",
					required = true,
					desc = "The file format for the script characters.",
				},
				{
					name = "defaultSize",
					type = "number",
					desc = "If unspecified, the default size will be the size of the character's file.",
				},
				{
					name = "charset",
					type = "array",
					required = true,
					items = { type = "string" },
					desc = "An array of all the source characters defined for the script.",
				},
				{
					name = "spaceBetween",
					type = "boolean",
					desc = "When enabled, the amount of space between characters is increased."
				},
			},
		},
	},
}

p.Templates = {
	Script = {
		purpose = "Transliterates in-game scripts from their source language (Japanese or English).",
		format = "inline",
		params = {
			[1] = {
				name = "scriptId",
				type = "string",
				required = true,
				enum = utilsTable.merge({}, utilsTable.keys(data), { 
					reference = "[[Module:Script/Data]]" 
				}),
				desc = "<p>Identifier for the language script.</p><p>The various forms of Hylian are named after the first game in which they were released.</p>",
			},
			[2] = {
				name = "text",
				type = "string",
				required = true,
				enumDependsOn = "scriptId",
				enum = function(scriptId)
					local chars = utilsTable.concat(data[scriptId] and data[scriptId].charset or {}, " ", " ", "", "\n", "\t")
					return utilsTable.merge({}, chars, {
						reference = "[[Module:Script/Data]]" 
					})
				end,
				split = "",
				desc = "<p>The text to transliterate into an in-game language.</p><p>Only characters which are defined for the script are allowed. Whitespace characters are also allowed and are preserved.</p>",
			},
			size = {
				type = "string",
				canOmit = true,
				desc = "Size of the characters in px. Defaults to the script's <code>defaultSize</code> if defined at [[Module:Script/Data]]. Otherwise, defaults to the size of the character images.",
			},
		},
		examples = {
			{"Gerudo", "The quick brown fox jumps over the lazy dog"},
			{"Hylian OoT", [[

タチツテトナニヌネニノハヒフヘホ
ヘホタチツテトナニヌネノハヒフ
]]},
			{"Hylian OoT 2", [[

タチツテトナニヌネニノハヒフヘホ
ヘホタチツテトナニヌネノハヒフ
]]},
			{"Hylian TWW", "ァィゥェォッャュョ 。、「」!?1234567890"},
			{"Hylian TP", "The quick brown fox jumps over the lazy dog"},
			{"Hylian SS", "The quick brown fox jumps over the lazy dog"},
			{"Hylian ALBW", "The quick brown fox jumps over the lazy dog"},
			{"Lorulean", "The quick brown fox jumps over the lazy dog"},
			{"Sheikah", "The quick brown fox 1234567890"},
			{
				desc = "Non-default sizes",
				args = {"Hylian ALBW", size = "x50px", "Big Font"},
			},
			{"Hylian OoT 2", size = "x50px", "ヒツク フオント"},
			{
				desc = "Invalid characters are ignored and simply passed on as-is.",
				args = {"Hylian TWW", "This won't work because TWW Hylian is based on katakana."},
			},
			{
				args = {"Hylian ALBW", "formatting<br>won't work '''either'''"},
			},
			{
				desc = "<code>scriptId</code> is required",
				args = {},
			},
			{
				args = {""},
			},
			{
				args = {"invalid ID", "foo"},
			},
			{
				desc = "<code>text</code> can be empty, but it cannot be undefined.",
				args = {"Hylian ALBW", ""},
			},
			{
				args = {"Hylian ALBW"},
			},
		},
	},
}

return p
Advertisement