]> git.lyx.org Git - features.git/blob - po/lyx_pot.py
po/Makefile.in.in, replace awk scripts with the Python version
[features.git] / po / lyx_pot.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 # file lyx_pot.py
5 # This file is part of LyX, the document processor.
6 # Licence details can be found in the file COPYING.
7 #
8 # \author Bo Peng
9 #
10 # Full author contact details are available in file CREDITS
11
12 # Usage: use
13 #     lyx_pot.py -h
14 # to get usage message
15
16 # This script will extract translatable strings from input files and write
17 # to output in gettext .pot format.
18 #
19 import sys, os, re, getopt
20
21
22 def relativePath(path, base):
23     '''return relative path from top source dir'''
24     # full pathname of path
25     path1 = os.path.normpath(os.path.realpath(path)).split(os.sep)
26     path2 = os.path.normpath(os.path.realpath(base)).split(os.sep)
27     if path1[:len(path2)] != path2:
28         print "Path %s is not under top source directory" % path
29     return os.path.join(*path1[len(path2):])
30
31
32 def ui_l10n(input_files, output, base):
33     '''Generate pot file from lib/ui/*'''
34     output = open(output, 'w')
35     Submenu = re.compile(r'^[^#]*Submenu\s+"([^"]*)"')
36     Toolbar = re.compile(r'^[^#]*Toolbar\s+"[^"]+"\s+"([^"]*)"')
37     Item = re.compile(r'[^#]*Item\s+"([^"]*)"')
38     for src in input_files:
39         input = open(src)
40         for lineno, line in enumerate(input.readlines()):
41             # get lines that match <string>...</string>
42             if Submenu.match(line):
43                 (string,) = Submenu.match(line).groups()
44                 string = string.replace('_', ' ')
45             elif Toolbar.match(line):
46                 (string,) = Toolbar.match(line).groups()
47             elif Item.match(line):
48                 (string,) = Item.match(line).groups()
49             else:
50                 continue
51             string = string.replace('\\', '\\\\').replace('"', '')
52             if string != "":
53                 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
54                     (relativePath(src, base), lineno+1, string)
55         input.close()
56     output.close()
57
58
59 def layouts_l10n(input_files, output, base):
60     '''Generate pot file from lib/layouts/*.layout and *.inc'''
61     output = open(output, 'w')
62     Style = re.compile(r'^Style\s+(.*)')
63     # include ???LabelString???, but exclude comment lines
64     LabelString = re.compile(r'^[^#]*LabelString\S*\s+(.*)')
65     GuiName = re.compile(r'\s*GuiName\s+(.*)')
66     ListName = re.compile(r'\s*ListName\s+(.*)')
67     for src in input_files:
68         input = open(src)
69         for lineno, line in enumerate(input.readlines()):
70             # get lines that match <string>...</string>
71             if Style.match(line):
72                 (string,) = Style.match(line).groups()
73                 string = string.replace('_', ' ')
74             elif LabelString.match(line):
75                 (string,) = LabelString.match(line).groups()
76             elif GuiName.match(line):
77                 (string,) = GuiName.match(line).groups()
78             elif ListName.match(line):
79                 (string,) = ListName.match(line).groups()
80             else:
81                 continue
82             string = string.replace('\\', '\\\\').replace('"', '')
83             if string != "":
84                 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
85                     (relativePath(src, base), lineno+1, string)
86         input.close()
87     output.close()
88
89
90 def qt4_l10n(input_files, output, base):
91     '''Generate pot file from src/frontends/qt4/ui/*.ui'''
92     output = open(output, 'w')
93     pat = re.compile(r'\s*<string>(.*)</string>')
94     prop = re.compile(r'\s*<property.*name.*=.*shortcut')
95     for src in input_files:
96         input = open(src)
97         skipNextLine = False
98         for lineno, line in enumerate(input.readlines()):
99             # looking for a line with <string></string>
100             if skipNextLine:
101                 skipNextLine = False
102                 continue
103             # skip the line after <property name=shortcut>
104             if prop.match(line):
105                 skipNextLine = True
106                 continue
107             # get lines that match <string>...</string>
108             if pat.match(line):
109                 (string,) = pat.match(line).groups()
110                 string = string.replace('&amp;', '&').replace('&lt;', '<').replace('&gt;', '>').replace('"', r'\"')
111                 print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \
112                     (relativePath(src, base), lineno+1, string) 
113         input.close()
114     output.close()
115
116
117 def languages_l10n(input_files, output, base):
118     '''Generate pot file from lib/language'''
119     output = open(output, 'w')
120     # assuming only one language file
121     input = open(input_files[0])
122     for lineno, line in enumerate(input.readlines()):
123         if line[0] == '#':
124             continue
125         items = line.split('"')
126         # empty lines?
127         if len(items) < 3:
128             continue
129         # From:
130         #   afrikaans   afrikaans       "Afrikaans"     false  iso8859-15 af_ZA  ""
131         # To:
132         #   #: lib/languages:2
133         #   msgid "Afrikaans"
134         #   msgstr ""
135         # I do not care extra "s like "af_ZA"
136         print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % (relativePath(input_files[0], base), lineno+1, items[1])
137     input.close()
138     output.close()
139
140
141 def processFiles(input_type, input_files, output, base):
142     '''Process files according to input_type'''
143     if input_type not in ['ui', 'layouts', 'qt4', 'languages'] or output is None:
144         print 'Wrong input type or output filename.'
145         sys.exit(1)
146     if input_type == 'ui':
147         ui_l10n(input_files, output, base)
148     elif input_type == 'layouts':
149         layouts_l10n(input_files, output, base)
150     elif input_type == 'qt4':
151         qt4_l10n(input_files, output, base)
152     else:
153         languages_l10n(input_files, output, base)
154
155
156 Usage = '''
157 lyx_pot.py [-b|--base top_src_dir] [-o|--output output_file] [-h|--help] -t|--type input_type input_files
158
159 where 
160     --base:
161         path to the top source directory. default to '.'
162     --output:
163         output pot file, default to './lyx.pot'
164     --input_type can be
165         ui: lib/ui/*
166         layouts: lib/layouts/*
167         qt4: qt4 ui files
168         languages: file lib/languages
169 '''
170
171 if __name__ == '__main__':
172     input_type = None
173     output = 'lyx.pot'
174     base = '.'
175     #
176     optlist, args = getopt.getopt(sys.argv[1:], 'ht:o:b:',
177         ['help', 'type=', 'output=', 'base='])
178     for (opt, value) in optlist:
179         if opt in ['-h', '--help']:
180             print Usage
181             sys.exit(0)
182         elif opt in ['-o', '--output']:
183             output = value
184         elif opt in ['-b', '--base']:
185             base = value
186         elif opt in ['-t', '--type']:
187             input_type = value
188     if input_type not in ['ui', 'layouts', 'qt4', 'languages'] or output is None:
189         print 'Wrong input type or output filename.'
190         sys.exit(1)
191     if input_type == 'ui':
192         ui_l10n(args, output, base)
193     elif input_type == 'layouts':
194         layouts_l10n(args, output, base)
195     elif input_type == 'qt4':
196         qt4_l10n(args, output, base)
197     else:
198         languages_l10n(args, output, base)
199