Anonymous

Module:Nomenclature: Difference between revisions

From Zelda Wiki, the Zelda encyclopedia
no edit summary
No edit summary
No edit summary
Line 2: Line 2:
local h = {}
local h = {}


local Franchise = require('Module:Franchise')
local Franchise = require("Module:Franchise")
local Language = require('Module:Language')
local Language = require("Module:Language")
local translation = require('Module:Translation')
local Term = require("Module:Term")
local utilsString = require("Module:UtilsString")
local utilsCargo = require("Module:UtilsCargo")
local utilsTable = require('Module:UtilsTable')
local utilsTable = require('Module:UtilsTable')
local DISCORD_URL = require("Module:Constants/url/discord")


-- temporary to remove {{Names}}
-- temporary to remove {{Names}}
function p.HasTranslationsStored(frame)
function p.HasTranslationsStored(frame)
local term = frame.args["term"]
local term = frame.args["term"]
if utilsString.isEmpty(term) then
if term == nil or term == "" then
term = mw.title.getCurrentTitle().subpageText
term = mw.title.getCurrentTitle().subpageText
end
end
if #translation.fetchTranslations(term) > 0 then
if #h.fetchTranslations(term) > 0 then
return true
return true
else
else
Line 22: Line 24:


-- For creating nomenclature tables
-- For creating nomenclature tables
function p.Main( frame )
function p.Main(frame)
local term = frame.args["term"]
local subject = frame.args["term"]
if utilsString.isEmpty(term) then
if subject == nil or subject == "" then
term = mw.title.getCurrentTitle().subpageText
subject = mw.title.getCurrentTitle().subpageText
end
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("<small>This table was generated using [[Data:Translations|translation pages]].<br>To request an addition, please <span class='plainlinks'>[https://discord.gg/eJnnvYb contact]</span> a [[Zelda Wiki:Staff|staff member]] with a [[Guidelines:References|reference]].</small>")))
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 translations = h.fetchTranslations(subject)
local headerRow = mw.html.create("tr"):done()
local translations, hasMeanings, displayGames = h.formatData(translations)
local headerContent = mw.html.create("th")
local nomenclatureTable = h.printNomenclatureTable(translations, hasMeanings, displayGames)
:wikitext("[[File:TMC Forest Minish Artwork.png|20px|link=]] Names in Other Regions [[File:TMC Jabber Nut Sprite.png|link=]]")
:attr("colspan", "4")
:css{
["font-size"] = "110%",
}:done()
headerRow:node(headerContent)
return nomenclatureTable
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
end


function h.CreateRows(output, cargoData, skipMeanings, displayGames)
function h.fetchTranslations(page)
h.SortTranslations(cargoData)
local whereClause = utilsCargo.allOf({
for _, row in ipairs(cargoData) do
    subject = page
if not row.skip and row.translation ~= "N/A" then
})
h.ProcessRow(output, cargoData, row, skipMeanings, displayGames)
-- Fetch translations of synonyms
end
local term = Term.fetchTerm(page)
if term and not string.find(page, "%)$") then -- without this ) check, Wood (Character) would also fetch data for BotW Wood
term = string.gsub(term, "#", "") -- terms with # in them are stored in a version of the page without the #, because MediaWiki. Also Cargo doesn't allow queries with # in them.
whereClause = whereClause .. " OR " ..utilsCargo.allOf({
    term = term
}, "subject NOT LIKE '%)'") -- without this, requesting "Wood" would also fetch data for Wood (Character)
end
end
local translations = utilsCargo.query("Translations2", "game, term, lang, translation, meaning, ref", {
where = whereClause
})
return output
return translations
end
end


