diff --git a/src/calibre/translations/msgfmt.py b/src/calibre/translations/msgfmt.py index 3c41cee2cd..a27a6c007f 100644 --- a/src/calibre/translations/msgfmt.py +++ b/src/calibre/translations/msgfmt.py @@ -1,20 +1,39 @@ #! /usr/bin/env python # Written by Martin v. Loewis -# Modified by Kovid Goyal """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation. + +Usage: msgfmt.py [OPTIONS] filename.po + +Options: + -o file + --output-file=file + Specify the output file to write to. If omitted, output will go to a + file named filename.mo (based off the input file name). + + -h + --help + Print this message and exit. + + -V + --version + Display version information and exit. """ import sys import os +import getopt import struct import array -__version__ = "1.2" +__version__ = "1.1" + +MESSAGES = {} + def usage(code, msg=''): print >> sys.stderr, __doc__ @@ -23,16 +42,16 @@ def usage(code, msg=''): sys.exit(code) - -def add(id, str, fuzzy, MESSAGES): +def add(id, str, fuzzy): "Add a non-fuzzy translation to the dictionary." + global MESSAGES if not fuzzy and str: MESSAGES[id] = str - -def generate(MESSAGES): +def generate(): "Return the generated output." + global MESSAGES keys = MESSAGES.keys() # the keys are sorted in the .mo file keys.sort() @@ -44,6 +63,7 @@ def generate(MESSAGES): offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) ids += id + '\0' strs += MESSAGES[id] + '\0' + output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. # translated string. @@ -71,9 +91,7 @@ def generate(MESSAGES): return output - def make(filename, outfile): - MESSAGES = {} ID = 1 STR = 2 @@ -101,7 +119,7 @@ def make(filename, outfile): lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: - add(msgid, msgstr, fuzzy, MESSAGES) + add(msgid, msgstr, fuzzy) section = None fuzzy = 0 # Record a fuzzy mark @@ -111,16 +129,39 @@ def make(filename, outfile): if l[0] == '#': continue # Now we are in a msgid section, output previous section - if l.startswith('msgid'): + if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: - add(msgid, msgstr, fuzzy, MESSAGES) + add(msgid, msgstr, fuzzy) section = ID l = l[5:] msgid = msgstr = '' + is_plural = False + # This is a message with plural forms + elif l.startswith('msgid_plural'): + if section != ID: + print >> sys.stderr, 'msgid_plural not preceeded by msgid on %s:%d' %\ + (infile, lno) + sys.exit(1) + l = l[12:] + msgid += '\0' # separator of singular and plural + is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR - l = l[6:] + if l.startswith('msgstr['): + if not is_plural: + print >> sys.stderr, 'plural without msgid_plural on %s:%d' %\ + (infile, lno) + sys.exit(1) + l = l.split(']', 1)[1] + if msgstr: + msgstr += '\0' # Separator of the various plural forms + else: + if is_plural: + print >> sys.stderr, 'indexed msgstr required for plural on %s:%d' %\ + (infile, lno) + sys.exit(1) + l = l[6:] # Skip empty lines l = l.strip() if not l: @@ -138,22 +179,40 @@ def make(filename, outfile): sys.exit(1) # Add last entry if section == STR: - add(msgid, msgstr, fuzzy, MESSAGES) + add(msgid, msgstr, fuzzy) # Compute output - output = generate(MESSAGES) + output = generate() + outfile.write(output) + + +def main(): try: - outfile.write(output) - except IOError,msg: - print >> sys.stderr, msg + opts, args = getopt.getopt(sys.argv[1:], 'hVo:', + ['help', 'version', 'output-file=']) + except getopt.error, msg: + usage(1, msg) + outfile = None + # parse options + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-V', '--version'): + print >> sys.stderr, "msgfmt.py", __version__ + sys.exit(0) + elif opt in ('-o', '--output-file'): + outfile = arg + # do it + if not args: + print >> sys.stderr, 'No input file given' + print >> sys.stderr, "Try `msgfmt --help' for more information." + return - -def main(outfile, args=sys.argv[1:]): for filename in args: make(filename, outfile) - return 0 + if __name__ == '__main__': - sys.exit(main(sys.stdout)) + main() diff --git a/src/calibre/utils/localization.py b/src/calibre/utils/localization.py index 294d8f7640..43b4fbcc89 100644 --- a/src/calibre/utils/localization.py +++ b/src/calibre/utils/localization.py @@ -71,13 +71,13 @@ def set_translators(): lang = get_lang() if lang: buf = iso639 = None - if os.access(lang+'.po', os.R_OK): + mpath = get_lc_messages_path(lang) + if os.access(mpath+'.po', os.R_OK): from calibre.translations.msgfmt import make buf = cStringIO.StringIO() - make(lang+'.po', buf) + make(mpath+'.po', buf) buf = cStringIO.StringIO(buf.getvalue()) - mpath = get_lc_messages_path(lang) if mpath is not None: with ZipFile(P('localization/locales.zip', allow_user_override=False), 'r') as zf: