Module:Nomenclature

local p = {} local h = {}

local cargo = mw.ext.cargocs local expgame = require('Module:Exp Game') local tab2 = require('Module:Tab2') local File = require("Module:File") local Franchise = require("Module:Franchise") local Term = require('Module:Term') local translation = require('Module:Translation') local utilsError = require('Module:UtilsError') local utilsLanguage = require('Module:UtilsLanguage') local utilsMarkup = require("Module:UtilsMarkup") local utilsString = require("Module:UtilsString") local utilsTable = require('Module:UtilsTable')

-- temporary to remove function p.HasTranslationsStored(frame) local term = frame.args["term"] if utilsString.isEmpty(term) then term = mw.title.getCurrentTitle.subpageText end if #translation.fetchTranslations(term) > 0 then return true else return false end end

-- For creating nomenclature tables function p.Main( frame ) local term = frame.args["term"] if utilsString.isEmpty(term) then term = mw.title.getCurrentTitle.subpageText end local cargoData = translation.fetchTranslations(term) local displayGames = false local skipMeanings = true for key, row in ipairs(cargoData) do		if cargoData[1]["game"] ~= row["game"] or Franchise.isRemake(row.game) or Franchise.hasRemakes(row.game) then displayGames = true end if not utilsString.isEmpty(row["meaning"]) then skipMeanings = false end end local resultTable = h.CreateTable(skipMeanings) resultTable = h.CreateRows(resultTable, cargoData, skipMeanings, displayGames) resultTable:node(mw.html.create("tr"):node(mw.html.create("th"):attr("colspan", "4"):wikitext(" This table was generated using translation pages. To request an addition, please contact a staff member with a reference. "))) return resultTable end

--Create an empty table with headers function h.CreateTable(skipMeanings) --Table structure local resultTable = mw.html.create("table") :addClass("wikitable"):done --Global header local headerRow = mw.html.create("tr"):done local headerContent = mw.html.create("th") :wikitext(" Names in Other Regions ") :attr("colspan", "4") :css{ ["font-size"] = "110%", }:done headerRow:node(headerContent) resultTable:node(headerRow) --Individual headers --Language headerRow = mw.html.create("tr"):done headerContent = mw.html.create("th") :wikitext("Language") :attr("colspan", "2"):done headerRow:node(headerContent) --Name headerContent = mw.html.create("th") :wikitext("Name"):done headerRow:node(headerContent) --Meaning if not skipMeanings then headerContent = mw.html.create("th") :wikitext("Meaning"):done headerRow:node(headerContent) end resultTable:node(headerRow) return resultTable end

function h.CreateRows(output, cargoData, skipMeanings, displayGames) h.SortTranslations(cargoData) for _, row in ipairs(cargoData) do		if not row.skip and row.translation ~= "N/A" then h.ProcessRow(output, cargoData, row, skipMeanings, displayGames) end end return output end

function h.SortTranslations(translations) local lookupLang = utilsTable.invert(utilsLanguage.enum) local lookupGame = utilsTable.invert(Franchise.enumGames) table.sort(translations, function (a,b)			if (lookupLang[a.language] or 0) == (lookupLang[b.language] or 0) then				return (lookupGame[a.game] or 0) < (lookupGame[b.game] or 0)			else				return (lookupLang[a.language] or 0) < (lookupLang[b.language] or 0)			end		end	) end

function h.ProcessRow(output, cargoData, row, skipMeanings, displayGames) local meanings = h.GetMeanings(cargoData, row) local langText, flag = utilsLanguage.printLanguage(row.language) local tr = output:tag('tr') :tag("td") :addClass("nomenclature-flag") :wikitext(flag) :done :tag("td") :wikitext(langText) :done local sameNameAsEnglish = row.translation == row.term h.PrintNames(tr, cargoData, row, displayGames, {		-- name and meaning get merged into one column if the name is the same as the English name		-- See The Legend of Zelda: Tears of the Kingdom, for example		colspan = sameNameAsEnglish and 2 or nil,	}) h.MarkRowsToSkip(cargoData, row) if not skipMeanings and not sameNameAsEnglish then h.PrintMeanings(tr, meanings) end end