function h.SortTranslations(translations)
function h.formatData(translations)
local lookupLang = utilsTable.invert(Language.enum())
local hasMeanings = utilsTable.find(translations, function(translation)
local lookupGame = utilsTable.invert(Franchise.enumGames())
return translation.meaning == nil and translation.meaning ~= "" and translation.term ~= translation.translation
table.sort(translations, function (a,b)
end)
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 lect = Language.getLect(row.language)
local flags
if #lect.flags == 1 then
flags = lect.flags[1]
else -- multi country (multi-flag) region like Taiwan+Hong Kong+Macau
flags = utilsTable.map(lect.flags, function(flag)
return "<div>"..flag.."</div>" end
)
flags = table.concat(flags, "")
end
local tr = output:tag('tr')
:attr("id", "nomenclature-"..row.language)
:tag("td")
:tag("div")
:addClass("nomenclature__flag-cell")
:wikitext(flags)
:done()
:done()
:tag("td")
:wikitext(lect.abbr)
:done()
local sameNameAsEnglish = h.PrintNames(tr, cargoData, row, displayGames)
h.MarkRowsToSkip(cargoData, row)
if not skipMeanings and not sameNameAsEnglish then
h.PrintMeanings(tr, meanings)
end
end
-- Determine whether to display Exp Game
 
local seenGames = {}
function h.GetMeanings(cargoData, row)
local gameCount = 0
local ret = { row.meaning }
local hasRemakes = false
for _, row2 in ipairs(cargoData) do
for i, translation in ipairs(translations) do
if h.SameLangDifTranslations(row, row2) then
local game = translation.game
ret[#ret+1] = row2.meaning
if not seenGames[game] then
gameCount = gameCount + 1
seenGames[game] = true
end
end
end
if Franchise.isRemake(game) or Franchise.hasRemakes(game) then
return ret
hasRemakes = true
end
 
function 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
local names, sameNameAsEnglish = h.GetNamesAndTheirGames(cargoData, row, displayGames)
local td = tr:tag('td')
:wikitext(table.concat(names, '<br>'))
if sameNameAsEnglish then
td:attr("colspan", 2)
end
return sameNameAsEnglish
end
 
function h.GetNamesAndTheirGames(cargoData, row, displayGames)
local sameNameAsEnglish = true
local nameAndGames, name = h.GetOneNameAndGames(cargoData, row, displayGames)
local ret = {nameAndGames}
if name ~= row.term then
sameNameAsEnglish = false
end
for _, row2 in ipairs(cargoData) do
if h.SameLangDifTranslations(row, row2) then
games = h.GamesWithSameTranslation(row2, cargoData)
local nameAndGames, name = h.GetOneNameAndGames(cargoData, row2, displayGames)
ret[#ret+1] = nameAndGames
if name ~= row.term then
sameNameAsEnglish = false
end
end
end
end
end
return ret, sameNameAsEnglish
local displayGames = gameCount > 1 or hasRemakes
end
 
-- Group translations by language and then by name
function h.GetOneNameAndGames(cargoData, row, displayGames)
local gameOrderLookup = utilsTable.invert(Franchise.enum())
local games = h.GamesWithSameTranslation(row, cargoData)
translations = utilsTable.sortBy(translations, function(translation)
local result = row.translation
return gameOrderLookup[translation.game] or 1000
if displayGames == true then
end)
result = result .. " " .. mw.getCurrentFrame():expandTemplate({
translations = utilsTable.groupBy(translations, "lang")
title = "Exp Game",
translations = utilsTable.mapValues(translations, utilsTable._groupBy("translation"))
args = {table.concat(games, ", ")}
})
end
local refs = h.RefsWithSameTranslation(row, cargoData)
-- Creates a list of unique translations grouped by language
for key, ref in ipairs(refs) do
-- For each unique translation, lists which games have that translation, assigns a meaning to it, and creates the refs
if not utilsString.isEmpty(ref) then
-- If multiple games have different meanings for the same translation, we use the latest game
result = result .. h.printRef(ref)
local hasMeanings = false
local translationLists = {}
for lang, langTranslations in pairs(translations) do
local translationList = {}
for translation, translationGames in pairs(langTranslations) do
local translationListItem = {
translation = translation,
games = {},
meaning = "&nbsp;",
term = translationGames[1].term,
refs = "",
}
for i, translationGame in ipairs(translationGames) do
local meaning = translationGame.meaning
if meaning ~= nil and meaning ~= "" then
translationListItem.meaning = meaning
hasMeanings = true
end
table.insert(translationListItem.games, translationGame.game)
translationListItem.refs = translationListItem.refs..h.printRef(translationGame.ref)
end
table.insert(translationList, translationListItem)
end
end
-- Sort translations by their earliest appearance
translationList = utilsTable.sortBy(translationList, function(translation)
return gameOrderLookup[translation.games[1]]
end)
translationLists[lang] = translationList
end
end
return result, row.translation
return translationLists, hasMeanings, displayGames
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
end


Line 227: Line 124:
local seenRefs = {}
local seenRefs = {}
function h.printRef(citation)
function h.printRef(citation)
if citation == nil or citation == "" then
return ""
end
citation = citation
local refIndex = seenRefs[citation]
local refIndex = seenRefs[citation]
Line 240: Line 141:
end
end
return mw.getCurrentFrame():extensionTag({
local frame = mw.getCurrentFrame()
return frame:extensionTag({
name = "ref",
name = "ref",
args = { name = refNamePrefix..refIndex },
args = { name = refNamePrefix..refIndex },
content = refContent
content = refContent,
})
})
end
end


function h.SameLangSameTranslation(row1, row2)
function h.printNomenclatureTable(translationsByLang, hasMeanings, displayGames)
return row1.language == row2.language and row1.translation == row2.translation
local html = mw.html.create("table")
:addClass("wikitable")
:tag("tr")
:tag("th")
:addClass("nomenclature__header")
:attr("colspan", hasMeanings and 3 or 2)
:wikitext("[[File:TMC Forest Minish Artwork.png|20px|link=]] Names in Other Regions [[File:TMC Jabber Nut Sprite.png|link=]]")
:done()
:done()
:done()
local columns = html:tag("tr")
columns:tag("th"):wikitext("Language")
columns:tag("th"):wikitext("Names")
if hasMeanings then
columns:tag("th"):wikitext("Meanings")
end
for i, lang in ipairs(Language.enum()) do
local translations = translationsByLang[lang]
if translations then
h.addRow(html, hasMeanings, displayGames, lang, translations)
end
end
local footerText = mw.getCurrentFrame():preprocess("<small>This table was generated using [[Data:Translations|translation pages]].<br>To request an addition, please {{Discord|contact|plainlink= true}} a [[Zelda Wiki:Staff|staff member]] with a [[Guidelines:References|reference]].</small>")
html:tag("tr")
:tag("th")
:attr("colspan", "3")
:wikitext(footerText)
return tostring(html:allDone())
end
end


function h.SameLangDifTranslations(row1, row2)
function h.addRow(html, hasMeanings, displayGames, lang, translations)
return row1.language == row2.language and row1.translation ~= row2.translation
local row = html:tag("tr")
end
local langCell = mw.html.create("td"):addClass("nomenclature__cell nomenclature__cell--language")
local nameCell = mw.html.create("td"):addClass("nomenclature__cell nomenclature__cell--name")
local meaningCell = mw.html.create("td"):addClass("nomenclature__cell nomenclature__cell--meanings")
local lect = Language.getLect(lang)
langCell:tag("div")
:addClass("nomenclature__language")
:tag("div")
:addClass("nomenclature__language-flags")
:wikitext(unpack(lect.flags))
:done()
:tag("div")
:addClass("nomenclature__language-name")
:wikitext(lect.abbr)
:done()
:done()
local names = {}
local meanings = {}
for i, translation in ipairs(translations) do
names[i] = h.printTranslationName(translation, displayGames)..translation.refs
meanings[i] = translation.meaning
end
names = #names == 1 and names[1] or h.list(names)
meanings = #meanings == 1 and meanings[1] or h.list(meanings)
nameCell:wikitext(names)
meaningCell:wikitext(meanings)
-- When the foreign name is the exact same as the NoA name (see TotK page for example)
if #translations == 1 and translations[1].translation == translations[1].term then
nameCell:attr("colspan", 2)
meaningCell = nil
end


function h.SameLang(row1, row2)
row:node(langCell)
return row1.language == row2.language
row:node(nameCell)
if hasMeanings and meaningCell then
row:node(meaningCell)
end
end
end


function h.PrintMeanings(tr, meanings)
function h.printTranslationName(translationData, displayGames)
local meaningsDisplays = h.ProcessMeanings(meanings)
local result = translationData.translation
td = tr:tag('td')
if displayGames then
:wikitext(table.concat(meaningsDisplays, '<br>'))
result = result .. " " .. mw.getCurrentFrame():expandTemplate({
end
title = "Exp Game",
 
args = {table.concat(translationData.games, ", ")}
function h.MarkRowsToSkip(cargoData, row)
})
for _, row2 in ipairs(cargoData) do
if h.SameLang(row, row2) then
row2.skip = true
end
end
end
return result
end
end


function h.ProcessMeanings(meanings)
function h.list(items)
local ret = {}
local list = mw.html.create("ul"):addClass("plainlist")
for k, v in pairs(meanings) do
for i, item in ipairs(items) do
if utilsString.isEmpty(v) then
list:tag("li"):wikitext(item)
ret[#ret+1] = '&nbsp;'
else
ret[#ret+1] = v
end
end
end
return ret
return tostring(list)
end
end


return p
return p