模块:GameText
This module is used to display text used in Terraria, exactly as in-game. It provides the functionality of the {{gameText}} template and can also be used from within other modules.
Usage
Wikitext
The module can be called from wikitext with the functions listed below.
get
{{#invoke:GameText| get | lang = <language> }}
Displays the string associated with the given key. If the given key refers to a group of strings (e.g. WorldGeneration), then it displays all strings in that group separated by the character ₪.
This function is generally only intended to be called from {{gameText}}. The parameters passed in the transclusion of that template are recognized and handled by this function. See the template documentation for details about the parameters.
getRaw
{{#invoke:GameText| getRaw | <key> | prefix = <output prefix> | postfix = <output postfix> | <placeholder replacements> | lang = <language> }}
Displays the string exactly as it is defined in the source language JSON file. The get function wraps its output in <span class="gameText"> and replaces linebreaks (\n) with HTML linebreaks (<br/>) for a more intuitive output. This function does not do that.
getSection
{{#invoke:GameText| getSection | <key> | lang = <language> }}
Returns all keys and their strings that are in the group of the given key (e.g. WorldGeneration) as an array from Extension:ArrayFunctions. This function is generally only intended to be called from {{gameText/section}}.
| Code | Result |
|---|---|
{{#af_print:{{#invoke:GameText|getSection|WorldGeneration}}}}
|
|
getSectionList
{{#invoke:GameText| getSectionList }}
Returns all top-level keys from the database as an array from Extension:ArrayFunctions. This function is generally only intended to be called from {{gameText/sectionList}}.
| Code | Result |
|---|---|
{{#af_print:{{#invoke:GameText|getSectionList}}}}
|
|
listAll
{{#invoke:GameText| listAll | <key> | lang = <language> }}
Displays all keys and their strings that are in the group of the given key (e.g. WorldGeneration), separated by the character ¦. The separator between each key and string is ₪. If no key is provided, then merely lists all keys in the entire database.
| Code | Result |
|---|---|
{{#invoke:GameText|listAll|WorldGeneration}}
|
OceanSand₪Generating ocean sand¦WavyCaves₪Generating wavy caves |
listKeys
{{#invoke:GameText| listKeys | <key> | lang = <language> }}
Similar to the listAll function, except that only the keys are displayed in any case, never the strings.
| Code | Result |
|---|---|
{{#invoke:GameText|listKeys|WorldGeneration}}
|
OceanSand¦WavyCaves |
{{#invoke:GameText|listKeys}}
|
LucyTheAxe_ChoppedCactus¦CreditsRollCategory_Sound¦BestiaryGirlSpecialText¦BunnyNames_Lop¦WorkshopTags¦GolferQuestsChatterApprentice¦CatNames_Black¦ItemTooltip¦BunnyNames_White¦StylistChatter¦MechanicSpecialText¦RandomWorldName_Location¦CreditsRollCategory_SpecialThanksto¦ItemVariant¦TownNPCMood_DD2Bartender¦DogNames_Corgi¦SantaSpecialText¦CLI¦ItemVariantCondition¦CatNames_Siamese¦PainterNames¦Social¦BunnyChatter¦AnglerSpecialText¦EmojiCommand¦TownNPCMood_Wizard¦SlimeNames_Blue¦CreditsRollCategory_Marketing¦DungeonDefenders2¦TownNPCMood_BestiaryGirlTransformed¦RandomWorldName_Composition¦TownNPCMood_BestiaryGirl¦GameUI¦TownNPCMood_Painter¦TownNPCMood_Truffle¦TownNPCMood_Golfer¦CatNames_RussianBlue¦SlimeRainbowChatter¦MapObject¦ClothierNames¦UI¦DryadSpecialText¦CreditsRollCategory_Creator¦TownNPCMood_Steampunker¦BartenderHelpText¦TownNPCMood_Pirate¦TownNPCMood_Guide¦TownNPCMood_Mechanic¦SpecialWorldName¦LoadingTips_GamePad¦SlimeCopperChatter¦TownNPCMood_Princess¦LegacyTooltip¦ArmsDealerNames¦DryadNames¦GuideNames¦LucyTheAxe_Storage¦ChatCommandDescription¦Achievements¦TownNPCMood_Dryad¦Prefix¦StardewTalk¦SlimeRedChatter¦CreativePowers¦LucyTheAxe_ChoppedTree¦TownNPCMood_Demolitionist¦Controls¦ProjectileName¦LegacyMenu¦BartenderSpecialText¦TownNPCMood_Stylist¦DogChatter¦TownNPCMood_PartyGirl¦AnglerNames¦SlimeNames_Yellow¦LegacyWorldGen¦TownNPCMood_Nurse¦TravellingMerchantSpecialText¦BuffDescription¦TownNPCMood_TaxCollector¦GolferQuestsChatterMaster¦GuideChatter¦PirateChatter¦NurseNames¦Currency¦GolferQuestsChatterBeginner¦StylistSpecialText¦GolferQuestsChatterJourneyman¦SkeletonMerchantSpecialText¦Enemies¦RichPresence¦SlimePurpleChatter¦DogNames_Beagle¦DeathTextGeneric¦CatNames_OrangeTabby¦LegacyInterface¦Language¦TownNPCMood¦LucyTheAxe_GemTree¦Bestiary_Events¦TownNPCMood_Merchant¦DogNames_Dalmation¦Net¦PrincessSpecialText¦ChatCommand¦GolferSpecialText¦Bestiary_Biomes¦Friends¦TownNPCHousingFailureReasons¦BestiaryGirlNames¦WitchDoctorSpecialText¦DeathSource¦RandomWorldName_Adjective¦PainterSpecialText¦CreditsRollCategory_EndingNotes¦Key¦BuffName¦PartyGirlSpecialText¦MerchantNames¦TaxCollectorNames¦DogNames_PitBull¦CreditsRollCategory_BusinessDevelopment¦Bestiary_BiomeText¦CreditsRollCategory_PublicRelations¦CreditsRollCategory_Programming¦AnglerQuestChatter¦LucyTheAxe_Idle¦LegacyChestType2¦BartenderNames¦CatNames_Silver¦SteampunkerSpecialText¦TruffleSpecialText¦NPCName¦DemolitionistSpecialText¦SlimeBlueChatter¦WizardSpecialText¦GoblinTinkererSpecialText¦ClothierSpecialText¦CreditsRollCategory_Webmaster¦SlimeNames_Rainbow¦MerchantSpecialText¦TownNPCMood_Cyborg¦SlimeYellowChatter¦SkeletonMerchantNames¦MechanicChatter¦NurseSpecialText¦GuideSpecialText¦GoblinTinkererChatter¦AnglerChatter¦CyborgChatter¦CreditsRollCategory_Designer¦TownNPCMood_Angler¦SteampunkerNames¦BestiaryInfo¦WizardNames¦AssetRejections¦GuideHelpText¦CommonItemTooltip¦SlimeNames_Purple¦LegacyMultiplayer¦TownNPCMood_Clothier¦TownNPCMood_DyeTrader¦SlimeGreenChatter¦RandomWorldName_Noun¦NurseChatter¦LegacyChestType¦CreditsRollCategory_Graphics¦PrincessChatter¦BestiaryGirlLycantropeChatter¦CaptureBiomeChoice¦BestiaryGirlChatter¦EmojiName¦BartenderChatter¦DyeTraderSpecialText¦LucyTheAxe_PickedUp¦Game¦SlimeNames_Copper¦SlimeNames_Red¦GuideHelpTextSpecific¦SlimeNames_Old¦CreditsRollCategory_Playtesting¦PartyGirlNames¦SlimeNames_Green¦GameTitle¦BunnyNames_Flemish¦TownNPCMood_WitchDoctor¦BunnyNames_Silver¦CreditsRollCategory_Dialog¦GolferChatter¦BunnyNames_Angora¦DogNames_Husky¦DogNames_Labrador¦CatNames_White¦BunnyNames_Dutch¦ItemName¦Workshop¦PirateNames¦LoadingTips_Default¦SlimeOldChatter¦Bestiary_ItemDropConditions¦TownNPCMoodBiomes¦CommonBestiaryFlavor¦PrincessNames¦DeathText¦PirateSpecialText¦GolferNames¦LegacyDialog¦RandomWorldName_Legacy¦Bestiary_FlavorText¦LegacyDresserType¦ArmsDealerSpecialText¦Misc¦TaxCollectorSpecialText¦LucyTheAxe_ThrownAway¦LegacyMisc¦TravelingMerchantNames¦LoadingTips_Keyboard¦StylistNames¦WitchDoctorNames¦CyborgNames¦CreditsRollCategory_QualityAssurance¦DyeTraderNames¦AnglerQuestText¦CyborgSpecialText¦TruffleNames¦CreditsRollCategory_Music¦Bestiary_Invasions¦Announcement¦MechanicNames¦DemolitionistNames¦TownNPCMood_ArmsDealer¦TownNPCMood_GoblinTinkerer¦CatChatter¦PaintingArtist¦Bestiary_Times¦TitleLinks¦CreditsRollCategory_ExecutiveProducer¦ArmorSetBonus¦GoblinTinkererNames¦TownNPCMood_SantaClaus¦Error¦WorldGeneration |
printTable
{{#invoke:GameText| printTable | lang = <language> }}
Displays a tabular visualization of the entire database, where the left column is the key and the right column is the string. The keys are ordered alphabetically.
purge
{{#invoke:GameText| purge | lang = <language> }}
Purges the cache of the game text database for the given language. This is necessary after making a change to the database. See Module:GameText/loaddata for more details.
Other modules
The module can be called from another module with the functions listed below.
getText
require('Module:GameText').getText('<key>', '<language>', {<placeholder replacements>})
Returns the string associated with the given key. The placeholder replacements should be in a literal translation table, i.e. {['<placeholder>']='<replacement>'}.
| Code | Variable result
|
|---|---|
local gameText = require('Module:GameText')
local result = gameText.getText('BuffDescription.ObsidianSkin')
|
'Immune to lava'
|
local gameText = require('Module:GameText')
local result = gameText.getText('LegacyDialog.19')
|
"{PlayerName} is it? I've heard good things, friend!"
|
local gameText = require('Module:GameText')
local result = gameText.getText('LegacyDialog.19', 'en', { ['{PlayerName}'] = 'myName' })
|
"myName is it? I've heard good things, friend!"
|
local gameText = require('Module:GameText')
local result = gameText.getText('Misc.ResolutionChanged')
|
'Resolution changed to: {0}x{1}.'
|
local gameText = require('Module:GameText')
local result = gameText.getText('Misc.ResolutionChanged', 'en', { ['{0}'] = '1920', ['{1}'] = '1080' })
|
'Resolution changed to: 1920x1080.'
|
getData
require('Module:GameText').getData('<key>', '<language>')
Returns the string or table associated with the given key. Placeholders are never replaced and condition marks like {?Homeless} are kept in the strings.
| Code | Variable result
|
|---|---|
local gameText = require('Module:GameText')
local result = gameText.getData('BuffDescription.ObsidianSkin')
|
'Immune to lava'
|
local gameText = require('Module:GameText')
local result = gameText.getData('WorldGeneration')
|
{
["OceanSand"] = "Generating ocean sand",
["WavyCaves"] = "Generating wavy caves"
}
|
local gameText = require('Module:GameText')
local result = gameText.getData('BartenderChatter')
|
{
["Chatter_1"] = "I've got the cure for what ails ya! Get it? Ale? No?",
["Chatter_2"] = "They say you're strong, well, I know strong. Let's see if you measure up.",
["Chatter_3"] = "Back where I'm from, we only serve Root Beer...",
["Chatter_4"] = "This is a big upgrade from wiping that table all day.",
["Chatter_5"] = "Life's a challenge when you're just naturally better than everyone else.",
["Chatter_6"] = "What am I doing here...",
["Chatter_7"] = "A lot of tenacity and a little bit of luck can go a long way...",
["Chatter_8"] = "Have you seen any Meburs around here?",
["Chatter_9"] = "{Dryad} seems nice. I should bring her back with me.",
["Chatter_10"] = "Do you think {Steampunker} has an extra of that gun? I know a witch that may want one.",
["Chatter_11"] = "No wonder {Demolitionist} has so many accidents. You can't imagine how much ale he buys from me.",
["Chatter_12"] = "Normally, I'm not much of a fan of Goblins, but {GoblinTinkerer} seems to be an alright sort.",
["Chatter_13"] = "{?Day}Anyone see where the Dryad went?",
["Chatter_14"] = "{?!Day}Really quiet out there. A little too quiet...",
["Chatter_15"] = "{?!Day}Check in with me, and do your job.",
["Chatter_16"] = "{?BloodMoon}You know, where I'm from, a Blood Moon is actually just an excuse to get some fresh air.",
["Chatter_17"] = "{?MoonLordDefeated}Moon Lord, don't you mean Abyss Lord?",
["Chatter_18"] = "{?HardMode}I know a Lavamancer that would really like that hellstone down in the underworld.",
["Chatter_19"] = "{?Homeless}Know any good places to set up shop? Would love to open up a bar here."
}
|
getSections
require('Module:GameText').getSections()
Returns all top-level keys from the database.
| Code | Variable result
|
|---|---|
local gameText = require('Module:GameText')
local result = gameText.getSections()
|
{
"Achievements",
"AnglerChatter",
"AnglerNames",
"AnglerQuestChatter",
"AnglerQuestText",
"AnglerSpecialText",
"Announcement",
"ArmorSetBonus",
"ArmsDealerNames",
"ArmsDealerSpecialText",
-- ...
-- (rest omitted for brevity)
}
|
purge
require('Module:GameText').purge('<language>')
Purges the cache of the game text database for the given language. This is necessary after making a change to the database. See Module:GameText/loaddata for more details.
--------------------------------------------------------------------------------
--
-- =============================================================================
--
-- Module:GameText
--
-- Fetching text from Terraria's localization files
--
-- =============================================================================
--
-- Code annotations:
-- This module is documented according to LuaCATS (Lua Comment and Type System).
-- LuaCATS comments are prefixed with three dashes (---) and use Markdown syntax.
-- For a full list of annotations, see the following link:
-- https://luals.github.io/wiki/annotations/
--
--------------------------------------------------------------------------------
local trim = mw.text.trim
---Holds the arguments from the template call.
---@type table<string, string>
local args_table
---Full database of all strings in Terraria's localization files for the
---different languages. Is filled by the `loadDatabase` function.
---Keys are language codes (e.g. 'de', 'en', 'fr', ...) and values are the
---respective localization tables from [[Module:GameText/db-de]],
---[[Module:GameText/db-en]], [[Module:GameText/db-fr]], ...
---@type table<string, table>
local db = {}
---Return a trimmed version of the value of the template parameter with the specified `key`.
---Return `nil` if the parameter is empty or unset.
---@param key string|integer
---@return string?
local function getArg(key)
local value = args_table[key]
if not value then
return nil
end
value = trim(value)
if value == '' then
return nil
end
return value
end
---Concatenate the values of a table as a string. Works like `table.concat()`,
---except it also accepts associative arrays, i.e. tables that don't have
---purely numerical indices, like `{['foo']='bar'}`.
---@param tbl table
---@param sep string Separator for concatenation
---@return string
local function concatTable(tbl, sep)
local arr = {}
for _, v in pairs(tbl) do
arr[#arr+1] = v
end
return table.concat(arr, sep)
end
---Fill the database of strings for a given language and return it.
---The database is cached; see [[Module:GameText/loaddata]] for details about
---what this means.
---@param lang string Language code
---@return table
local function loadDatabase(lang)
if not db[lang] then
local success, result = xpcall(
-- try to load the database for the given language
function() return mw.loadData('Module:GameText/loaddata-' .. lang) end,
-- if it doesn't exist, fall back to the English database
function() return mw.loadData('Module:GameText/loaddata-en') end
)
db[lang] = result or {}
end
return db[lang]
end
---Process the template parameter input for placeholder replacements.
---Terraria's localization strings contain placeholders like '{0}' or '<right>',
---which the `getText` function of this module replaces by the custom strings
---provided by template parameters. The function uses `string.gsub()` for that
---replacement and it requires a table of replacements for it, so the template
---parameters must be converted to a replacement table for `string.gsub()`.
---That conversion is what this function does. Example:
---Template parameter input: `|x_0=Angler|y_right=Right click`.
---Replacement table: `{['{0}']='Angler', ['<right>']='Right click'}`.
---
---There are two types of placeholders: '{foo}' and '<foo>'. The first type is
---prefixed with 'x_' in the template parameters, the second with 'y_'.
---@param templateParams table<string, string> Template parameter input
---@return table? repl Replacement table suitable for `string.gsub()`
local function replacementArgs(templateParams)
local replTable = {}
---Whether the `replTable` is empty.
local anyReplacements = false
-- iterate over the template parameters and extract the ones starting with
-- 'x_' or 'y_'
for paramKey, paramValue in pairs(templateParams) do
-- first type of placeholder: 'x_foo' => '{foo}'
string.gsub(paramKey, '^x_(.+)', function(s)
replTable['{' .. s .. '}'] = paramValue
anyReplacements = true
end)
-- second type of placeholder: 'y_foo' => '<foo>'
string.gsub(paramKey, '^y_(.+)', function(s)
replTable['<' .. s .. '>'] = paramValue
anyReplacements = true
end)
end
-- return `nil` if the `replTable` is empty, i.e. if there are no relevant
-- parameters in the input
if anyReplacements then
return replTable
end
end
---Return the localization string or table of strings corresponding to the given
---key. Keys can be nested using dots, e.g. `ItemName.IronPickaxe`.
---@param key string Identifier of the localization string/table
---@param lang? string Language code
---@return string|table|nil
local function get(key, lang)
key = trim(key)
-- The `key` is a dot-separated string that identifies a string or object in
-- the localization data. The JSON localization files contain nested objects
-- like so (fictional example):
-- {
-- "Buffs": {
-- "Names": {
-- "StardustMinion": "Stardust Cell"
-- }
-- }
-- }
-- Usually there are only 2 levels of nesting but we must assume that there
-- can be any number of levels.
-- The JSON data is `db[lang]` here, with JSON objects being Lua tables.
-- We "descend" into the data by splitting the `key` on dots into subkeys.
---Index of the next "subkey" within the `key`.
local nextSubkeyStartPosition = 1
-- For the key splitting we use a for-loop in the "generic form", which
-- requires a "function-in-function":
---Return a function that returns the index of the next dot in the `key`,
---starting from the current `nextSubkeyStartPosition`.
local function findNextDot()
return function()
-- note: string.find() returns start *and* end index, but those are
-- always identical because our pattern is only 1 character long
return string.find(key, '.', nextSubkeyStartPosition, true)
end
end
-- Initially we start with the entire database.
local data = db[lang] or loadDatabase(lang or 'en')
-- We locate the first subkey:
for dotPosition in findNextDot() do
local subkey = string.sub(key, nextSubkeyStartPosition, dotPosition - 1)
-- Then we descend into the `data` using this subkey:
data = data[tonumber(subkey) or subkey]
-- (`tonumber` is needed because numerical indices are true integers,
-- not "integer-as-a-string"s)
if not data then
-- subkey is invalid
return nil
end
-- Finally we repeat it with the next subkey.
nextSubkeyStartPosition = dotPosition + 1
end
-- The above is the "generic form" of the for-loop. It is repeated until
-- `dotPosition` becomes `nil`, i.e. until there are no more dots in the
-- `key`.
-- The final part of the `key` is the subkey to look for in the `data`.
if nextSubkeyStartPosition ~= 0 then
key = string.sub(key, nextSubkeyStartPosition)
end
-- Using the example data from above, this is how the process would go:
-- We would get the first subkey from the `key` 'Buffs.Names.StardustMinion',
-- i.e. 'Buffs'. We would descend one level now by setting `data`
-- (previously the entire database) to `data['Buffs']`.
-- Then we would get the second subkey, 'Names' and descend another level by
-- setting `data` to `data['Names']`.
-- There would be no more dots in the `key` now, so the current `data` would
-- be the table in which to look for the third subkey, 'StardustMinion'.
-- Since we would have descended two levels, the `data` would be:
-- `db[lang]['Buffs']['Names']`.
-- Look for the final subkey:
local result = data[tonumber(key) or key]
if result and type(result) == 'string' then
-- some localization strings contain reference marks, such as
-- '{$CommonItemTooltip.RightClickToOpen}'; replace those
result = string.gsub(result, '({%$(.-)})', function(_, referenceKey)
return get(referenceKey, lang)
end)
end
return result
end
---Return the string corresponding to the given `key`. The value of the `key`
---must be a string, not a table. Placeholders in it like '{0}' or '<right>'
---will be replaced according to the `placeholderReplacements`, which should
---be a table suitable for `string.gsub()`, e.g.:
---```lua
---{
--- ['{0}'] = 'Angler',
--- ['<right>'] = 'Right click'
---}
---```
---@param key string Identifier of the localization string
---@param lang? string Language code
---@param placeholderReplacements? table<string, string>
---@return string?
local function getText(key, lang, placeholderReplacements)
if not key then
return
end
local result = get(key, lang) or get(key, 'en')
-- error handling
if not result then
return
end
if type(result) ~= 'string' then
error('The value of "' .. key .. '" is not a string! getText can only be used for strings.')
end
-- strip condition marks like '{?Homeless}'
result = string.gsub(result, '{%?.-}', '')
-- replace placeholders
if placeholderReplacements then
result = string.gsub(result, '%b{}', placeholderReplacements)
result = string.gsub(result, '%b<>', placeholderReplacements)
end
return result
end
---Return all keys of the localization database for one language on the top level.
---@return string[]
local function getSectionList()
-- the language doesn't matter because all languages should have the same keys
local data = db['en'] or loadDatabase('en')
local arr = {}
for k, v in pairs(data) do
arr[#arr + 1] = k
end
return arr
end
--------------------------------------------------------------------------------
---Main return object
local p = {}
---For `{{gameText}}`: return a string by key.
---@param frame table Interface to the parser (`mw.frame`)
---@return string?
p.get = function(frame)
args_table = frame:getParent().args -- global input args cache
local result = getText(getArg(1), getArg('lang') or frame.args['lang'], replacementArgs(args_table))
if result then
return '<span class="gameText">' .. string.gsub(result, '\n', '<br/>') .. '</span>'
end
end
---For `{{gameText/raw}}`: return a string by key without any processing/formatting.
---@param frame table Interface to the parser (`mw.frame`)
---@return string
p.getRaw = function(frame)
return
(frame.args['prefix'] or '')
.. (getText(frame.args[1], frame.args['lang'] or require('Module:Lang').get(), replacementArgs(frame.args)) or '')
.. (frame.args['postfix'] or '')
end
---For `{{gameText/section}}`: return one table ("section") from the database as
---an array from Extension:ArrayFunctions.
---@param frame table Interface to the parser (`mw.frame`)
---@return string
p.getSection = function(frame)
args_table = frame.args -- global input args cache
return mw.af.export(get(getArg(1), getArg('lang')))
end
---For `{{gameText/sectionList}}`: return all top-level keys as an array from
---Extension:ArrayFunctions.
---@param frame table Interface to the parser (`mw.frame`)
---@return string
p.getSectionList = function(frame)
args_table = frame.args -- global input args cache
return mw.af.export(getSectionList())
end
---Return all keys and strings of one table from the database, separated by the
---character '¦'. The separator between each key and string is '₪'. If no key is
---provided, then merely return all keys in the entire database.
---@param frame table Interface to the parser (`mw.frame`)
---@return string?
p.listAll = function(frame)
local lang = frame.args['lang'] or 'en'
loadDatabase(lang)
local arr = {}
if frame.args[1] then
if not db[lang][frame.args[1]] then
return
end
for k, v in pairs(db[lang][frame.args[1]]) do
arr[#arr + 1] = k .. '₪' .. v
end
else
-- no key provided
for k, v in pairs(db[lang]) do
arr[#arr + 1] = k
end
end
return table.concat(arr, '¦')
end
---Return all keys of one table from the database, separated by the character '¦'.
---If no key is provided, then merely return all keys in the entire database.
---@param frame table Interface to the parser (`mw.frame`)
---@return string
p.listKeys = function(frame)
local lang = frame.args['lang'] or 'en'
loadDatabase(lang)
local data
if frame.args[1] then
data = db[lang][frame.args[1]] or {}
else
-- no key provided
data = db[lang]
end
local arr = {}
for k, v in pairs(data) do
arr[#arr + 1] = k
end
return table.concat(arr, '¦')
end
---Return a tabular visualization of the entire database, where the left column
---is the key and the right column is the string.
---@param frame table Interface to the parser (`mw.frame`)
---@return string
p.printTable = function(frame)
local lang = frame.args['lang'] or 'en'
local data = loadDatabase(lang)
local allKeys = {}
local allValues = {}
local function recurse(datatable, previousKey)
for thisSubkey, thisData in pairs(datatable) do
local nextKey
if previousKey ~= '' then
nextKey = previousKey .. '.' .. thisSubkey
else
nextKey = thisSubkey
end
if type(thisData) ~= 'table' then
table.insert(allKeys, nextKey)
allValues[nextKey] = thisData
else
recurse(thisData, nextKey)
end
end
end
recurse(data, '')
table.sort(allKeys)
local output = {'<table class="wikitable"><tr><th>Key</th><th>String</th></tr>'}
for i = 1, #allKeys do
local key = allKeys[i]
local keyCell = '<td><code>' .. key .. '</code></td>'
local valueCell = '<td><span class="gameText">' .. string.gsub(allValues[key], '\n', '<br/>') .. '</span></td>'
table.insert(output, '<tr>' .. keyCell .. valueCell .. '</tr>')
end
table.insert(output, '</table>')
return table.concat(output)
end
---Purge the cache of the string database for the given language. See
---[[Module:GameText/loaddata]] for details about what this means.
---Invoke from wikitext or from another module.
---@param frame table Interface to the parser (`mw.frame`)
p.purge = function(frame)
local lang
if frame == mw.getCurrentFrame() then
lang = frame.args['lang']
else
lang = frame
end
lang = lang or 'en'
require('Module:GameText/loaddata').purge(lang)
end
---For other modules: return a string.
p.getText = getText
---For other modules: return a string or table without processing/formatting.
p.getData = get
---For other modules: return an array of top-level keys.
p.getSections = getSectionList
return p