2 # -*- coding: utf-8 -*-
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
10 # Full author contact details are available in file CREDITS
14 # to get usage message
16 # This script will extract translatable strings from input files and write
17 # to output in gettext .pot format.
19 import sys, os, re, getopt
21 def relativePath(path, base):
22 '''return relative path from top source dir'''
23 # full pathname of path
24 path1 = os.path.normpath(os.path.realpath(path)).split(os.sep)
25 path2 = os.path.normpath(os.path.realpath(base)).split(os.sep)
26 if path1[:len(path2)] != path2:
27 print "Path %s is not under top source directory" % path
28 path3 = os.path.join(*path1[len(path2):]);
29 # replace all \ by / such that we get the same comments on Windows and *nix
30 path3 = path3.replace('\\', '/')
34 def ui_l10n(input_files, output, base):
35 '''Generate pot file from lib/ui/*'''
36 output = open(output, 'w')
37 Submenu = re.compile(r'^[^#]*Submenu\s+"([^"]*)"')
38 Popupmenu = re.compile(r'^[^#]*PopupMenu\s+"[^"]+"\s+"([^"]*)"')
39 Toolbar = re.compile(r'^[^#]*Toolbar\s+"[^"]+"\s+"([^"]*)"')
40 Item = re.compile(r'[^#]*Item\s+"([^"]*)"')
41 for src in input_files:
43 for lineno, line in enumerate(input.readlines()):
44 if Submenu.match(line):
45 (string,) = Submenu.match(line).groups()
46 string = string.replace('_', ' ')
47 elif Popupmenu.match(line):
48 (string,) = Popupmenu.match(line).groups()
49 elif Toolbar.match(line):
50 (string,) = Toolbar.match(line).groups()
51 elif Item.match(line):
52 (string,) = Item.match(line).groups()
55 string = string.replace('"', '')
57 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
58 (relativePath(src, base), lineno+1, string)
63 def layouts_l10n(input_files, output, base):
64 '''Generate pot file from lib/layouts/*.layout and *.inc'''
65 output = open(output, 'w')
66 Style = re.compile(r'^Style\s+(.*)')
67 # include ???LabelString???, but exclude comment lines
68 LabelString = re.compile(r'^[^#]*LabelString\S*\s+(.*)')
69 GuiName = re.compile(r'\s*GuiName\s+(.*)')
70 ListName = re.compile(r'\s*ListName\s+(.*)')
71 for src in input_files:
73 for lineno, line in enumerate(input.readlines()):
75 (string,) = Style.match(line).groups()
76 string = string.replace('_', ' ')
77 elif LabelString.match(line):
78 (string,) = LabelString.match(line).groups()
79 elif GuiName.match(line):
80 (string,) = GuiName.match(line).groups()
81 elif ListName.match(line):
82 (string,) = ListName.match(line).groups()
85 string = string.replace('\\', '\\\\').replace('"', '')
87 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
88 (relativePath(src, base), lineno+1, string)
93 def qt4_l10n(input_files, output, base):
94 '''Generate pot file from src/frontends/qt4/ui/*.ui'''
95 output = open(output, 'w')
96 pat = re.compile(r'\s*<string>(.*)</string>')
97 prop = re.compile(r'\s*<property.*name.*=.*shortcut')
98 for src in input_files:
101 for lineno, line in enumerate(input.readlines()):
102 # skip the line after <property name=shortcut>
109 # get lines that match <string>...</string>
111 (string,) = pat.match(line).groups()
112 string = string.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', r'\"')
113 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
114 (relativePath(src, base), lineno+1, string)
119 def languages_l10n(input_files, output, base):
120 '''Generate pot file from lib/language'''
121 output = open(output, 'w')
122 # assuming only one language file
123 reg = re.compile('[\w-]+\s+[\w"]+\s+"([\w \-\(\)]+)"\s+(true|false)\s+[\w-]+\s+\w+\s+"[^"]*"')
124 input = open(input_files[0])
125 for lineno, line in enumerate(input.readlines()):
129 # afrikaans afrikaans "Afrikaans" false iso8859-15 af_ZA ""
135 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
136 (relativePath(input_files[0], base), lineno+1, reg.match(line).groups()[0])
138 print "Error: Unable to handle line:"
146 lyx_pot.py [-b|--base top_src_dir] [-o|--output output_file] [-h|--help] -t|--type input_type input_files
150 path to the top source directory. default to '.'
152 output pot file, default to './lyx.pot'
155 layouts: lib/layouts/*
157 languages: file lib/languages
160 if __name__ == '__main__':
165 optlist, args = getopt.getopt(sys.argv[1:], 'ht:o:b:',
166 ['help', 'type=', 'output=', 'base='])
167 for (opt, value) in optlist:
168 if opt in ['-h', '--help']:
171 elif opt in ['-o', '--output']:
173 elif opt in ['-b', '--base']:
175 elif opt in ['-t', '--type']:
177 if input_type not in ['ui', 'layouts', 'qt4', 'languages'] or output is None:
178 print 'Wrong input type or output filename.'
180 if input_type == 'ui':
181 ui_l10n(args, output, base)
182 elif input_type == 'layouts':
183 layouts_l10n(args, output, base)
184 elif input_type == 'qt4':
185 qt4_l10n(args, output, base)
187 languages_l10n(args, output, base)