Module:Script

local p = {} local h = {} local data = require("Module:Script/Data")

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

local CATEGORY_INVALID_ARGS = require("Module:Constants/category/invalidArgs")

function h.warn(msg, ...) local utilsError = require("Module:UtilsError") msg = string.format(msg, ...) utilsError.warn(msg) end

function p.Main(frame) local frameArgs = utilsTable.clone(frame:getParent.args) local args, err = utilsArg.parse(frameArgs, p.Templates.Script) local categories = err and err.categoryText or "" if err and err.args.scriptId or args.text == nil then return "", categories end local result = p.transliterate(args.scriptId, args.text, {		size = args.size	}) return result, categories end

function p.enum local enum = utilsTable.keys(data) table.sort(enum) enum.reference = "Module:Script/Data" return enum end

function p.transliterate(scriptId, text, options) local options = options or {} local size = options.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 text, brTags = h.liftBrTags(text) text = string.upper(text or "") local chars = utilsString.split(text, "") local invalidChars = {} local result = "" local isMultiline = false for i, char in ipairs(chars or {}) do		if brTags[i] then result = result.." " end 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" then result = result .. char isMultiline = true elseif char == "\n" and i == #chars then -- ignore trailing newlines elseif utilsString.isBlank(char) then result = result .. char else table.insert(invalidChars, " ") 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 if #invalidChars > 0 then h.warn("Invalid characters for script : %s", scriptId, mw.text.listToText(invalidChars)) result = 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

function h.liftBrTags(text) local brTags = {} local startIndex repeat startIndex = mw.ustring.find(text, "") if startIndex then text = string.gsub(text, "", "", 1) brTags[startIndex] = true end until not startIndex return text, brTags end

function p.Schemas(frame) return { Data = { type = "map", required = true, desc = "Key value pairs defining in-game scripts, where the key corresponds to the  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." },				},			},		},	} end

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 = p.enum, desc = " Identifier for the language script. The various forms of Hylian are named after the first game in which they were released. ", },			[2] = {				name = "text", type = "string", required = true, desc = " The text to transliterate into an in-game language. Only characters which are defined for the script are allowed. Whitespace characters are also allowed and are preserved. ", },			size = { type = "string", canOmit = true, desc = "Size of the characters in px. Defaults to the script's  if defined at Module:Script/Data. Otherwise, defaults to the size of the character images.", },		},		examples = { {				desc = "Whitespace is preserved.", args = 	{"Hylian OoT", [[

タチツテトナニヌネニノハヒフヘホ ヘホタチツテトナニヌネノハヒフ ]]},			},			{				desc = " and   tags are allowed.", args = {"Hylian OoT", "ムユサツマムユ イコサツマムユリ イコサツマム"}, },			{				desc = "Using the  parameter", 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."}, },			{				desc = "Aside from tags, markup is not valid input.", args = {"Hylian ALBW", "Bold italics"}, },			{				desc = " is required", args = {}, },			{				args = {""}, },			{				args = {"invalid ID", "foo"}, },			{				desc = " can be empty, but it cannot be undefined.", args = {"Hylian ALBW", ""}, },			{				args = {"Hylian ALBW"}, },		},	}, }

return p