function h.GetMeanings(cargoData, row) local ret = { row.meaning } for _, row2 in ipairs(cargoData) do		if h.SameLangDifTranslations(row, row2) then ret[#ret+1] = row2.meaning end end return ret end

function h.PrintNames(tr, cargoData, row, displayGames, options) local td = tr:tag('td') :wikitext(table.concat(h.GetNamesAndTheirGames(cargoData, row, displayGames), ' ')) if options.colspan then td:attr("colspan", options.colspan) end end

function h.GetNamesAndTheirGames(cargoData, row, displayGames) local ret = { h.GetOneNameAndGames(cargoData, row, displayGames) } for _, row2 in ipairs(cargoData) do		if h.SameLangDifTranslations(row, row2) then games = h.GamesWithSameTranslation(row2, cargoData) ret[#ret+1] = h.GetOneNameAndGames(cargoData, row2, displayGames) end end return ret end

function h.GetOneNameAndGames(cargoData, row, displayGames) local games = h.GamesWithSameTranslation(row, cargoData) local result = row.translation if displayGames == true then result = result .. " " .. expgame.printGames(games) end local refs = h.RefsWithSameTranslation(row, cargoData) for key, ref in ipairs(refs) do		if not utilsString.isEmpty(ref) then result = result .. mw.getCurrentFrame:extensionTag("ref", ref) end end return result end

function h.GamesWithSameTranslation(row, cargoData) local ret = {} for _, row2 in ipairs(cargoData) do		if h.SameLangSameTranslation(row, row2) then ret[#ret+1] = row2.game end end return ret end

function h.RefsWithSameTranslation(row, cargoData) local ret = {} for _, row2 in ipairs(cargoData) do		if h.SameLangSameTranslation(row, row2) then ret[#ret+1] = row2.reference end end return ret end

function h.SameLangSameTranslation(row1, row2) return row1.language == row2.language and row1.translation == row2.translation end

function h.SameLangDifTranslations(row1, row2) return row1.language == row2.language and row1.translation ~= row2.translation end

function h.SameLang(row1, row2) return row1.language == row2.language end

function h.PrintMeanings(tr, meanings) local meaningsDisplays = h.ProcessMeanings(meanings) td = tr:tag('td') :wikitext(table.concat(meaningsDisplays, ' ')) end

function h.MarkRowsToSkip(cargoData, row) for _, row2 in ipairs(cargoData) do		if h.SameLang(row, row2) then row2.skip = true end end end

function h.ProcessMeanings(meanings) local ret = {} for k, v in pairs(meanings) do		if utilsString.isEmpty(v) then ret[#ret+1] = ' ' else ret[#ret+1] = v		end end return ret end

-- TRANSLATION PAGES function p._CreateTranslationTables(frame) local args = frame:getParent.args local tabs = {} local index = 0 while true do		index = index + 1 if utilsString.isEmpty(args["tab" .. index]) then break else table.insert(tabs, {tabName = args["tab" .. index], tabContent = args["subjects"]}) end end return p.CreateTranslationTables(args["game"], args["filetype"], args["header"], tabs, args["subjects"]) end

function p.CreateTranslationTables(game, filetype, header, tabs, subjects) subjects = utilsString.split(subjects) if filetype == "Screenshot" then filetype = "" end if utilsString.isEmpty(header) then header = "Subject" end for key, tab in ipairs(tabs) do		local languages = utilsString.split(tab["tabName"], '%s*,%s*') --Creating tab contents local headerRow = mw.html.create("tr") :node(mw.html.create("th"):wikitext(header)):done for key2, language in ipairs(languages) do			local langText, flag = utilsLanguage.printLanguage(language) headerRow:node(				mw.html.create("th")					:wikitext(flag .. " " .. langText)					:css("width", 100 / (#languages + 1) .. "%")				)				:done end local content = mw.html.create("table") :addClass("wikitable") :css("width", "100%") :node(headerRow) --Creating rows local errs = {} local translations = translation.fetchTranslationsByGame(game, subjects) for key2, subject in ipairs(subjects) do			local term, err = Term.fetchTerm(subject, game) if not term then utilsError.warn(string.format("Page %s does not store any terms.", utilsMarkup.code(subject))) errs = utilsTable.concat(errs, err) else -- Assume that by default, the file is named according to the term. If term+game cannot uniquely identify the subject, assume the file name matches the page name. -- Example A: Given subject Wood (Character) and game ST, the filename is inferred to be "ST Wood Model.png". In ST, the term "Wood" uniquely identifies the subject. -- Example B: Given subject Link (Goron) and game MM, the file name is inferred to be "MM Link (Goron) Model.png. In MM, the term 'Link' refers to two characters and does not uniquely identify the subject.				local fileIdentifier = term				if utilsString.endsWith(subject, ")") and #Term.fetchSubjects(term, game) > 1 then					fileIdentifier = subject 				end				local img = File.gameImage(game, fileIdentifier, filetype, {					size = "150x150px",					checkExists = false, -- checking for file existence has too much of a time cost for translation pages				})				term = Term.printTerm({					page = subject,					game = game,					link = "link",				})				local row = h.printRow(img, term, languages, translations[subject] or {})				content:node(row)			end		end		tab["tabContent"] = tostring(content) .. " Return to top " .. utilsMarkup.categories(errs)		-- Formatting tab names		for key2, language in ipairs(languages) do			languages[key2] = utilsLanguage.printLanguage(language, true) end languages = utilsTable.unique(languages) tab["tabName"] = table.concat(languages, ", ") end if #tabs == 1 then return tabs[1]["tabContent"] else return tab2.Main(tabs, 1, "top", #tabs, "", "", "", "left") end end

function h.printRow(img, term, languages, translations) local row = mw.html.create("tr") :node(mw.html.create("td")			:addClass("centered")			:wikitext(img .. " " .. utilsMarkup.bold(term))) for _, language in ipairs(languages) do		outputs = {} for _, translation in ipairs(translations) do			if translation["language"] == language then table.insert(outputs, translation["translation"]) end end

local cell = mw.html.create("td"):addClass("centered") if outputs[1] == "N/A" then cell:wikitext("—") else cell:wikitext(table.concat(outputs, " ")) end row:node(cell):done end return row end

return p