extract_strings_qt.py raw

   1  #!/usr/bin/env python3
   2  # Copyright (c) 2012-2021 The Limenka developers
   3  # Distributed under the MIT software license, see the accompanying
   4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  '''
   6  Extract _("...") strings for translation and convert to Qt stringdefs so that
   7  they can be picked up by Qt linguist.
   8  '''
   9  from subprocess import Popen, PIPE
  10  import operator
  11  import os
  12  import sys
  13  
  14  OUT_CPP="qt/limenkastrings.cpp"
  15  EMPTY=['""']
  16  
  17  def parse_po(text):
  18      """
  19      Parse 'po' format produced by xgettext.
  20      Return a list of (msgid,msgstr) tuples.
  21      """
  22      messages = []
  23      msgid = []
  24      msgstr = []
  25      in_msgid = False
  26      in_msgstr = False
  27  
  28      for line in text.split('\n'):
  29          line = line.rstrip('\r')
  30          if line.startswith('msgid '):
  31              if in_msgstr:
  32                  messages.append((msgid, msgstr))
  33                  in_msgstr = False
  34              # message start
  35              in_msgid = True
  36  
  37              msgid = [line[6:]]
  38          elif line.startswith('msgstr '):
  39              in_msgid = False
  40              in_msgstr = True
  41              msgstr = [line[7:]]
  42          elif line.startswith('"'):
  43              if in_msgid:
  44                  msgid.append(line)
  45              if in_msgstr:
  46                  msgstr.append(line)
  47  
  48      if in_msgstr:
  49          messages.append((msgid, msgstr))
  50  
  51      return messages
  52  
  53  files = sys.argv[1:]
  54  
  55  # xgettext -n --keyword=_ $FILES
  56  XGETTEXT=os.getenv('XGETTEXT', 'xgettext')
  57  if not XGETTEXT:
  58      print('Cannot extract strings: xgettext utility is not installed or not configured.',file=sys.stderr)
  59      print('Please install package "gettext" and re-run \'cmake -B build\'.',file=sys.stderr)
  60      sys.exit(1)
  61  child = Popen([XGETTEXT,'--output=-','--from-code=utf-8','-n','--keyword=_'] + files, stdout=PIPE)
  62  (out, err) = child.communicate()
  63  
  64  messages = parse_po(out.decode('utf-8'))
  65  
  66  f = open(OUT_CPP, 'w', encoding="utf8")
  67  f.write("""
  68  
  69  #include <QtGlobal>
  70  
  71  // Automatically generated by extract_strings_qt.py
  72  #ifdef __GNUC__
  73  #define UNUSED __attribute__((unused))
  74  #else
  75  #define UNUSED
  76  #endif
  77  """)
  78  f.write('static const char UNUSED *limenka_strings[] = {\n')
  79  f.write('QT_TRANSLATE_NOOP("limenka", "%s"),\n' % (os.getenv('COPYRIGHT_HOLDERS'),))
  80  messages.sort(key=operator.itemgetter(0))
  81  for (msgid, msgstr) in messages:
  82      if msgid != EMPTY:
  83          f.write('QT_TRANSLATE_NOOP("limenka", %s),\n' % ('\n'.join(msgid)))
  84  f.write('};\n')
  85  f.close()
  86