"""
Meta information about languages.
"""
from collections import namedtuple
import os, re, sys
class LanguageData:
"""
@ivar name: Name of the language in English.
@type name: C{str}
@ivar ownname: Name of the language in the language itself.
@type ownname: C{str}
@ivar isocode: Systematic name of the language.
@type isocode: C{str}
@ivar plural: Plural form number.
@type plural: C{int}
@ivar grflangid: Language id according to the NewGRF system.
@type grflangid: C{int}
@ivar gender: Genders of the language.
@type gender: C{list} of C{str}
@ivar case: Cases of the language.
@type case: C{list} of C{str}
"""
def __init__(self, found_lines):
self.name = found_lines['name']
self.ownname = found_lines['ownname']
self.isocode = found_lines['isocode']
self.plural = found_lines['plural']
self.grflangid = found_lines['grflangid']
gender = found_lines.get('gender')
if gender is None: gender = []
self.gender = gender
case = found_lines.get('case')
if case is None: case = []
if '' not in case: case.append('')
self.case = case
def as_str(text):
return text.strip()
def as_int(text):
if text[:2] in ('0x', '0X'):
return int(text, base=16)
else:
return int(text, base=10)
def as_strlist(text):
return list(set(text.split()))
# Recognized lines in a language file.
LanguageLine = namedtuple('LanguageLine', ['name', 'pattern', 'convert', 'required'])
recognized = [
LanguageLine('name', re.compile('##name +(.*) *$'), as_str, True),
LanguageLine('ownname', re.compile('##ownname +(.*) *$'), as_str, True),
LanguageLine('isocode', re.compile('##isocode +([a-z][a-z]_[A-Z][A-Z]) *$'), as_str, True),
LanguageLine('plural', re.compile('##plural +((0[xX])?[0-9A-Fa-f]+) *$'), as_int, True),
LanguageLine('grflangid', re.compile('##grflangid +((0[xX])?[0-9A-Fa-f]+) *$'), as_int, True),
LanguageLine('gender', re.compile('##gender +(.*) *$'), as_strlist, False),
LanguageLine('case', re.compile('##case +(.*) *$'), as_strlist, False)]
def parse_file(fname):
"""
Parse a language file, collecting the recognized lines.
@param fname: Name of the file to read.
@type fname: C{str}
@return: The found meta-information about a language.
@rtype: C{LanguageData}
"""
handle = open(fname, "rt", encoding="utf-8")
found_lines = {}
for line in handle:
if not line.startswith('##'):
continue
line = line.rstrip()
for ll in recognized:
m = ll.pattern.match(line)
if m:
found_lines[ll.name] = ll.convert(m.group(1))
break
handle.close()
if not all(ll.name in found_lines for ll in recognized if ll.required):
for ll in recognized:
if ll.required and ll.name not in found_lines:
msg = "File \"{}\" is missing required language line ##{} (or it has the wrong format)"
print(msg.format(fname, ll.name))
sys.exit(1)
return LanguageData(found_lines)
def init(path):
"""
Find all text files (".txt" extension) in the tree below L{path}, and load
the meta-language information in them.
@param path: Root of the tree containing language meta-data text files.
@type path: C{str}
"""
global all_languages, grflangid, isocode
all_languages = []
for dirpath, dirnames, filenames in os.walk(path):
for fname in filenames:
if fname.lower().endswith('.txt'):
all_languages.append(parse_file(os.path.join(dirpath, fname)))
grflangid = dict((x.grflangid, x) for x in all_languages)
assert len(all_languages) == len(grflangid)
isocode = dict((x.isocode, x) for x in all_languages)
assert len(all_languages) == len(isocode)