make the translation file a markdown file (#140)

* make the translation file a markdown file and (blindly) fix the language init script
* Updated formatting of the file to make it easier to read (and look better.)
* Included missing bonuses section
* Also fixed `card_db_dir` to point to the correct directory.

* Added link to Tranlsation instructions

* Updated link to translation.md in README.md
This commit is contained in:
Peter 2017-01-08 10:26:35 -08:00 committed by GitHub
parent 1a1dd9eac8
commit d4e69bc7d3
4 changed files with 607 additions and 518 deletions

View File

@ -8,6 +8,10 @@ This is a script and library to generate card dividers for storing cards for the
Again, to generate tabs go to the ***[Online Generator](http://domtabs.sandflea.org)***. Again, to generate tabs go to the ***[Online Generator](http://domtabs.sandflea.org)***.
## Translations
If you would like to help with translations to new (or updating existing) languages, please see [instructions here] (https://github.com/sumpfork/dominiontabs/blob/master/domdiv/card_db/translation.md).
## Prerequisites ## Prerequisites
#### Python Packages #### Python Packages

View File

@ -0,0 +1,180 @@
# Translation Instructions
## File Format
/card_db/
xx/
bonuses_xx.json
cards_xx.json
sets_xx.json
types_xx.json
where xx is ISO 639-1 standard language code in lower case with under bar '_' replacing dash '-'
Please rename the directory and the files to match the language you are providing.
## Character encoding
The files:
bonuses_xx.json
cards_xx.json
sets_xx.json
types_xx.json
must be encoded in ISO 8859-15, also known as "Latin alphabet no. 9"
This character set is used throughout the Americas, Western Europe, Oceania, and much of Africa.
It is also commonly used in most standard romanizations of East-Asian languages.
If you have a language that is not supported by ISO 8859-15 please contact the developers.
## Anatomy of sets_xx.json
Entries in this file represent Dominion sets/expansions. A typical entry looks like:
"alchemy": {
"set_name": "Alchimia",
"text_icon": "Al"
},
- The set key word (e.g., `alchemy` for the above entry) MUST NOT BE CHANGED. This value is used to identify the translation entry.
- The key word `set_name` MUST NOT BE CHANGED, but the value after the `:` should be changed to the name of the set in the target language.
- The key word `text_icon` MUST NOT BE CHANGED, but the value after the `:` should be a one or two letter identifier to be used by the set if the set graphics are not displayed. This is usually the first letter of the set name in the target language.
- Do not change any punctuation outside of the quotes `"`. For example, brackets `{` or `}`, colons `:`, quotes `"` or commas `,`.
## Anatomy of bonuses_xx.json
Entries in this file represent Dominion bonuses. A typical entry looks like:
"exclude": [
"token",
"Tokens"
],
"include": [
"Coins",
"Coin",
"Cards",
"Card",
"Buys",
"Buy",
"Actions",
"Action",
"<VP>"
]
The items in the `include` list are items that will be marked **bold** (i.e., `<b>..</b>`)
when found in the card text in the following format:
`+# item_from_include_list`
as long as this is not followed by a item from the `exclude` list.
For example in English:
`+2 Buys` will be made bold, but
`+1 Action token` will not, since the key word token follows.
- Just replace the English terms with the terms used in the target language.
- Generally you should include the singular as well as the plural version of the term.
- English versions do not need to be duplicated, since they are used automatically.
- The key words `exclude` and `include` MUST NOT BE CHANGED.
- Do not change any punctuation outside of the quotes `"`. For example, brackets `{` or `}`, colons `:`, quotes `"` or commas `,`.
## Anatomy of types_xx.json
Entries in this file represent Dominion card types. A typical entry looks like:
"Action": "Action in new language",
- The type key word (i.e., the `Action` for the above entry) MUST NOT BE CHANGED. This value is used to identify the translation entry.
- Do not change any punctuation outside of the quotes `"`. For example, brackets `{` or `}`, colons `:`, quotes `"` or commas `,`.
## Anatomy of cards_xx.json
Entries in this file represent Dominion cards, and groups of cards. A typical entry looks like:
"Gold": {
"description": "Worth 3 Coins.",
"extra": "30 cards per game.",
"name": "Gold",
"untranslated" : "description, extra, name"
},
- The card key word (e.g., `Gold` for the above entry) MUST NOT BE CHANGED. This value is used to identify the translation entry.
- The key word `name` MUST NOT BE CHANGED, but the value after the `:` should be changed to the name of the card in the target language.
- The key word `description` MUST NOT BE CHANGED, but the value after the `:` should be changed to the card text in the target language.
- The key word `extra` MUST NOT BE CHANGED, but the value after the `:` should be changed to any extra rules or explanations for the card in the target language. If you purposely want no extra text, enter `""`.
- The key word `untranslated` MUST NOT BE CHANGED, but the value after the `:` should be changed. Removed any key word for which you have provided a translation.
For example:
- if you provided the `name` of the card, and only the `name`, then change to `description, extra`
- if you provided the `name` of the card and it's `description`, but have not translated the `extra`, then change to `extra`
- if you provided all 3 entries, then change to `""`
The "untranslated" entry is used during maintanance of the language files to update any remaining default language entries that might have changed.
## Special Text
These character sequences have special meaning in the "description" and "extra" text:
- `<b>` ... `</b>` for **bold**
- `<i>` ... `</i>` for *italics*
- `<u>` ... `</u>` for underline
- `<tab>` and `<t>` and `\t` to add a tab (4 spaces)
- `<n>` and `\n` for a "hard new line"
- `<br>` and `<br/>` and `<br />` for a "soft new line"
- `<c>` and `<center>` add hard new line and center text until the next hard new line
- `<l>` and `<left>` add hard new line and left align text until the next hard new line
- `<r>` and `<right>` add hard new line and right align text until the next hard new line
- `<j>` and `<justify>` add hard new line and justify align text until the next hard new line
- `<line>` to add a hard new line, a centered dividing line, and a trailing hard new line
Hard new lines (`\n` and `<n>`), will reset the paragraph formatting back to the default.
Soft new lines will insert a new line, but will continue the current formatting.
The `description` will be default to "center" text.
The `extra` will default to "justify" text.
## Special Images
Special character sequences are recognized by the program to substitute graphics in the text. These include:
- `<VP>` and ` VP ` for a Victory Point graphic
- `Potion` for a small Potion graphic
- `# Coin` where # is a number 0 - 13, a question mark `?`, `_`, or the letters `empty` for a small coin graphic with the # on top
- `# Coins` where # is a number 0 - 13, a question mark `?`, `_`, or the letters `empty` for a small coin graphic with the # on top
- `# coin` where # is a number 0 - 13, a question mark `?`, `_`, or the letters `empty` for a small coin graphic with the # on top
- `# coins` where # is a number 0 - 13, a question mark `?`, `_`, or the letters `empty` for a small coin graphic with the # on top
- `# <*COIN*>` where # is a number 0 - 13, will produce a large coin graphic with the # on top
- `# <*VP*>` where # is a number, will produce a large Victory Point graphic with the # before it
- `# <*POTION*>` where # is a number, will produce a large Potion graphic with the # before it
For example:
- the text `1 coin` would produce a graphic of a coin with the number 1 on top.
- the text `empty coin` and `_ coin` would produce a graphic of only a coin.
IMPORTANT: To keep the special images, please do not translate any of the above Special character sequences into the target language.
## Style Guide
- If bonuses_xx.json for the target language is configured correctly, bonuses within the text will automatically be bolded.
In English, it will not bold the text if it is followed by `token` or `Token`. Example:
`Choose one: +3 Cards; or +2 Actions.` will bold `+3 Cards` and `+2 Actions`.
- Bonuses should be listed in the following order:
* `+ Cards`,
* `+ Actions`,
* `+ Buys`,
* `+ Coins`,
* `+ <VP>`
- When possible, bonuses should be listed vertically and centered. Examples:
* `+1 Card<br>+1 Action<br>+1 Buy<br>+1 Coin<br>+2 <VP><n>`
* `+1 Card\n+1 Action\n+1 Buy\n+1 Coin\n+2 <VP>\n`
The `description` field by default is centered. `<br>`, `<n>`, and `\n` will all provide new lines.
- If a Dividers/Tab has more than one card explanation, if space permits, try to mimic a stand alone Dividers/Tab in the overall format. Example from "Settlers - Bustling Village":
`<left><u>Settlers</u>:<n>+1 Card<br>+1 Action<n>Look through your discard pile.
You may reveal a Copper from it and put it into your hand.<n>
<left><u>Bustling Village</u>:<n><center>+1 Card<br>+3 Actions<n>
Look through your discard pile. You may reveal a Settlers from it and put it into your hand.`

View File

@ -1,138 +0,0 @@
# Translation Instructions
## File Format
/card_db/
xx/
bonuses_xx.json
cards_xx.json
sets_xx.json
types_xx.json
where xx is ISO 639-1 standard language code in lower case with under bar '_' replacing dash '-'
Please rename the directory and the files to match the language you are providing.
## Character encoding
The files:
bonuses_xx.json
cards_xx.json
sets_xx.json
types_xx.json
must be encoded in ISO 8859-15, also known as "Latin alphabet no. 9"
This character set is used throughout the Americas, Western Europe, Oceania, and much of Africa.
It is also commonly used in most standard romanizations of East-Asian languages.
If you have a language that is not supported by ISO 8859-15 please contact the developers.
## Anatomy of sets_xx.json
Entries in this file represent Dominion sets/expansions. A typical entry looks like:
"alchemy": {
"set_name": "Alchimia",
"text_icon": "Al"
},
The set key word (e.g., "alchemy" for the above entry) MUST NOT BE CHANGED. This value is used to identify the translation entry.
The key word "set_name" MUST NOT BE CHANGED, but the value after the : should be changed to the name of the set in the target language.
The key word "text_icon" MUST NOT BE CHANGED, but the value after the : should be a one or two letter identifier to be used by the set if the set graphics are not displayed. This is usually the first letter of the set name in the target language.
Do not change any punctuation outside of the quotes '"'. For example, brackets '{' or '}', colons ':', quotes '"' or commas ','.
## Anatomy of bonuses_xx.json
Entries in this file represent Dominion bonuses. The items in the "include" list are items that will be marked bold (i.e., <b>..</b>)
when found in the card text in the following format:
+# item_from_include_list
as long as this is not followed by a item from the "exclude" list.
For example in English:
"+2 Buys" will be made bold, but
"+1 Action token" will not, since the key word token follows.
Just replace the English terms with the terms used in the target language.
Generally you should include the singular as well as the plural version of the term.
English versions do not need to be duplicated, since they are used automatically.
The key words "exclude" and "include" MUST NOT BE CHANGED.
Do not change any punctuation outside of the quotes '"'. For example, brackets '{' or '}', colons ':', quotes '"' or commas ','.
## Anatomy of types_xx.json
Entries in this file represent Dominion card types. A typical entry looks like:
"Action": "Action in new language",
The type key word (i.e., the "Action": for the above entry) MUST NOT BE CHANGED. This value is used to identify the translation entry.
Do not change any punctuation outside of the quotes '"'. For example, brackets '{' or '}', colons ':', quotes '"' or commas ','.
## Anatomy of cards_xx.json
Entries in this file represent Dominion cards, and groups of cards. A typical entry looks like:
"Gold": {
"description": "Worth 3 Coins.",
"extra": "30 cards per game.",
"name": "Gold",
"untranslated" : "description, extra, name"
},
The card key word (e.g., "Gold": for the above entry) MUST NOT BE CHANGED. This value is used to identify the translation entry.
The key word "name" MUST NOT BE CHANGED, but the value after the : should be changed to the name of the card in the target language.
The key word "description" MUST NOT BE CHANGED, but the value after the : should be changed to the card text in the target language.
The key word "extra" MUST NOT BE CHANGED, but the value after the : should be changed to any extra rules or explanations for the card in the target language. If you purposely want no extra text, enter "".
The key word "untranslated" MUST NOT BE CHANGED, but the value after the : should be changed. Removed any key word for which you have provided a translation.
For example:
- if you provided the "name" of the card, and only the "name", then change to "description, extra"
- if you provided the "name" of the card and it's "description", but have not translated the "extra", then change to "extra"
- if you provided all 3 entries, then change to ""
The "untranslated" entry is used during maintanance of the language files to update any remaining default language entries that might have changed.
## Special Text
These character sequences have special meaning in the "description" and "extra" text:
'<b>' ... '</b>' for bold
'<i>' ... '</i>' for italics
'<u>' ... '</u>' for underline
'<tab>' and '<t>' and '\t' to add a tab (4 spaces)
'<n>' and '\n' for a "hard new line"
'<br>' and '<br/>' and '<br />' for a "soft new line"
'<c>' and '<center>' add hard new line and center text until the next hard new line
'<l>' and '<left>' add hard new line and left align text until the next hard new line
'<r>' and '<right>' add hard new line and right align text until the next hard new line
'<j>' and '<justify>' add hard new line and justify align text until the next hard new line
'<line>' to add a hard new line, a centered dividing line, and a trailing hard new line
Hard new lines ('\n' and '<n>'), will reset the paragraph formatting back to the default.
Soft new lines will insert a new line, but will continue the current formatting.
The "description" will be default to "center" text.
The "extra" will default to "justify" text.
## Special Images
Special character sequences are recognized by the program to substitute graphics in the text. These include:
'<VP>' and ' VP ' for a Victory Point graphic
'Potion' for a small Potion graphic
'# Coin' where # is a number 0 - 13, a question mark '?', '_', or the letters 'empty' for a small coin graphic with the # on top
'# Coins' where # is a number 0 - 13, a question mark '?', '_', or the letters 'empty' for a small coin graphic with the # on top
'# coin' where # is a number 0 - 13, a question mark '?', '_', or the letters 'empty' for a small coin graphic with the # on top
'# coins' where # is a number 0 - 13, a question mark '?', '_', or the letters 'empty' for a small coin graphic with the # on top
For example:
- the text '1 coin' would produce a graphic of a coin with the number 1 on top.
- the text 'empty coin' and '_ coin' would produce a graphic of only a coin.
'# <*COIN*>' where # is a number 0 - 13, will produce a large coin graphic with the # on top
'# <*VP*>' where # is a number, will produce a large Victory Point graphic with the # before it
'# <*POTION*>' where # is a number, will produce a large Potion graphic with the # before it
To keep the special images, please do not translate '<VP>', 'Potion', or the 'coin' variations into the target language.
## Style Guide
- If bonuses_xx.json for the target language is configured correctly, bonuses within the text will automatically be bolded.
It will not bold the text if it is followed by 'token' or 'Token'.
Example: "Choose one: +3 Cards; or +2 Actions." will bold '+3 Cards' and '+2 Actions'.
- Bonuses should be listed in the following order:
+Cards, +Actions, +Buys, +Coins, then +<VP>
- When possible, bonuses should be listed vertically and centered.
Examples: "+1 Card<br>+1 Action<br>+1 Buy<br>+1 Coin<br>+2 <VP><n>"
"+1 Card\n+1 Action\n+1 Buy\n+1 Coin\n+2 <VP>\n"
The "description" field by default is centered. '<br>', '<n>', and '\n' will all provide new lines.
- If a Dividers/Tab has more than one card explanation, if space permits, try to mimic a stand alone Dividers/Tab in the overall format.
Example from "Settlers - Bustling Village": "<left><u>Settlers</u>:<n>+1 Card<br>+1 Action<n>Look through your discard pile. You may reveal a Copper from it and put it into your hand.<n><left><u>Bustling Village</u>:<n><center>+1 Card<br>+3 Actions<n>Look through your discard pile. You may reveal a Settlers from it and put it into your hand."

View File

@ -1,380 +1,423 @@
########################################################################### ###########################################################################
# This file provides maintenance on the various language files # This file provides maintenance on the various language files
# 1. Create new "xx/cards_xx.json" files that have entries ordered as: # 1. Create new "xx/cards_xx.json" files that have entries ordered as:
# a. the card_tag entries in "cards_db.json" # a. the card_tag entries in "cards_db.json"
# b. the group_tag entries as found in "cards_db.json" # b. the group_tag entries as found in "cards_db.json"
# c. the super group entries (grouping across all expansions" # c. the super group entries (grouping across all expansions"
# d. any unused entries existing in the file (assumed to be work in progress) # d. any unused entries existing in the file (assumed to be work in progress)
# #
# 2. Create new "sets_db.json" and "xx/cards_xx.json" with entries sorted alphabetically # 2. Create new "sets_db.json" and "xx/cards_xx.json" with entries sorted alphabetically
# #
# All output is in the designated output directory. Original files are not overwritten. # All output is in the designated output directory. Original files are not overwritten.
########################################################################### ###########################################################################
import os import os
import io import io
import codecs import codecs
import json import json
from shutil import copyfile from shutil import copyfile
LANGUAGE_DEFAULT = 'en_us' # default language, which takes priority
LANGUAGE_DEFAULT = 'en_us' # default language, which takes priority LANGUAGE_XX = 'xx' # language for starting a translation
LANGUAGE_XX = 'xx' # language for starting a translation card_db_dir = os.path.join("..", "domdiv", "card_db") # directory of card data
card_db_dir = os.path.join("..", "card_db") # directory of card data output_dir = os.path.join(".", "card_db") # directory for output data
output_dir = os.path.join(".", "card_db") # directory for output data
def get_lang_dirs(path):
def get_lang_dirs(path): # Find all valid languages.
# Find all valid languages. languages = []
languages = [] for name in os.listdir(path):
for name in os.listdir(path): dir_path = os.path.join(path, name)
dir_path = os.path.join(path, name) if os.path.isdir(dir_path):
if os.path.isdir(dir_path): cards_file = os.path.join(dir_path, "cards_" + name + ".json")
cards_file = os.path.join(dir_path, "cards_" + name + ".json") sets_file = os.path.join(dir_path, "sets_" + name + ".json")
sets_file = os.path.join(dir_path, "sets_" + name + ".json") if os.path.isfile(cards_file) and os.path.isfile(sets_file):
if os.path.isfile(cards_file) and os.path.isfile(sets_file): languages.append(name)
languages.append(name) return languages
return languages
def get_json_data(json_file_path):
def get_json_data(json_file_path): # Read in the json from the specified file
# Read in the json from the specified file with codecs.open(json_file_path, 'r', 'utf-8') as json_file:
with codecs.open(json_file_path, 'r', 'utf-8') as json_file: data = json.load(json_file)
data = json.load(json_file) assert data, "Could not load json at: '%r' " % json_file_path
assert data, "Could not load json at: '%r' " % json_file_path return data
return data
def json_dict_entry(entry, separator=''):
def json_dict_entry(entry, separator=''): # Return a nicely formated json dict entry.
# Return a nicely formated json dict entry. # It does not include the enclosing {} and removes trailing white space
# It does not include the enclosing {} and removes trailing white space json_data = json.dumps(entry, indent=4, ensure_ascii=False, sort_keys=True)
json_data = json.dumps(entry, indent=4, ensure_ascii=False, sort_keys=True) json_data = json_data.strip(
json_data = json_data.strip('{}').rstrip() # Remove outer{} and then trailing whitespace '{}').rstrip() # Remove outer{} and then trailing whitespace
return separator + json_data return separator + json_data
# Multikey sort
# see: http://stackoverflow.com/questions/1143671/python-sorting-list-of-dictionaries-by-multiple-keys # Multikey sort
def multikeysort(items, columns): # see: http://stackoverflow.com/questions/1143671/python-sorting-list-of-dictionaries-by-multiple-keys
from operator import itemgetter def multikeysort(items, columns):
comparers = [((itemgetter(col[1:].strip()), -1) if col.startswith('-') else from operator import itemgetter
(itemgetter(col.strip()), 1)) for col in columns] comparers = [((itemgetter(col[1:].strip()), -1)
def comparer(left, right): if col.startswith('-') else (itemgetter(col.strip()), 1))
for fn, mult in comparers: for col in columns]
result = cmp(fn(left), fn(right))
if result: def comparer(left, right):
return mult * result for fn, mult in comparers:
else: result = cmp(fn(left), fn(right))
return 0 if result:
return sorted(items, cmp=comparer) return mult * result
else:
########################################################################### return 0
# Get all the languages, and place the default language first in the list
########################################################################### return sorted(items, cmp=comparer)
languages = get_lang_dirs(card_db_dir)
languages.remove(LANGUAGE_DEFAULT)
languages.insert(0, LANGUAGE_DEFAULT) ###########################################################################
if LANGUAGE_XX not in languages: # Get all the languages, and place the default language first in the list
languages.append(LANGUAGE_XX) ###########################################################################
print "Languages:" languages = get_lang_dirs(card_db_dir)
print languages languages.remove(LANGUAGE_DEFAULT)
print languages.insert(0, LANGUAGE_DEFAULT)
if LANGUAGE_XX not in languages:
languages.append(LANGUAGE_XX)
########################################################################### print "Languages:"
# Make sure the directories exist to hold the output print languages
########################################################################### print
# main output directory ###########################################################################
if not os.path.exists(output_dir): # Make sure the directories exist to hold the output
os.makedirs(output_dir) ###########################################################################
# each language directory # main output directory
for lang in languages: if not os.path.exists(output_dir):
# Make sure the directory is there to hold the file os.makedirs(output_dir)
lang_dir = os.path.join(output_dir,lang)
if not os.path.exists(lang_dir): # each language directory
os.makedirs(lang_dir) for lang in languages:
# Make sure the directory is there to hold the file
lang_dir = os.path.join(output_dir, lang)
########################################################################### if not os.path.exists(lang_dir):
# Get the types_db information os.makedirs(lang_dir)
# Store in a list in the order found in types[]. Ordered by card_type
# 1. card_tags, 2. group_tags, 3. super groups ###########################################################################
########################################################################### # Get the types_db information
types = [] # Store in a list in the order found in types[]. Ordered by card_type
type_parts = [] # 1. card_tags, 2. group_tags, 3. super groups
###########################################################################
# Get the card data types = []
type_data = get_json_data(os.path.join(card_db_dir, "types_db.json")) type_parts = []
# Sort the cards by cardset_tags, then card_tag # Get the card data
sorted_type_data = multikeysort(type_data, ['card_type']) type_data = get_json_data(os.path.join(card_db_dir, "types_db.json"))
with io.open(os.path.join(output_dir, "types_db.json"), 'w', encoding='utf-8') as lang_out: # Sort the cards by cardset_tags, then card_tag
lang_out.write(unicode("[")) # Start of list sorted_type_data = multikeysort(type_data, ['card_type'])
sep = ""
for type in sorted_type_data: with io.open(
# Collect all the individual types os.path.join(output_dir, "types_db.json"), 'w',
type_parts = list(set(type['card_type']) | set(type_parts)) encoding='utf-8') as lang_out:
lang_out.write(sep + json.dumps(type, indent=4, ensure_ascii=False, sort_keys=True)) lang_out.write(unicode("[")) # Start of list
sep = "," sep = ""
lang_out.write(unicode("\n]\n")) # End of List for type in sorted_type_data:
# Collect all the individual types
type_parts.sort() type_parts = list(set(type['card_type']) | set(type_parts))
print "Unique Types:" lang_out.write(sep + json.dumps(
print type_parts type, indent=4, ensure_ascii=False, sort_keys=True))
print sep = ","
lang_out.write(unicode("\n]\n")) # End of List
########################################################################### type_parts.sort()
# Fix up all the xx/types_xx.json files print "Unique Types:"
# Place entries in alphabetical order print type_parts
# If entries don't exist: print
# If the default language, set from information in the "types_db.json" file,
# If not the default language, set based on information from the default language. ###########################################################################
# Lastly, keep any extra entries that are not currently used, just in case needed # Fix up all the xx/types_xx.json files
# in the future or is a work in progress. # Place entries in alphabetical order
########################################################################### # If entries don't exist:
for lang in languages: # If the default language, set from information in the "types_db.json" file,
lang_file = "types_" + lang + ".json" # If not the default language, set based on information from the default language.
fname = os.path.join(card_db_dir, lang, lang_file) # Lastly, keep any extra entries that are not currently used, just in case needed
if os.path.isfile(fname): # in the future or is a work in progress.
lang_type_data = get_json_data(fname) ###########################################################################
else: for lang in languages:
lang_type_data = {} lang_file = "types_" + lang + ".json"
fname = os.path.join(card_db_dir, lang, lang_file)
with io.open( os.path.join(output_dir, lang, lang_file), 'w',encoding='utf-8') as lang_out: if os.path.isfile(fname):
lang_out.write(unicode("{")) # Start of types lang_type_data = get_json_data(fname)
sep = "" else:
used = [] lang_type_data = {}
for type in sorted(type_parts): with io.open(
if type not in lang_type_data: os.path.join(output_dir, lang, lang_file), 'w',
if lang == LANGUAGE_DEFAULT: encoding='utf-8') as lang_out:
lang_type_data[type] = type lang_out.write(unicode("{")) # Start of types
else: sep = ""
lang_type_data[type] = lang_type_default[type] used = []
lang_out.write(json_dict_entry({type:lang_type_data[type]}, sep)) for type in sorted(type_parts):
used.append(type) if type not in lang_type_data:
sep = "," if lang == LANGUAGE_DEFAULT:
lang_type_data[type] = type
# Now keep any unused values just in case needed in the future lang_type_default = lang_type_data
for key in lang_type_data: else:
if key not in used: lang_type_data[type] = lang_type_default[type]
lang_out.write(json_dict_entry({key:lang_type_data[key]}, sep))
sep = "," lang_out.write(json_dict_entry({type: lang_type_data[type]}, sep))
used.append(type)
lang_out.write(unicode("\n}\n")) # End of Types sep = ","
if lang == LANGUAGE_DEFAULT: # Now keep any unused values just in case needed in the future
lang_type_default = lang_type_data # Keep for later languages for key in lang_type_data:
if key not in used:
lang_out.write(
########################################################################### json_dict_entry({
# Get the cards_db information key: lang_type_data[key]
# Store in a list in the order found in cards[]. Ordered as follows: }, sep))
# 1. card_tags, 2. group_tags, 3. super groups sep = ","
###########################################################################
cards = [] lang_out.write(unicode("\n}\n")) # End of Types
groups = []
super_groups = [u'events', u'landmarks'] if lang == LANGUAGE_DEFAULT:
lang_type_default = lang_type_data # Keep for later languages
# Get the card data
card_data = get_json_data(os.path.join(card_db_dir, "cards_db.json")) ###########################################################################
# Get the cards_db information
# Sort the cardset_tags # Store in a list in the order found in cards[]. Ordered as follows:
for card in card_data: # 1. card_tags, 2. group_tags, 3. super groups
card["cardset_tags"].sort() ###########################################################################
# But put all the base cards together by moving to front of the list cards = []
if 'base' in card["cardset_tags"]: groups = []
card["cardset_tags"].remove('base') super_groups = [u'events', u'landmarks']
card["cardset_tags"].insert(0, 'base')
# Get the card data
# Sort the cards by cardset_tags, then card_tag card_data = get_json_data(os.path.join(card_db_dir, "cards_db.json"))
sorted_card_data = multikeysort(card_data, ['cardset_tags', 'card_tag'])
# Sort the cardset_tags
with io.open(os.path.join(output_dir, "cards_db.json"), 'w', encoding='utf-8') as lang_out: for card in card_data:
lang_out.write(unicode("[")) # Start of list card["cardset_tags"].sort()
sep = "" # But put all the base cards together by moving to front of the list
for card in sorted_card_data: if 'base' in card["cardset_tags"]:
if card['card_tag'] not in cards: card["cardset_tags"].remove('base')
cards.append(card['card_tag']) card["cardset_tags"].insert(0, 'base')
if 'group_tag' in card:
if card['group_tag'] not in groups: # Sort the cards by cardset_tags, then card_tag
groups.append(card['group_tag']) sorted_card_data = multikeysort(card_data, ['cardset_tags', 'card_tag'])
lang_out.write(sep + json.dumps(card, indent=4, ensure_ascii=False, sort_keys=True))
sep = "," with io.open(
lang_out.write(unicode("\n]\n")) # End of List os.path.join(output_dir, "cards_db.json"), 'w',
encoding='utf-8') as lang_out:
cards.extend(groups) lang_out.write(unicode("[")) # Start of list
cards.extend(super_groups) sep = ""
for card in sorted_card_data:
print "Cards:" if card['card_tag'] not in cards:
print cards cards.append(card['card_tag'])
print if 'group_tag' in card:
if card['group_tag'] not in groups:
########################################################################### groups.append(card['group_tag'])
# Fix up all the cards_xx.json files lang_out.write(sep + json.dumps(
# Place entries in the same order as given in "cards_db.json". card, indent=4, ensure_ascii=False, sort_keys=True))
# If entries don't exist: sep = ","
# If the default language, set base on information in the "cards_db.json" file, lang_out.write(unicode("\n]\n")) # End of List
# If not the default language, set based on information from the default language.
# Lastly, keep any extra entries that are not currently used, just in case needed cards.extend(groups)
# in the future or is a work in progress. cards.extend(super_groups)
###########################################################################
for lang in languages: print "Cards:"
print cards
# contruct the cards json file name print
lang_file = "cards_" + lang + ".json"
fname = os.path.join(card_db_dir, lang, lang_file) ###########################################################################
if os.path.isfile(fname): # Fix up all the cards_xx.json files
lang_data = get_json_data(fname) # Place entries in the same order as given in "cards_db.json".
else: # If entries don't exist:
lang_data = {} # If the default language, set base on information in the "cards_db.json" file,
# If not the default language, set based on information from the default language.
# Process the file # Lastly, keep any extra entries that are not currently used, just in case needed
with io.open(os.path.join(output_dir, lang, lang_file), 'w', encoding='utf-8') as lang_out: # in the future or is a work in progress.
lang_out.write(unicode("{")) # Start of set ###########################################################################
sep = "" for lang in languages:
fields = [u"description", u"extra", u"name"]
# contruct the cards json file name
for card in cards: lang_file = "cards_" + lang + ".json"
if card not in lang_data or lang == LANGUAGE_XX: fname = os.path.join(card_db_dir, lang, lang_file)
# Card is missing, need to add it if os.path.isfile(fname):
lang_data[card] = {} lang_data = get_json_data(fname)
if lang == LANGUAGE_DEFAULT: else:
# Default language gets bare minimum. Really need to add by hand. lang_data = {}
lang_data[card]["extra"] = ""
lang_data[card]["name"] = card # Process the file
lang_data[card]["description"] = "" with io.open(
lang_data[card]["untranslated"] = ', '.join(fields) os.path.join(output_dir, lang, lang_file), 'w',
else: encoding='utf-8') as lang_out:
# All other languages should get the default languages' text lang_out.write(unicode("{")) # Start of set
lang_data[card]["extra"] = lang_default[card]["extra"] sep = ""
lang_data[card]["name"] = lang_default[card]["name"] fields = [u"description", u"extra", u"name"]
lang_data[card]["description"] = lang_default[card]["description"]
lang_data[card]["untranslated"] = ', '.join(fields) for card in cards:
else: if card not in lang_data or lang == LANGUAGE_XX:
# Card exists, figure out what needs updating (don't update default language) # Card is missing, need to add it
if lang != LANGUAGE_DEFAULT: lang_data[card] = {}
if 'untranslated' in lang_data[card]: if lang == LANGUAGE_DEFAULT:
# Has an 'untranslated' field. Process accordingly # Default language gets bare minimum. Really need to add by hand.
if not lang_data[card]["untranslated"].strip(): lang_data[card]["extra"] = ""
# It is empty, so just remove it lang_data[card]["name"] = card
del lang_data[card]["untranslated"] lang_data[card]["description"] = ""
else: lang_data[card]["untranslated"] = ', '.join(fields)
# If a field remains untranslated, then replace with the default languages copy lang_default = lang_data
for field in fields: else:
if field in lang_data[card]['untranslated']: # All other languages should get the default languages' text
lang_data[card][field] = lang_default[card][field] lang_data[card]["extra"] = lang_default[card]["extra"]
else: lang_data[card]["name"] = lang_default[card]["name"]
# Need to create the 'untranslated' field and update based upon existing fields lang_data[card]["description"] = lang_default[card][
untranslated = [] "description"]
for field in fields: lang_data[card]["untranslated"] = ', '.join(fields)
if field not in lang_data[card]: else:
lang_data[card][field] = lang_default[card][field] # Card exists, figure out what needs updating (don't update default language)
untranslated.append(field) if lang != LANGUAGE_DEFAULT:
if untranslated: if 'untranslated' in lang_data[card]:
# only add if something is still needing translation # Has an 'untranslated' field. Process accordingly
lang_data[card]["untranslated"] = ', '.join(untranslated) if not lang_data[card]["untranslated"].strip():
# It is empty, so just remove it
lang_out.write(json_dict_entry({card:lang_data[card]}, sep)) del lang_data[card]["untranslated"]
lang_data[card]['used'] = True else:
sep = "," # If a field remains untranslated, then replace with the default languages copy
for field in fields:
# Now keep any unused values just in case needed in the future if field in lang_data[card]['untranslated']:
for key in lang_data: lang_data[card][field] = lang_default[
if 'used' not in lang_data[key]: card][field]
lang_data[key]["untranslated"] = "Note: This card is currently not used." else:
lang_out.write(json_dict_entry({key:lang_data[key]}, sep)) # Need to create the 'untranslated' field and update based upon existing fields
sep = "," untranslated = []
lang_out.write(unicode("\n}\n")) # End of Set for field in fields:
if field not in lang_data[card]:
if lang == LANGUAGE_DEFAULT: lang_data[card][field] = lang_default[card][
lang_default = lang_data # Keep for later languages field]
untranslated.append(field)
if untranslated:
########################################################################### # only add if something is still needing translation
# Fix up the sets_db.json file lang_data[card]["untranslated"] = ', '.join(
# Place entries in alphabetical order untranslated)
###########################################################################
lang_file = "sets_db.json" lang_out.write(json_dict_entry({card: lang_data[card]}, sep))
set_data = get_json_data(os.path.join(card_db_dir, lang_file)) lang_data[card]['used'] = True
sep = ","
with io.open( os.path.join(output_dir, lang_file), 'w',encoding='utf-8') as lang_out:
lang_out.write(unicode("{")) # Start of set # Now keep any unused values just in case needed in the future
sep = "" for key in lang_data:
sets = [] if 'used' not in lang_data[key]:
for set in sorted(set_data): lang_data[key][
lang_out.write(json_dict_entry({set:set_data[set]}, sep)) "untranslated"] = "Note: This card is currently not used."
sep = "," lang_out.write(json_dict_entry({key: lang_data[key]}, sep))
if set not in sets: sep = ","
sets.append(set) lang_out.write(unicode("\n}\n")) # End of Set
lang_out.write(unicode("\n}\n")) # End of Set if lang == LANGUAGE_DEFAULT:
lang_default = lang_data # Keep for later languages
print "Sets:"
print sets ###########################################################################
print # Fix up the sets_db.json file
# Place entries in alphabetical order
###########################################################################
########################################################################### lang_file = "sets_db.json"
# Fix up all the xx/sets_xx.json files set_data = get_json_data(os.path.join(card_db_dir, lang_file))
# Place entries in alphabetical order
# If entries don't exist: with io.open(
# If the default language, set from information in the "sets_db.json" file, os.path.join(output_dir, lang_file), 'w',
# If not the default language, set based on information from the default language. encoding='utf-8') as lang_out:
# Lastly, keep any extra entries that are not currently used, just in case needed lang_out.write(unicode("{")) # Start of set
# in the future or is a work in progress. sep = ""
########################################################################### sets = []
for lang in languages: for set in sorted(set_data):
lang_file = "sets_" + lang + ".json" lang_out.write(json_dict_entry({set: set_data[set]}, sep))
fname = os.path.join(card_db_dir, lang, lang_file) sep = ","
if os.path.isfile(fname): if set not in sets:
lang_set_data = get_json_data(fname) sets.append(set)
else:
lang_set_data = {} lang_out.write(unicode("\n}\n")) # End of Set
with io.open( os.path.join(output_dir, lang, lang_file), 'w',encoding='utf-8') as lang_out: print "Sets:"
lang_out.write(unicode("{")) # Start of set print sets
sep = "" print
for set in sorted(set_data): ###########################################################################
if set not in lang_set_data: # Fix up all the xx/sets_xx.json files
lang_set_data[set] = {} # Place entries in alphabetical order
if lang == LANGUAGE_DEFAULT: # If entries don't exist:
lang_set_data[set]["set_name"] = set.title() # If the default language, set from information in the "sets_db.json" file,
lang_set_data[set]["text_icon"] = set_data[set]["text_icon"] # If not the default language, set based on information from the default language.
if 'short_name' in set_data[set]: # Lastly, keep any extra entries that are not currently used, just in case needed
lang_set_data[set]["short_name"] = set_data[set]["short_name"] # in the future or is a work in progress.
else: ###########################################################################
lang_set_data[set]["set_name"] = lang_default[set]["set_name"] for lang in languages:
lang_set_data[set]["text_icon"] = lang_default[set]["text_icon"] lang_file = "sets_" + lang + ".json"
if 'short_name' in lang_default[set]: fname = os.path.join(card_db_dir, lang, lang_file)
lang_set_data[set]["short_name"] = lang_default[set]["short_name"] if os.path.isfile(fname):
lang_set_data = get_json_data(fname)
lang_out.write(json_dict_entry({set:lang_set_data[set]}, sep)) else:
lang_set_data[set]['used'] = True lang_set_data = {}
sep = ","
with io.open(
# Now keep any unused values just in case needed in the future os.path.join(output_dir, lang, lang_file), 'w',
for key in lang_set_data: encoding='utf-8') as lang_out:
if 'used' not in lang_set_data[key]: lang_out.write(unicode("{")) # Start of set
lang_out.write(json_dict_entry({key:lang_set_data[key]}, sep)) sep = ""
sep = ","
for set in sorted(set_data):
lang_out.write(unicode("\n}\n")) # End of Set if set not in lang_set_data:
lang_set_data[set] = {}
if lang == LANGUAGE_DEFAULT: if lang == LANGUAGE_DEFAULT:
lang_default = lang_set_data # Keep for later languages lang_set_data[set]["set_name"] = set.title()
lang_set_data[set]["text_icon"] = set_data[set][
########################################################################### "text_icon"]
# translation.txt if 'short_name' in set_data[set]:
########################################################################### lang_set_data[set]["short_name"] = set_data[set][
copyfile(os.path.join(card_db_dir, "translation.txt" ), "short_name"]
os.path.join(output_dir, "translation.txt" )) else:
lang_set_data[set]["set_name"] = lang_default[set][
# Since xx is the starting point for new translations, "set_name"]
# make sure xx has the latest copy of translation.txt lang_set_data[set]["text_icon"] = lang_default[set][
copyfile(os.path.join(card_db_dir, "translation.txt" ), "text_icon"]
os.path.join(output_dir, LANGUAGE_XX, "translation.txt" )) if 'short_name' in lang_default[set]:
lang_set_data[set]["short_name"] = lang_default[set][
"short_name"]
lang_out.write(json_dict_entry({set: lang_set_data[set]}, sep))
lang_set_data[set]['used'] = True
sep = ","
# Now keep any unused values just in case needed in the future
for key in lang_set_data:
if 'used' not in lang_set_data[key]:
lang_out.write(json_dict_entry({key: lang_set_data[key]}, sep))
sep = ","
lang_out.write(unicode("\n}\n")) # End of Set
if lang == LANGUAGE_DEFAULT:
lang_default = lang_set_data # Keep for later languages
###########################################################################
# bonuses_xx files
###########################################################################
for lang in languages:
# Special case for xx. Reseed from default language
fromLanguage = lang
if lang == LANGUAGE_XX:
fromLanguage = LANGUAGE_DEFAULT
copyfile(
os.path.join(card_db_dir, fromLanguage, "bonuses_" + fromLanguage + ".json"),
os.path.join(output_dir, lang, "bonuses_" + lang + ".json"))
###########################################################################
# translation.txt
###########################################################################
copyfile(
os.path.join(card_db_dir, "translation.md"),
os.path.join(output_dir, "translation.md"))
# Since xx is the starting point for new translations,
# make sure xx has the latest copy of translation.md
copyfile(
os.path.join(card_db_dir, "translation.md"),
os.path.join(output_dir, LANGUAGE_XX, "translation.md"))