From 5e94f81cbf944383aba32b9120256632d1012913 Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Thu, 22 Mar 2007 15:39:44 +0000 Subject: [PATCH] Scons: update_po target, move processing functions to po/lyx_pot.py git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@17509 a592a061-630c-0410-9148-cb99ea01b6c8 --- development/scons/SConstruct | 9 +- development/scons/scons_utils.py | 118 ------------------ po/lyx_pot.py | 199 +++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 122 deletions(-) create mode 100755 po/lyx_pot.py diff --git a/development/scons/SConstruct b/development/scons/SConstruct index 5706497052..aa16849ce7 100644 --- a/development/scons/SConstruct +++ b/development/scons/SConstruct @@ -1988,19 +1988,20 @@ if update_po: Exit(1) # build language_l10n.pot, ui_l10n.pot, layouts_l10n.pot, qt4_l10n.pot # and combine them to lyx.po + env['LYX_POT'] = 'python $TOP_SRCDIR/po/lyx_pot.py' lyx_po = env.Command('$BUILDDIR/po/lyx.po', env.Command('$BUILDDIR/po/all.po', [env.Command('$BUILDDIR/po/language_l10n.pot', '$TOP_SRCDIR/lib/languages', - utils.env_language_l10n), + '$LYX_POT -b $TOP_SRCDIR -t languages -o $TARGET $SOURCES'), env.Command('$BUILDDIR/po/qt4_l10n.pot', ['$TOP_SRCDIR/src/frontends/qt4/ui/%s' % x for x in src_frontends_qt4_ui_files], - utils.env_qt4_l10n), + '$LYX_POT -b $TOP_SRCDIR -t qt4 -o $TARGET $SOURCES'), env.Command('$BUILDDIR/po/layouts_l10n.pot', ['$TOP_SRCDIR/lib/layouts/%s' % x for x in lib_layouts_files], - utils.env_layouts_l10n), + '$LYX_POT -b $TOP_SRCDIR -t layouts -o $TARGET $SOURCES'), env.Command('$BUILDDIR/po/ui_l10n.pot', ['$TOP_SRCDIR/lib/ui/%s' % x for x in lib_ui_files], - utils.env_ui_l10n) + '$LYX_POT -b $TOP_SRCDIR -t ui -o $TARGET $SOURCES'), ], utils.env_cat), '$MSGUNIQ -o $TARGET $SOURCE' ) diff --git a/development/scons/scons_utils.py b/development/scons/scons_utils.py index a8e582237e..bb924cafc8 100644 --- a/development/scons/scons_utils.py +++ b/development/scons/scons_utils.py @@ -113,124 +113,6 @@ def env_toc(target, source, env): doc_toc.build_toc(str(target[0]), [file.abspath for file in source]) -def relativePath(env, path): - '''return relative path from top source dir''' - # full pathname of path - path1 = os.path.normpath(env.File(path).abspath).split(os.sep) - path2 = os.path.normpath(env.Dir('$TOP_SRCDIR').abspath).split(os.sep) - if path1[:len(path2)] != path2: - print "Path %s is not under top source directory" % path - return os.path.join(*path1[len(path2):]) - - -def env_language_l10n(target, source, env): - '''Generate pot file from lib/language''' - input = open(env.File(source[0]).abspath) - output = open(env.File(target[0]).abspath, 'w') - for lineno, line in enumerate(input.readlines()): - if line[0] == '#': - continue - items = line.split('"') - # empty lines? - if len(items) != 5: - print 'Warning: this line looks strange:' - print line - # From: - # afrikaans afrikaans "Afrikaans" false iso8859-15 af_ZA "" - # To: - # #: lib/languages:2 - # msgid "Afrikaans" - # msgstr "" - print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % (relativePath(env, source[0]), lineno+1, items[1]) - input.close() - output.close() - - -def env_qt4_l10n(target, source, env): - '''Generate pot file from src/frontends/qt4/ui/*.ui''' - output = open(env.File(target[0]).abspath, 'w') - pat = re.compile(r'\s*(.*)') - prop = re.compile(r'\s* - if skipNextLine: - skipNextLine = False - continue - # skip the line after - if prop.match(line): - skipNextLine = True - continue - # get lines that match ... - if pat.match(line): - (string,) = pat.match(line).groups() - string = string.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', r'\"') - print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \ - (relativePath(env, src), lineno+1, string) - input.close() - output.close() - - -def env_layouts_l10n(target, source, env): - '''Generate pot file from lib/layouts/*.layout and *.inc''' - output = open(env.File(target[0]).abspath, 'w') - Style = re.compile(r'^Style\s+(.*)') - # include ???LabelString???, but exclude comment lines - LabelString = re.compile(r'^[^#]*LabelString\S*\s+(.*)') - GuiName = re.compile(r'\s*GuiName\s+(.*)') - ListName = re.compile(r'\s*ListName\s+(.*)') - for src in source: - input = open(env.File(src).abspath) - for lineno, line in enumerate(input.readlines()): - # get lines that match ... - if Style.match(line): - (string,) = Style.match(line).groups() - string = string.replace('_', ' ') - elif LabelString.match(line): - (string,) = LabelString.match(line).groups() - elif GuiName.match(line): - (string,) = GuiName.match(line).groups() - elif ListName.match(line): - (string,) = ListName.match(line).groups() - else: - continue - string = string.replace('\\', '\\\\').replace('"', '') - if string != "": - print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \ - (relativePath(env, src), lineno+1, string) - input.close() - output.close() - - -def env_ui_l10n(target, source, env): - '''Generate pot file from lib/ui/*''' - output = open(env.File(target[0]).abspath, 'w') - Submenu = re.compile(r'^[^#]*Submenu\s+"([^"]*)"') - Toolbar = re.compile(r'^[^#]*Toolbar\s+"[^"]+"\s+"([^"]*)"') - Item = re.compile(r'[^#]*Item\s+"([^"]*)"') - for src in source: - input = open(env.File(src).abspath) - for lineno, line in enumerate(input.readlines()): - # get lines that match ... - if Submenu.match(line): - (string,) = Submenu.match(line).groups() - string = string.replace('_', ' ') - elif Toolbar.match(line): - (string,) = Toolbar.match(line).groups() - elif Item.match(line): - (string,) = Item.match(line).groups() - else: - continue - string = string.replace('\\', '\\\\').replace('"', '') - if string != "": - print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \ - (relativePath(env, src), lineno+1, string) - input.close() - output.close() - - def env_cat(target, source, env): '''Cat source > target. Avoid pipe to increase portability''' output = open(env.File(target[0]).abspath, 'w') diff --git a/po/lyx_pot.py b/po/lyx_pot.py new file mode 100755 index 0000000000..5660e45abd --- /dev/null +++ b/po/lyx_pot.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# file lyx_pot.py +# This file is part of LyX, the document processor. +# Licence details can be found in the file COPYING. +# +# \author Bo Peng +# +# Full author contact details are available in file CREDITS + +# Usage: use +# lyx_pot.py -h +# to get usage message + +# This script will extract translatable strings from input files and write +# to output in gettext .pot format. +# +import sys, os, re, getopt + + +def relativePath(path, base): + '''return relative path from top source dir''' + # full pathname of path + path1 = os.path.normpath(os.path.realpath(path)).split(os.sep) + path2 = os.path.normpath(base).split(os.sep) + if path1[:len(path2)] != path2: + print "Path %s is not under top source directory" % path + return os.path.join(*path1[len(path2):]) + + +def ui_l10n(input_files, output, base): + '''Generate pot file from lib/ui/*''' + output = open(output, 'w') + Submenu = re.compile(r'^[^#]*Submenu\s+"([^"]*)"') + Toolbar = re.compile(r'^[^#]*Toolbar\s+"[^"]+"\s+"([^"]*)"') + Item = re.compile(r'[^#]*Item\s+"([^"]*)"') + for src in input_files: + input = open(src) + for lineno, line in enumerate(input.readlines()): + # get lines that match ... + if Submenu.match(line): + (string,) = Submenu.match(line).groups() + string = string.replace('_', ' ') + elif Toolbar.match(line): + (string,) = Toolbar.match(line).groups() + elif Item.match(line): + (string,) = Item.match(line).groups() + else: + continue + string = string.replace('\\', '\\\\').replace('"', '') + if string != "": + print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \ + (relativePath(src, base), lineno+1, string) + input.close() + output.close() + + +def layouts_l10n(input_files, output, base): + '''Generate pot file from lib/layouts/*.layout and *.inc''' + output = open(output, 'w') + Style = re.compile(r'^Style\s+(.*)') + # include ???LabelString???, but exclude comment lines + LabelString = re.compile(r'^[^#]*LabelString\S*\s+(.*)') + GuiName = re.compile(r'\s*GuiName\s+(.*)') + ListName = re.compile(r'\s*ListName\s+(.*)') + for src in input_files: + input = open(src) + for lineno, line in enumerate(input.readlines()): + # get lines that match ... + if Style.match(line): + (string,) = Style.match(line).groups() + string = string.replace('_', ' ') + elif LabelString.match(line): + (string,) = LabelString.match(line).groups() + elif GuiName.match(line): + (string,) = GuiName.match(line).groups() + elif ListName.match(line): + (string,) = ListName.match(line).groups() + else: + continue + string = string.replace('\\', '\\\\').replace('"', '') + if string != "": + print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \ + (relativePath(src, base), lineno+1, string) + input.close() + output.close() + + +def qt4_l10n(input_files, output, base): + '''Generate pot file from src/frontends/qt4/ui/*.ui''' + output = open(output, 'w') + pat = re.compile(r'\s*(.*)') + prop = re.compile(r'\s* + if skipNextLine: + skipNextLine = False + continue + # skip the line after + if prop.match(line): + skipNextLine = True + continue + # get lines that match ... + if pat.match(line): + (string,) = pat.match(line).groups() + string = string.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', r'\"') + print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % \ + (relativePath(src, base), lineno+1, string) + input.close() + output.close() + + +def languages_l10n(input_files, output, base): + '''Generate pot file from lib/language''' + output = open(output, 'w') + # assuming only one language file + input = open(input_files[0]) + for lineno, line in enumerate(input.readlines()): + if line[0] == '#': + continue + items = line.split('"') + # empty lines? + if len(items) < 3: + continue + # From: + # afrikaans afrikaans "Afrikaans" false iso8859-15 af_ZA "" + # To: + # #: lib/languages:2 + # msgid "Afrikaans" + # msgstr "" + # I do not care extra "s like "af_ZA" + print >> output, '#: %s:%d\nmsgid "%s"\nmsgstr ""\n' % (relativePath(input_files[0], base), lineno+1, items[1]) + input.close() + output.close() + + +def processFiles(input_type, input_files, output, base): + '''Process files according to input_type''' + if input_type not in ['ui', 'layouts', 'qt4', 'languages'] or output is None: + print 'Wrong input type or output filename.' + sys.exit(1) + if input_type == 'ui': + ui_l10n(input_files, output, base) + elif input_type == 'layouts': + layouts_l10n(input_files, output, base) + elif input_type == 'qt4': + qt4_l10n(input_files, output, base) + else: + languages_l10n(input_files, output, base) + + +Usage = ''' +lyx_pot.py [-b|--base top_src_dir] [-o|--output output_file] [-h|--help] -t|--type input_type input_files + +where + --base: + path to the top source directory. default to '.' + --output: + output pot file, default to './lyx.pot' + --input_type can be + ui: lib/ui/* + layouts: lib/layouts/* + qt4: qt4 ui files + languages: file lib/languages +''' + +if __name__ == '__main__': + input_type = None + output = 'lyx.pot' + base = '.' + # + optlist, args = getopt.getopt(sys.argv[1:], 'ht:o:b:', + ['help', 'type=', 'output=', 'base=']) + for (opt, value) in optlist: + if opt in ['-h', '--help']: + print Usage + sys.exit(0) + elif opt in ['-o', '--output']: + output = value + elif opt in ['-b', '--base']: + base = value + elif opt in ['-t', '--type']: + input_type = value + if input_type not in ['ui', 'layouts', 'qt4', 'languages'] or output is None: + print 'Wrong input type or output filename.' + sys.exit(1) + if input_type == 'ui': + ui_l10n(args, output, base) + elif input_type == 'layouts': + layouts_l10n(args, output, base) + elif input_type == 'qt4': + qt4_l10n(args, output, base) + else: + languages_l10n(args, output, base) +