feat: add translator cog for fantasy languages

Implements commands for translating text into roleplay languages like Valspiren, Elvish, and Draconic, ported from a web application.
This commit is contained in:
2025-09-21 04:22:21 -04:00
parent 48c3793768
commit d3ee48112a
3 changed files with 178 additions and 0 deletions

4
translator/__init__.py Normal file
View File

@@ -0,0 +1,4 @@
from .translator import Translator
async def setup(bot):
await bot.add_cog(Translator(bot))

17
translator/info.json Normal file
View File

@@ -0,0 +1,17 @@
{
"author": [
"unstableCogs"
],
"install_msg": "Thank you for installing the Translator cog. Use the `/translate` command to get started.",
"name": "Translator",
"short": "Translates text into various fantasy and fun languages.",
"description": "A feature-rich translator cog ported from a web application. Supports numerous languages from Common to Valspiren, Sinary, and more. Includes a command to list all available languages.",
"tags": [
"translate",
"fun",
"roleplay",
"language"
],
"requirements": [],
"end_user_data_statement": "This cog does not store any end user data."
}

157
translator/translator.py Normal file
View File

@@ -0,0 +1,157 @@
import discord
import re
from redbot.core import commands, app_commands
# --- Translation Maps (Ported from JavaScript) ---
VALSPIREN_MAP = {'a':'ak','b':'ba','c':'ce','d':'di','e':'ek','f':'fo','g':'gu','h':'ha','i':'ik','j':'je','k':'ki','l':'lo','m':'mu','n':'na','o':'ok','p':'pe','q':'qi','r':'ro','s':'su','t':'ta','u':'uk','v':'ve','w':'wi','x':'xo','y':'yk','z':'zu'}
KITSUNE_MAP = {'a':'ka','b':'be','c':'chi','d':'de','e':'e','f':'fu','g':'ga','h':'hi','i':'i','j':'ji','k':'ki','l':'ru','m':'ma','n':'na','o':'o','p':'pe','q':'kyu','r':'re','s':'sa','t':'to','u':'u','v':'ve','w':'wa','x':'za','y':'ya','z':'ze'}
ELVISH_MAP = {'a':'ael','b':'\'eth','c':'cal','d':'dor','e':'elen','f':'fae','g':'\'gan','h':'h<EFBFBD>r','i':'ia','j':'yel','k':'\'ken','l':'lael','m':'mel','n':'n<EFBFBD>n','o':'oia','p':'\'pes','q':'qen','r':'rae','s':'sil','t':'t<EFBFBD>','u':'ui','v':'vae','w':'win','x':'\'xal','y':'yl','z':'z<EFBFBD>r'}
DWARVISH_MAP = {'a':'az','b':'bar','c':'krag','d':'dur','e':'ek','f':'fol','g':'grum','h':'hur','i':'in','j':'jor','k':'kaz','l':'lur','m':'mor','n':'nur','o':'ok','p':'por','q':'qur','r':'ruk','s':'son','t':'thor','u':'um','v':'val','w':'wor','x':'xor','z':'zul'}
ORCISH_MAP = {'a':'agh','b':'bug','c':'karg','d':'dur','e':'egh','f':'fug','g':'grol','h':'hosh','i':'izg','j':'jug','k':'krunk','l':'lug','m':'mog','n':'nog','o':'ogg','p':'pug','q':'qug','r':'ruk','s':'snaga','t':'tusk','u':'uruk','v':'vug','w':'warg','x':'xug','y':'yag','z':'zug'}
GOBLIN_MAP = {'a':'az','b':'bik','c':'clik','d':'dik','e':'ek','f':'fiz','g':'gib','h':'hik','i':'ik','j':'jik','k':'krik','l':'lik','m':'mik','n':'nik','o':'ok','p':'pik','q':'qik','r':'rik','s':'snik','t':'tik','u':'uk','v':'vik','w':'wik','x':'xik','y':'yik','z':'zik'}
DRACONIC_MAP = {'a':'ax','b':'baxis','c':'caex','d':'drak','e':'ess','f':'faex','g':'gix','h':'heth','i':'ir','j':'jyss','k':'kex','l':'lix','m':'maex','n':'nex','o':'oth','p':'pex','q':'qexis','r':'rax','s':'syth','t':'thrax','u':'ur','v':'vyx','w':'wess','x':'xis','y':'yth','z':'zix'}
FELINE_MAP = {'a':'meow','b':'brrt','c':'chrr','d':'drrt','e':'eek','f':'frrt','g':'grrowl','h':'hiss','i':'mii','j':'jrr','k':'krr','l':'lrr','m':'mrow','n':'nyah','o':'oww','p':'purr','q':'qrr','r':'rrr','s':'sss','t':'trill','u':'urr','v':'vrr','w':'wrr','x':'xrr','y':'yowl','z':'zzz'}
AQUAN_MAP = {'a':'aqua','b':'blub','c':'\'cress','d':'drop','e':'eelee','f':'flow','g':'glur','h':'hydro','i':'ishi','j':'\'jyr','k':'\'kyr','l':'luu','m':'\'myr','n':'\'nyr','o':'oro','p':'ploop','q':'\'qyr','r':'\'ryp','s':'sh\'l','t':'tide','u':'\'urn','v':'\'vyr','w':'wash','x':'\'xyr','y':'\'yyr','z':'\'zyr'}
CELESTIAL_MAP = {'a':'\'ana','b':'\'bara','c':'\'cera','d':'\'dona','e':'\'elara','f':'\'fana','g':'\'gala','h':'\'hylia','i':'\'iana','j':'\'jana','k':'\'kana','l':'\'lora','m':'\'mara','n':'\'nara','o':'\'ora','p':'\'pera','q':'\'qana','r':'\'ria','s':'\'sera','t':'\'tara','u':'\'ura','v':'\'vara','w':'\'wana','x':'\'xara','y':'\'yana','z':'\'zara'}
INFERNAL_MAP = {'a':'az\'','b':'\'baal','c':'\'krez','d':'\'drak','e':'ez\'','f':'\'fel','g':'\'gor','h':'\'hath','i':'iz\'','j':'\'jaz','k':'\'kraz','l':'\'laz','m':'\'mor','n':'\'naz','o':'oz\'','p':'\'paz','q':'\'qaz','r':'\'raz','s':'\'saz','t':'\'taz','u':'uz\'','v':'\'vaz','w':'\'waz','x':'\'xaz','y':'\'yaz','z':'\'zaz'}
SYLVAN_MAP = {'a':'ani','b':'bri','c':'cae','d':'dae','e':'eni','f':'fae','g':'gra','h':'hae','i':'ia','j':'jae','k':'kae','l':'lor','m':'mae','n':'nem','o':'olo','p':'pae','q':'qae','r':'rae','s':'sae','t':'tae','u':'uni','v':'vae','w':'wae','x':'xae','y':'yae','z':'zae'}
GNOMISH_MAP = {'a':'akk','b':'bink','c':'clank','d':'dink','e':'enk','f':'fizz','g':'giz','h':'hink','i':'ink','j':'jink','k':'kink','l':'link','m':'mink','n':'nink','o':'onk','p':'sprok','q':'qink','r':'rink','s':'sprock','t':'tink','u':'unk','v':'vink','w':'whirr','x':'xink','y':'yink','z':'zink'}
SINARY_MAP = {'a':'a!','b':'7b','c':'c#','d':'d4','e':'3e','f':'f^','g':'g&','h':'h8','i':'(i','j':'j0','k':'_k','l':'l2','m':'=m','n':'n+','o':'5o','p':'-p','q':'q{','r':'}r','s':'[s','t':'t]','u':'|u','v':':v','w':'"w','x':'x<','y':'>y','z':'?z'}
SUCCUBUS_MAP = {'a':'ah\'','b':'\'bel','c':'\'chae','d':'\'des','e':'\'esh','f':'\'fey','g':'\'gis','h':'hah\'','i':'\'ish','j':'\'jo','k':'\'ka','l':'\'lis','m':'\'mah','n':'\'nah','o':'oh\'','p':'\'pah','q':'\'qia','r':'\'rah','s':'\'sha','t':'\'thae','u':'uh\'','v':'\'vi','w':'\'wah','x':'\'xi','y':'\'yah','z':'\'zah'}
SCORPION_MAP = {'a':'sk\'','b':'t\'k','c':'k\'ss','d':'d\'th','e':'e\'sk','f':'f\'t','g':'g\'th','h':'h\'k','i':'i\'s','j':'j\'t','k':'k\'t','l':'l\'k','m':'m\'k','n':'n\'t','o':'o\'s','p':'p\'k','q':'q\'t','r':'r\'k','s':'s\'k','t':'t\'s','u':'u\'s','v':'v\'t','w':'w\'k','x':'x\'s','y':'y\'k','z':'z\'t'}
ABYSSAL_MAP = {'a':'azg','b':'braz','c':'kraz','d':'dorg','e':'ezg','f':'fraz','g':'gor','h':'hath','i':'ix','j':'jraz','k':'kral','l':'laz','m':'maz','n':'naz','o':'oz','p':'praz','q':'qor','r':'raz','s':'saz','t':'taz','u':'uzg','v':'vraz','w':'waz','x':'xul','y':'yaz','z':'zaz'}
SPIRITUAL_MAP = {'a':'\'aura','b':'\'breth','c':'\'ciel','d':'\'dion','e':'\'ethys','f':'\'fey','g':'\'glyn','h':'\'hymn','i':'\'ia','j':'\'jora','k':'\'kye','l':'\'lume','m':'\'mana','n':'\'nima','o':'\'omni','p':'\'pria','q':'\'qia','r':'\'reth','s':'\'seren','t':'\'thyme','u':'\'umbra','v':'\'vym','w':'\'wisp','x':'\'xia','y':'\'yara','z':'\'zion'}
OGRISH_MAP = {'a':'ug','b':'blud','c':'crag','d':'dug','e':'eeg','f':'fug','g':'gron','h':'hug','i':'ig','j':'jug','k':'krug','l':'lug','m':'mush','n':'nug','o':'og','p':'pug','q':'qug','r':'rug','s':'slog','t':'thok','u':'urk','v':'vog','w':'wug','x':'xug','y':'yug','z':'zug'}
AVIAN_MAP = {'a':'\'aara','b':'\'bree','c':'chir\'','d':'\'dree','e':'eek','f':'\'flutter','g':'gree\'','h':'hrooa','i':'ii\'','j':'\'jakk','k':'kree\'','l':'\'liri','m':'\'meeka','n':'\'neer','o':'\'oroo','p':'pip\'','q':'\'qree','r':'\'reea','s':'\'skraw','t':'tweet\'','u':'\'urr','v':'\'vree','w':'\'warble','x':'\'xee','y':'\'yari','z':'\'zeer'}
DEVILISH_MAP = {'a':'\'ayl','b':'\'baal','c':'\'cress','d':'\'drev','e':'\'eyl','f':'\'fane','g':'\'gyl','h':'hysh\'','i':'\'iyl','j':'\'jex','k':'\'krys','l':'\'lyl','m':'\'mal','n':'\'nyl','o':'\'oyl','p':'\'prax','q':'\'qyl','r':'\'ryl','s':'\'shayd','t':'\'trys','u':'\'uyl','v':'\'vyl','w':'\'wryl','x':'\'xyl','y':'\'yyl','z':'\'zyll'}
HERBILORE_MAP = {'a':'aloe','b':'bark','c':'clover','d':'dand','e':'elder','f':'fern','g':'groot','h':'herb','i':'ivy','j':'juni','k':'kelp','l':'leaf','m':'moss','n':'nettle','o':'oak','p':'petal','q':'quin','r':'root','s':'sprout','t':'thyme','u':'ursi','v':'vine','w':'willow','x':'xylem','y':'yarrow','z':'zinni'}
FIENDISH_MAP = {'a':'az\'ael','b':'ba\'al','c':'cre\'z','d':'dre\'th','e':'esh\'','f':'fiir\'','g':'gre\'th','h':'ha\'el','i':'i\'z','j':'je\'th','k':'krez\'','l':'le\'th','m':'morn\'','n':'ne\'th','o':'o\'z','p':'pre\'th','q':'qe\'th','r':'re\'th','s':'se\'th','t':'te\'th','u':'u\'z','v':'ve\'th','w':'we\'th','x':'xith\'','y':'ye\'th','z':'zael\''}
ELEMENTAL_MAP = {'a':'aer','b':'breeze','c':'cinder','d':'dust','e':'ember','f':'flow','g':'gust','h':'hail','i':'ignis','j':'jet','k':'kinetic','l':'lava','m':'mist','n':'nova','o':'ozone','p':'pyre','q':'quake','r':'rain','s':'stone','t':'terra','u':'umbra','v':'vapor','w':'wave','x':'xenon','y':'yon','z':'zephyr'}
AQUATIC_MAP = {'a':'abyss','b':'brine','c':'coral','d':'depth','e':'eel','f':'fin','g':'gurgle','h':'hydro','i':'ink','j':'jelly','k':'krill','l':'lagoon','m':'murk','n':'naut','o':'ocean','p':'pearl','q':'quatic','r':'reef','s':'salt','t':'tide','u':'urchin','v':'void','w':'wave','x':'xiph','y':'yacht','z':'zone'}
CONSTRUCT_MAP = {'a':'auto','b':'bolt','c':'clank','d':'diode','e':'engine','f':'forge','g':'gear','h':'hydro','i':'iron','j':'joint','k':'kinetic','l':'link','m':'motor','n':'node','o':'optic','p':'piston','q':'quantum','r':'rivet','s':'servo','t':'titan','u':'unit','v':'volt','w':'whirr','x':'xenon','y':'yoke','z':'zinc'}
MYCONID_MAP = {'a':'agaric','b':'bolete','c':'cap','d':'decay','e':'enoki','f':'fungi','g':'gill','h':'hyphae','i':'indigo','j':'jelly','k':'kombu','l':'lichen','m':'myco\'','n':'nidur','o':'oyster','p':'puff','q':'quorn','r':'rhizo','s':'spore\'','t':'thallus','u':'umbra','v':'velvet','w':'wart','x':'xero','y':'yeast','z':'zoospore'}
VOIDTOUCHED_MAP = {'a':'a\'th','b':'b\'zoth','c':'c\'thun','d':'d\'gol','e':'e\'th','f':'f\'thagn','g':'g\'noth','h':'h\'zoth','i':'i\'th','j':'j\'th','k':'k\'th','l':'l\'th','m':'m\'th','n':'n\'th','o':'o\'th','p':'p\'th','q':'qor\'','r':'r\'lyeh','s':'s\'th','t':'t\'th','u':'u\'th','v':'v\'lath','w':'w\'th','x':'x\'thul','y':'y\'th','z':'zy\'th'}
LIZARDFOLK_MAP = {'a':'\'ax','b':'\'bax','c':'\'caz','d':'\'daz','e':'\'ex','f':'\'fax','g':'\'gaz','h':'h\'ss','i':'\'ix','j':'\'jax','k':'sk\'ex','l':'\'lax','m':'\'max','n':'\'nax','o':'\'ox','p':'\'pax','q':'\'qax','r':'\'rax','s':'s\'lith','t':'t\'char','u':'\'ux','v':'\'vax','w':'\'wax','x':'\'xax','y':'\'yax','z':'\'zax'}
ARACHNID_MAP = {'a':'\'arr','b':'\'brach','c':'ch\'t','d':'\'drach','e':'\'err','f':'\'fune','g':'\'goss','h':'\'harr','i':'\'itt','j':'\'jarr','k':'klik\'','l':'\'lar','m':'\'marr','n':'\'narr','o':'\'orr','p':'\'parr','q':'\'qarr','r':'\'rarr','s':'skitter\'','t':'th\'k','u':'\'urr','v':'\'varr','w':'web\'','x':'\'xarr','y':'\'yarr','z':'\'zarr'}
ANGELIC_MAP = {'a':'adriel','b':'baraqiel','c':'camael','d':'divinus','e':'elohim','f':'fanuel','g':'gloria','h':'hesed','i':'israfel','j':'jophiel','k':'kyrie','l':'lux','m':'michael','n':'netzach','o':'ophaniel','p':'peniel','q':'qadish','r':'raphael','s':'seraph','t':'tiferet','u':'uriel','v':'virtues','w':'wele\'el','x':'xathanael','y':'yesod','z':'zadkiel'}
RATFOLK_MAP = {'a':'skree','b':'bite','c':'claw','d':'dark-thing','e':'eek','f':'filth','g':'gnaw','h':'hiss','i':'itch','j':'junk','k':'kill','l':'long-tail','m':'muck','n':'nest-thing','o':'rot-stink','p':'plague','q':'quick-quick','r':'rust','s':'skitter','t':'twitch','u':'under-thing','v':'vermin','w':'waste','x':'pox','y':'yes-yes','z':'zap-tail'}
HALFTONGUE_MAP = {'a':'apple','b':'bramble','c':'crumpet','d':'dale','e':'elderberry','f':'fiddle','g':'garden','h':'hearth','i':'iris','j':'jam','k':'kettle','l':'lazy','m':'meadow','n':'nimble','o':'oats','p':'pudding','q':'quaint','r':'river','s':'sunny','t':'tater','u':'underhill','v':'vine','w':'willow','x':'extra','y':'yarn','z':'zesty'}
UNDERCOMMON_MAP = {'a':'velk','b':'xund','c':'k\'yorl','d':'d\'ruth','e':'e\'trorn','f':'faer','g':'gol','h':'h\'chak','i':'i\'lith','j':'j\'lar','k':'k\'lar','l':'lil','m':'m\'lar','n':'nind','o':'olath','p':'p\'lar','q':'qu\'ellar','r':'ril','s':'sorn','t':'t\'lar','u':'uss','v':'v\'lar','w':'wyl','x':'x\'lar','y':'y\'lar','z':'z\'ress'}
MORSE_MAP = {'a':'.-','b':'-...','c':'-.-.','d':'-..','e':'.','f':'..-.','g':'--.','h':'....','i':'..','j':'.---','k':'-.-','l':'.-..','m':'--','n':'-.','o':'---','p':'.--.','q':'--.-','r':'.-.','s':'...','t':'-','u':'..-','v':'...-','w':'.--','x':'-..-','y':'-.--','z':'--..','1':'.----','2':'..---','3':'...--','4':'....-','5':'.....','6':'-....','7':'--...','8':'---..','9':'----.','0':'-----',' ':'/'}
LEET_MAP = {'a':'4','b':'8','c':'(','d':')','e':'3','f':'|=','g':'6','h':'#','i':'1','j':']','k':'|<','l':'1','m':'/\\/\\','n':'/\\/','o':'0','p':'|D','q':'(,)','r':'|2','s':'5','t':'7','u':'|_|','v':'\\/','w':'\\/\\/','x':'><','y':'`/','z':'2'}
# --- Translation Logic Functions ---
def generic_translator(text, translation_map, separator):
"""Translate text by mapping characters and joining them."""
translated_words = []
for word in text.split(' '):
translated_chars = [translation_map.get(char.lower(), char) for char in word]
translated_words.append(separator.join(translated_chars))
return (' ' if separator else ' ').join(translated_words)
# --- Main Cog Class ---
class Translator(commands.Cog):
"""A cog for translating text into various languages."""
def __init__(self, bot):
self.bot = bot
self.languages = self._setup_languages()
def _setup_languages(self):
"""Initializes the language definitions."""
# Using lambdas to keep it concise, matching the JS structure
return {
'common': {'name': 'Common', 'translate': lambda text: text},
'abyssal': {'name': 'Abyssal', 'translate': lambda text: generic_translator(text, ABYSSAL_MAP, ' ')},
'angelic': {'name': 'Angelic', 'translate': lambda text: generic_translator(text, ANGELIC_MAP, ' ')},
'aquan': {'name': 'Aquan', 'translate': lambda text: generic_translator(text, AQUAN_MAP, ' ')},
'aquatic': {'name': 'Aquatic', 'translate': lambda text: generic_translator(text, AQUATIC_MAP, ' ')},
'arachnid': {'name': 'Arachnid', 'translate': lambda text: generic_translator(text, ARACHNID_MAP, ' ')},
'avian': {'name': 'Avian', 'translate': lambda text: generic_translator(text, AVIAN_MAP, ' ')},
'celestial': {'name': 'Celestial', 'translate': lambda text: generic_translator(text, CELESTIAL_MAP, ' ')},
'construct': {'name': 'Construct', 'translate': lambda text: generic_translator(text, CONSTRUCT_MAP, ' ')},
'devilish': {'name': 'Devilish', 'translate': lambda text: generic_translator(text, DEVILISH_MAP, ' ')},
'draconic': {'name': 'Draconic', 'translate': lambda text: generic_translator(text, DRACONIC_MAP, ' ')},
'dwarvish': {'name': 'Dwarvish', 'translate': lambda text: generic_translator(text, DWARVISH_MAP, ' ')},
'elemental': {'name': 'Elemental', 'translate': lambda text: generic_translator(text, ELEMENTAL_MAP, ' ')},
'elvish': {'name': 'Elvish', 'translate': lambda text: generic_translator(text, ELVISH_MAP, ' ')},
'feline': {'name': 'Feline', 'translate': lambda text: generic_translator(text, FELINE_MAP, ' ')},
'fiendish': {'name': 'Fiendish', 'translate': lambda text: generic_translator(text, FIENDISH_MAP, ' ')},
'gnomish': {'name': 'Gnomish', 'translate': lambda text: generic_translator(text, GNOMISH_MAP, ' ')},
'goblin': {'name': 'Goblin', 'translate': lambda text: generic_translator(text, GOBLIN_MAP, ' ')},
'halftongue': {'name': 'Half-Tongue', 'translate': lambda text: generic_translator(text, HALFTONGUE_MAP, ' ')},
'herbilore': {'name': 'Herbilore', 'translate': lambda text: generic_translator(text, HERBILORE_MAP, ' ')},
'infernal': {'name': 'Infernal', 'translate': lambda text: generic_translator(text, INFERNAL_MAP, ' ')},
'kitsune': {'name': 'Kitsune', 'translate': lambda text: generic_translator(text, KITSUNE_MAP, '')},
'leet': {'name': 'Leet Speak', 'translate': lambda text: generic_translator(text, LEET_MAP, '')},
'lizardfolk': {'name': 'Lizardfolk', 'translate': lambda text: generic_translator(text, LIZARDFOLK_MAP, ' ')},
'morse': {'name': 'Morse Code', 'translate': lambda text: generic_translator(text, MORSE_MAP, ' ')},
'myconid': {'name': 'Myconid', 'translate': lambda text: generic_translator(text, MYCONID_MAP, ' ')},
'ogrish': {'name': 'Ogrish', 'translate': lambda text: generic_translator(text, OGRISH_MAP, ' ')},
'orcish': {'name': 'Orcish', 'translate': lambda text: generic_translator(text, ORCISH_MAP, ' ')},
'ratfolk': {'name': 'Ratfolk', 'translate': lambda text: generic_translator(text, RATFOLK_MAP, ' ')},
'scorpion': {'name': 'Scorpion', 'translate': lambda text: generic_translator(text, SCORPION_MAP, ' ')},
'sinary': {'name': 'Sinary', 'translate': lambda text: generic_translator(text, SINARY_MAP, '')},
'spiritual': {'name': 'Spiritual', 'translate': lambda text: generic_translator(text, SPIRITUAL_MAP, ' ')},
'succubus': {'name': 'Succubus', 'translate': lambda text: generic_translator(text, SUCCUBUS_MAP, ' ')},
'sylvan': {'name': 'Sylvan', 'translate': lambda text: generic_translator(text, SYLVAN_MAP, ' ')},
'undercommon': {'name': 'Undercommon', 'translate': lambda text: generic_translator(text, UNDERCOMMON_MAP, ' ')},
'valspiren': {'name': 'Valspiren', 'translate': lambda text: generic_translator(text, VALSPIREN_MAP, '')},
'voidtouched': {'name': 'Voidtouched', 'translate': lambda text: generic_translator(text, VOIDTOUCHED_MAP, ' ')},
}
async def language_autocomplete(self, interaction: discord.Interaction, current: str) -> list[app_commands.Choice[str]]:
"""Autocomplete for language choices."""
choices = [
app_commands.Choice(name=lang_data['name'], value=lang_key)
for lang_key, lang_data in self.languages.items()
if current.lower() in lang_data['name'].lower()
]
return choices[:25]
@commands.hybrid_command(name="translate", description="Translate text to a selected language.")
@app_commands.describe(
language="The language to translate the text into.",
text="The text to translate."
)
@app_commands.autocomplete(language=language_autocomplete)
async def translate(self, ctx: commands.Context, language: str, *, text: str):
"""
Translates the given text into the specified language.
To see a list of available languages, use the command without specifying a language.
"""
language_key = language.lower()
if language_key not in self.languages:
await ctx.send(f"Sorry, '{language}' is not a valid language. Please choose from the list.", ephemeral=True)
return
translator_func = self.languages[language_key]['translate']
translated_text = translator_func(text)
embed = discord.Embed(
title=f"Translation to {self.languages[language_key]['name']}",
color=discord.Color.blue()
)
embed.add_field(name="Original Text", value=f"```\n{text}\n```", inline=False)
embed.add_field(name="Translated Text", value=f"```\n{translated_text}\n```", inline=False)
await ctx.send(embed=embed)
@commands.hybrid_command(name="languages", description="List all available languages for translation.")
async def list_languages(self, ctx: commands.Context):
"""Provides a list of all available languages."""
sorted_languages = sorted(self.languages.values(), key=lambda x: x['name'])
description = "\n".join([lang['name'] for lang in sorted_languages])
embed = discord.Embed(
title="Available Languages",
description=description,
color=discord.Color.green()
)
await ctx.send(embed=embed)