Loading

Paste #pbl35qpli

  1. """
  2. Meta information about languages.
  3. """
  4. from collections import namedtuple
  5. import os, re, sys
  6.  
  7. class LanguageData:
  8.     """
  9.    @ivar name: Name of the language in English.
  10.    @type name: C{str}
  11.  
  12.    @ivar ownname: Name of the language in the language itself.
  13.    @type ownname: C{str}
  14.  
  15.    @ivar isocode: Systematic name of the language.
  16.    @type isocode: C{str}
  17.  
  18.    @ivar plural: Plural form number.
  19.    @type plural: C{int}
  20.  
  21.    @ivar grflangid: Language id according to the NewGRF system.
  22.    @type grflangid: C{int}
  23.  
  24.    @ivar gender: Genders of the language.
  25.    @type gender: C{list} of C{str}
  26.  
  27.    @ivar case: Cases of the language.
  28.    @type case: C{list} of C{str}
  29.    """
  30.     def __init__(self, found_lines):
  31.         self.name = found_lines['name']
  32.         self.ownname = found_lines['ownname']
  33.         self.isocode = found_lines['isocode']
  34.         self.plural = found_lines['plural']
  35.         self.grflangid = found_lines['grflangid']
  36.  
  37.         gender = found_lines.get('gender')
  38.         if gender is None: gender = []
  39.         self.gender = gender
  40.  
  41.         case = found_lines.get('case')
  42.         if case is None: case = []
  43.         if '' not in case: case.append('')
  44.         self.case = case
  45.  
  46. def as_str(text):
  47.     return text.strip()
  48.  
  49. def as_int(text):
  50.     if text[:2] in ('0x', '0X'):
  51.         return int(text, base=16)
  52.     else:
  53.         return int(text, base=10)
  54.  
  55. def as_strlist(text):
  56.     return list(set(text.split()))
  57.  
  58. # Recognized lines in a language file.
  59. LanguageLine = namedtuple('LanguageLine', ['name', 'pattern', 'convert', 'required'])
  60. recognized = [
  61.     LanguageLine('name',      re.compile('##name +(.*) *$'),                        as_str,     True),
  62.     LanguageLine('ownname',   re.compile('##ownname +(.*) *$'),                     as_str,     True),
  63.     LanguageLine('isocode',   re.compile('##isocode +([a-z][a-z]_[A-Z][A-Z]) *$'),  as_str,     True),
  64.     LanguageLine('plural',    re.compile('##plural +((0[xX])?[0-9A-Fa-f]+) *$'),    as_int,     True),
  65.     LanguageLine('grflangid', re.compile('##grflangid +((0[xX])?[0-9A-Fa-f]+) *$'), as_int,     True),
  66.     LanguageLine('gender',    re.compile('##gender +(.*) *$'),                      as_strlist, False),
  67.     LanguageLine('case',      re.compile('##case +(.*) *$'),                        as_strlist, False)]
  68.  
  69.  
  70. def parse_file(fname):
  71.     """
  72.    Parse a language file, collecting the recognized lines.
  73.  
  74.    @param fname: Name of the file to read.
  75.    @type  fname: C{str}
  76.  
  77.    @return: The found meta-information about a language.
  78.    @rtype:  C{LanguageData}
  79.    """
  80.     handle = open(fname, "rt", encoding="utf-8")
  81.     found_lines = {}
  82.     for line in handle:
  83.         if not line.startswith('##'):
  84.             continue
  85.  
  86.         line = line.rstrip()
  87.         for ll in recognized:
  88.             m = ll.pattern.match(line)
  89.             if m:
  90.                 found_lines[ll.name] = ll.convert(m.group(1))
  91.                 break
  92.  
  93.     handle.close()
  94.  
  95.     if not all(ll.name in found_lines for ll in recognized if ll.required):
  96.         for ll in recognized:
  97.             if ll.required and ll.name not in found_lines:
  98.                 msg = "File \"{}\" is missing required language line ##{} (or it has the wrong format)"
  99.                 print(msg.format(fname, ll.name))
  100.         sys.exit(1)
  101.  
  102.     return LanguageData(found_lines)
  103.  
  104.  
  105. def init(path):
  106.     """
  107.    Find all text files (".txt" extension) in the tree below L{path}, and load
  108.    the meta-language information in them.
  109.  
  110.    @param path: Root of the tree containing language meta-data text files.
  111.    @type  path: C{str}
  112.    """
  113.     global all_languages, grflangid, isocode
  114.  
  115.     all_languages = []
  116.     for dirpath, dirnames, filenames in os.walk(path):
  117.         for fname in filenames:
  118.             if fname.lower().endswith('.txt'):
  119.                 all_languages.append(parse_file(os.path.join(dirpath, fname)))
  120.  
  121.     grflangid = dict((x.grflangid, x) for x in all_languages)
  122.     assert len(all_languages) == len(grflangid)
  123.  
  124.     isocode = dict((x.isocode, x) for x in all_languages)
  125.     assert len(all_languages) == len(isocode)

Comments