Automatic translation of card names and card information
by mtgrares
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
2 posts
• Page 1 of 1
Automatic translation of card names and card information
by klaxnek » 06 Jul 2019, 15:00
Hi all,
I'm trying to translate card names and info of all the cards into spanish (or other languages automatically using the info from scryfall).
I have done a python script to automatically translate the card info contained in each .txt card file in cardsfolder. zip with the info retrieved from scryfall. I want to translate the following fields: Name, Types and Oracle. Here is the result of abbot_of_keral_keep.txt:
Could you please help me? It would be nice to have automatically translated cards.
Here is the python script I have done (remove the spaces in the url, 1st post here and I cannot post urls...):
I'm trying to translate card names and info of all the cards into spanish (or other languages automatically using the info from scryfall).
I have done a python script to automatically translate the card info contained in each .txt card file in cardsfolder. zip with the info retrieved from scryfall. I want to translate the following fields: Name, Types and Oracle. Here is the result of abbot_of_keral_keep.txt:
- Code: Select all
Name:Abad de la Fortaleza Keral
ManaCost:1 R
Types:Criatura - Monje humano
PT:2/1
K:Prowess
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ When CARDNAME enters the battlefield, exile the top card of your library. Until end of turn, you may play that card.
SVar:TrigMill:DB$ Mill | Defined$ You | NumCards$ 1 | Destination$ Exile | RememberMilled$ True | SubAbility$ DBEffect
SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBCleanup | ExileOnMoved$ Exile
SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play remembered card.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:PlayMain1:ALWAYS
SVar:Picture:...
Oracle:Destreza. (Siempre que lances un hechizo que no sea de criatura, esta criatura obtiene +1/+1 hasta el final del turno.)Cuando el Abad de la Fortaleza Keral entre al campo de batalla, exilia la primera carta de tu biblioteca. Hasta el final del turno, puedes jugar esa carta.
Could you please help me? It would be nice to have automatically translated cards.
Here is the python script I have done (remove the spaces in the url, 1st post here and I cannot post urls...):
- Code: Select all
import urllib.request
import re
import os
def sanitize(text):
# remove initial \n and spaces and final \n
text = text[3:]
text = text.strip()
text = text[:-2]
# replace '
text = text.replace("\\xe2\\x80\\x99", "'")
# replace dash
text = text.replace("\\xe2\\x80\\x94", "-")
# replace ""
text = text.replace("\\xe2\\x80\\x9c", "\"")
text = text.replace("\\xe2\\x80\\x9d", "\"")
# replace ·
text = text.replace("\\xe2\\x80\\xa2", "·")
# remove .
text = text.replace("\\xe2\\x80\\xa8", "·")
# replace ñ
text = text.replace("\\xc3\\xb1", "ny")
# replace accute vowels
text = text.replace("\\xc3\\x81", "A")
text = text.replace("\\xc3\\x89", "E")
text = text.replace("\\xc3\\x8d", "I")
text = text.replace("\\xc3\\x93", "O")
text = text.replace("\\xc3\\x9a", "U")
text = text.replace("\\xc3\\xa1", "a")
text = text.replace("\\xc3\\xa9", "e")
text = text.replace("\\xc3\\xad", "i")
text = text.replace("\\xc3\\xb3", "o")
text = text.replace("\\xc3\\xba", "u")
return text
def remove_abbr(result):
result = re.sub("<abbr.*\">", "", result)
result = result.replace("</abbr>", "")
return result
def extract_title(idx):
found = re.findall(r'class="card-text-title" lang="es">(.*?)</h1>',str(respData))
if not found:
return ""
result = found[idx]
# remove mana cost
result = result.replace("<span class=\"card-text-mana-cost\">", "")
result = result.replace("</span>", "")
result = re.sub("{.*}", "", result)
result = result.replace("\\n", "")
result = remove_abbr(result)
result = sanitize(result + "\\n")
return result
def extract_types(idx):
found = re.findall(r'class="card-text-type-line" lang="es">(.*?)</p>',str(respData))
if not found:
return ""
# remove card symbols
result = remove_abbr(found[idx])
if idx==1:
result = result.replace("\\n", "")
result = result + "\\n"
result = sanitize(result)
return result
def extract_oracle(idx):
found = re.findall(r'class="card-text-oracle">(.*?)</div>',str(respData))
if not found:
return ""
if idx < len(found):
result = sanitize(found[idx])
else:
result = sanitize(found[0])
# remove <p>
result = result.replace("<p>", "")
# remove \n
result = result.replace("\\n", "")
# replace </p> to \n
result = result.replace("</p>", "\\n")
# remove italics
result = result.replace("<i>", "")
result = result.replace("</i>", "")
# remove card symbols
result = remove_abbr(result)
# remove trailing \n
result = result[0:-2]
return result
directory = "cards"
for filename in os.listdir(directory):
if filename.endswith(".txt"):
cardname = filename[0:-4]
cardname = cardname.replace("_", "+")
print(cardname)
url = 'https :// scryfall. com/search?as=grid&order=name&q=' + cardname + '+lang:es'
req = urllib.request.Request(url)
resp = urllib.request.urlopen(req)
respData = resp.read()
fi = open("cards/" + filename)
fo = open("cardstranslated/" + filename, "w")
idx = 0
for line in fi:
if "Name" in line[0:4]:
res = extract_title(idx)
if res=="":
res = line[5:-1]
fo.write("Name:" + res + "\n")
elif "Types" in line[0:5]:
res = extract_types(idx)
if res=="":
res = line[6:-1]
fo.write("Types:" + res + "\n")
elif "Oracle" in line[0:6]:
res = extract_oracle(idx)
if res=="":
res = line[7:-1]
fo.write("Oracle:" + res + "\n")
elif "ALTERNATE" in line:
idx = idx + 1
fo.write(line)
else:
fo.write(line)
fi.close()
fo.close()
Re: Automatic translation of card names and card information
by klaxnek » 09 Jul 2019, 18:43
Hi all,
I've achieved to automatically translate all cards except the name and the card type, because Forge uses them internally. I've changed the script and now I use the offline .json file from Scryfall that contains all the info about All Cards (https: //archive.scryfall. com/json/scryfall-all-cards.json)
The script translates the different Description$ and Oracle text of all the cards into the selected language.
It compares the original text in english with some parts of the translated text if there is a translation available, and it gets the text that have the maximum likelihood with the original. Sometimes it fails with the chosen translation, but I think it works really well.
Here is the script:
Here is the spanish translation of carddata.zip from Forge 1.6.27
Put that file into /res/cardsfolder/
Spanish carddata.zip Forge 1.6.27
https: //drive.google. com/file/d/1bfuRk9MdwzEZ99KF2kA_UEJH8brjOSa_/view?usp=sharing
Image of using Forge with this spanish translation:
https: //drive.google. com/file/d/1VH-XLW2VFWjqm-zD8B9-ElU5R0rvPIA9/view?usp=sharing
PS: Remove the spaces in all the links...
I've achieved to automatically translate all cards except the name and the card type, because Forge uses them internally. I've changed the script and now I use the offline .json file from Scryfall that contains all the info about All Cards (https: //archive.scryfall. com/json/scryfall-all-cards.json)
The script translates the different Description$ and Oracle text of all the cards into the selected language.
It compares the original text in english with some parts of the translated text if there is a translation available, and it gets the text that have the maximum likelihood with the original. Sometimes it fails with the chosen translation, but I think it works really well.
Here is the script:
- Code: Select all
import json
import os
from difflib import SequenceMatcher
def similar(a, b):
return SequenceMatcher(None, a, b).ratio()
database = "scryfall-all-cards.json"
directory = "cards"
translateddirectory = "cardstranslated"
language = 'es'
def sanitize(text):
# replace accute vowels
text = text.replace("Á", "A")
text = text.replace("É", "E")
text = text.replace("Í", "I")
text = text.replace("Ó", "O")
text = text.replace("Ú", "U")
text = text.replace("á", "a")
text = text.replace("é", "e")
text = text.replace("í", "i")
text = text.replace("ó", "o")
text = text.replace("ú", "u")
# replace ñ
text = text.replace("ñ", "ny")
return text
def removenewline(text):
text = text.replace('\n', '\\n')
return text
def removeinitialicon(text):
initial = text.find(': ')
if initial != -1:
text = text[initial+2:]
text = text.lstrip()
return text
with open(database) as json_file:
data = json.load(json_file)
found = False
for folder in ['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', 'upcoming']:
for filename in os.listdir(directory + '/' + folder):
if filename.endswith('.txt'):
fi = open(directory + "/" + folder + "/" + filename)
os.system('mkdir -p ' + translateddirectory + "/" + folder)
fo = open(translateddirectory + "/" + folder + "/" + filename, "w")
line = fi.readline()
name = line[5:-1]
print("Card: " + name)
printed_name = printed_text = ''
found = False
for card in data:
if name == card['name'] and language == card['lang']:
found = True
try:
printed_name = sanitize(card['printed_name'])
except:
pass
try:
printed_text = sanitize(removenewline(card['printed_text']))
except:
pass
# Write Name: without translating
fo.write(line)
for line in fi:
# 1st check if there's no translation => copy file to output
if printed_text == '':
fo.write(line)
# Description$
elif line.rfind("Description$ ") != -1:
line = line[:-1] + ' |'
pieces = line.split('|')
idx = 0
for piece in pieces:
if piece.find("Description$ ") != -1:
# Find Description$ at the end of the line and write it out
init = piece.rfind("Description$ ")
init = init + len("Description$ ")
fo.write(piece[0:init])
# Take the description and replace CARDNAME with the original cardname
descriptionenglish = piece[init:-1]
originalenglish = descriptionenglish
# Found printed_text
if len(printed_text) > 0:
descriptionenglish = descriptionenglish.replace('CARDNAME', printed_name)
ratio = 0
outtext = ''
translated = printed_text.split("\\n")
for t in translated:
if similar(t, descriptionenglish) > ratio:
ratio = similar(t, descriptionenglish)
outtext = t
translated = printed_text.split(":")
for t in translated:
if similar(t, descriptionenglish) > ratio:
ratio = similar(t, descriptionenglish)
outtext = t
translated = printed_text.split(".")
for t in translated:
if similar(t, descriptionenglish) > ratio:
ratio = similar(t, descriptionenglish)
outtext = t
translated = printed_text.split(".|:|\\n")
for t in translated:
if similar(t, descriptionenglish) > ratio:
ratio = similar(t, descriptionenglish)
outtext = t
# Remove initial icons
outtext = outtext.replace('\\n', '')
outtext = removeinitialicon(outtext) + ' '
outtext = sanitize(outtext)
if outtext[0] == ')':
outtext = outtext[1:]
fo.write(outtext)
# Not Description in piece
else:
fo.write(piece)
idx = idx + 1
if idx == len(pieces) - 1:
fo.write('\n')
if idx < len(pieces) - 1:
fo.write('|')
# Oracle
elif line.startswith('Oracle'):
if printed_text!='':
fo.write("Oracle:" + printed_text + "\n")
else:
# Translate
# output = hardcodedtranslations(line)
# output = translate(output)
fo.write(line)
else:
fo.write(line)
fi.close()
fo.close()
- Code: Select all
language = 'es'
Here is the spanish translation of carddata.zip from Forge 1.6.27
Put that file into /res/cardsfolder/
Spanish carddata.zip Forge 1.6.27
https: //drive.google. com/file/d/1bfuRk9MdwzEZ99KF2kA_UEJH8brjOSa_/view?usp=sharing
Image of using Forge with this spanish translation:
https: //drive.google. com/file/d/1VH-XLW2VFWjqm-zD8B9-ElU5R0rvPIA9/view?usp=sharing
PS: Remove the spaces in all the links...
2 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 30 guests