diff babel/messages/pofile.py @ 104:22f222e23b86

Merged `write_pot` and `write_po` functions by moving more functionality to the `Catalog` class. This is certainly not perfect yet, but moves us in the right direction.
author cmlenz
date Wed, 13 Jun 2007 23:02:24 +0000
parents 7cdf89eb9007
children f744dd56573d
line wrap: on
line diff
--- a/babel/messages/pofile.py
+++ b/babel/messages/pofile.py
@@ -30,14 +30,19 @@
 from babel.messages.catalog import Catalog
 from babel.util import LOCALTZ
 
-__all__ = ['escape', 'normalize', 'read_po', 'write_po', 'write_pot']
+__all__ = ['escape', 'normalize', 'read_po', 'write_po']
 
 def read_po(fileobj):
     """Read messages from a ``gettext`` PO (portable object) file from the given
     file-like object and return a `Catalog`.
     
     >>> from StringIO import StringIO
-    >>> buf = StringIO('''
+    >>> buf = StringIO('''# Translations template for PROJECT.
+    ... # Copyright (C) YEAR COPYRIGHT HOLDER
+    ... # This file is distributed under the same license as the PROJECT project.
+    ... # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+    ... #
+    ... 
     ... #: main.py:1
     ... #, fuzzy, python-format
     ... msgid "foo %(name)s"
@@ -52,6 +57,14 @@
     ... msgstr[1] ""
     ... ''')
     >>> catalog = read_po(buf)
+    >>> catalog.revision_date = datetime(2007, 04, 01)
+    
+    >>> print catalog.header_comment
+    # Translations template for PROJECT.
+    # Copyright (C) 2007 ORGANIZATION
+    # This file is distributed under the same license as the PROJECT project.
+    # FIRST AUTHOR <EMAIL@ADDRESS>, 2007.
+    
     >>> for message in catalog:
     ...     if message.id:
     ...         print (message.id, message.string)
@@ -73,6 +86,8 @@
     flags = []
     comments = []
     in_msgid = in_msgstr = False
+    in_header = True
+    header_lines = []
 
     def _add_message():
         translations.sort()
@@ -91,29 +106,33 @@
     for line in fileobj.readlines():
         line = line.strip()
         if line.startswith('#'):
-            in_msgid = in_msgstr = False
-            if messages:
-                _add_message()
-            if line[1:].startswith(':'):
-                for location in line[2:].lstrip().split():
-                    filename, lineno = location.split(':', 1)
-                    locations.append((filename, int(lineno)))
-            elif line[1:].startswith(','):
-                for flag in line[2:].lstrip().split(','):
-                    flags.append(flag.strip())
-            elif line[1:].startswith('.'):
-                # These are called auto-comments
-                comment = line[2:].strip()
-                if comment:
-                    # Just check that we're not adding empty comments
-                    comments.append(comment)
-            elif line[1:].startswith(' '):
-                # These are called user comments
-                comment = line[1:].strip()
-                if comment:
-                    # Just check that we're not adding empty comments
-                    comments.append(comment)
-        elif line:
+            if in_header and line[1:].startswith(' '):
+                header_lines.append(line)
+            else:
+                in_header = in_msgid = in_msgstr = False
+                if messages:
+                    _add_message()
+                if line[1:].startswith(':'):
+                    for location in line[2:].lstrip().split():
+                        filename, lineno = location.split(':', 1)
+                        locations.append((filename, int(lineno)))
+                elif line[1:].startswith(','):
+                    for flag in line[2:].lstrip().split(','):
+                        flags.append(flag.strip())
+                elif line[1:].startswith('.'):
+                    # These are called auto-comments
+                    comment = line[2:].strip()
+                    if comment:
+                        # Just check that we're not adding empty comments
+                        comments.append(comment)
+                elif line[1:].startswith(' '):
+                    # These are called user comments
+                    comment = line[1:].strip()
+                    if comment:
+                        # Just check that we're not adding empty comments
+                        comments.append(comment)
+        else:
+            in_header = False
             if line.startswith('msgid_plural'):
                 in_msgid = True
                 msg = line[12:].lstrip()
@@ -139,18 +158,11 @@
                 elif in_msgstr:
                     translations[-1][1] += line.rstrip()[1:-1]
 
+    catalog.header_comment = '\n'.join(header_lines)
     if messages:
         _add_message()
     return catalog
 
-POT_HEADER = u"""\
-# Translations template for %(project)s.
-# Copyright (C) %(year)s %(copyright_holder)s
-# This file is distributed under the same license as the %(project)s project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-""" 
-
 WORD_SEP = re.compile('('
     r'\s+|'                                 # any whitespace
     r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|' # hyphenated words
@@ -236,8 +248,8 @@
         lines[-1] += '\n'
     return u'""\n' + u'\n'.join([escape(l) for l in lines])
 
-def write_pot(fileobj, catalog, width=76, no_location=False, omit_header=False,
-              sort_output=False, sort_by_file=False, copyright_holder=None):
+def write_po(fileobj, catalog, width=76, no_location=False, omit_header=False,
+             sort_output=False, sort_by_file=False):
     r"""Write a ``gettext`` PO (portable object) template file for a given
     message catalog to the provided file-like object.
     
@@ -247,7 +259,7 @@
     >>> catalog.add((u'bar', u'baz'), locations=[('main.py', 3)])
     >>> from StringIO import StringIO
     >>> buf = StringIO()
-    >>> write_pot(buf, catalog, omit_header=True)
+    >>> write_po(buf, catalog, omit_header=True)
     >>> print buf.getvalue()
     #: main.py:1
     #, fuzzy, python-format
@@ -269,7 +281,6 @@
     :param no_location: do not emit a location comment for every message
     :param omit_header: do not include the ``msgid ""`` entry at the top of the
                         output
-    :param copyright_holder: sets the copyright holder in the output
     """
     def _normalize(key):
         return normalize(key, width=width).encode(catalog.charset,
@@ -280,33 +291,24 @@
             text = text.encode(catalog.charset)
         fileobj.write(text)
 
+    messages = list(catalog)
     if sort_output:
-        messages = list(catalog)
         messages.sort(lambda x,y: cmp(x.id, y.id))
     elif sort_by_file:
-        messages = list(catalog)
         messages.sort(lambda x,y: cmp(x.locations, y.locations))
-    else:
-        messages = catalog
-
-    _copyright_holder = copyright_holder or 'ORGANIZATION'
 
     for message in messages:
         if not message.id: # This is the header "message"
             if omit_header:
                 continue
-            pot_header = POT_HEADER % {
-                'year': date.today().strftime('%Y'),
-                'project': catalog.project,
-                'copyright_holder': _copyright_holder,
-            }
+            comment_header = catalog.header_comment
             if width and width > 0:
                 lines = []
-                for line in pot_header.splitlines():
+                for line in comment_header.splitlines():
                     lines += wrap(line, width=width, subsequent_indent='# ',
                                   break_long_words=False)
-                pot_header = u'\n'.join(lines) + u'\n'
-            _write(pot_header)
+                comment_header = u'\n'.join(lines) + u'\n'
+            _write(comment_header)
 
         if message.comments:
             for comment in message.comments:
@@ -331,135 +333,3 @@
             _write('msgid %s\n' % _normalize(message.id))
             _write('msgstr %s\n' % _normalize(message.string or ''))
         _write('\n')
-
-
-# TODO: this should really be a combination of read_po() and write_pot(), the
-#       latter then being renamed back to write_po(). The problem at this time
-#       is that the Catalog class doesn't know anything about the header
-#       comment header
-
-def write_po(fileobj, input_fileobj, locale_obj, project='PROJECT',
-             version='VERSION', first_author=None, first_author_email=None,
-             plurals=('INTEGER', 'EXPRESSION')):
-    r"""Write a ``gettext`` PO (portable object) file to the given file-like 
-    object, from the given input PO template file.
-    
-    >>> from StringIO import StringIO
-    >>> from babel import Locale
-    >>> locale_obj = Locale.parse('pt_PT')
-    >>> inbuf = StringIO(r'''# Translations template for FooBar.
-    ... # Copyright (C) 2007 ORGANIZATION
-    ... # This file is distributed under the same license as the
-    ... # FooBar project.
-    ... # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-    ... #
-    ... #, fuzzy
-    ... msgid ""
-    ... msgstr ""
-    ... "Project-Id-Version: FooBar 0.1\n"
-    ... "POT-Creation-Date: 2007-06-07 22:54+0100\n"
-    ... "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-    ... "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-    ... "Language-Team: LANGUAGE <LL@li.org>\n"
-    ... "MIME-Version: 1.0\n"
-    ... "Content-Type: text/plain; charset=utf-8\n"
-    ... "Content-Transfer-Encoding: 8bit\n"
-    ... "Generated-By: Babel 0.1dev-r50\n"
-    ...
-    ... #: base.py:83 templates/index.html:9
-    ... #: templates/index2.html:9
-    ... msgid "Home"
-    ... msgstr ""
-    ...
-    ... #: base.py:84 templates/index.html:9
-    ... msgid "Accounts"
-    ... msgstr ""
-    ... ''')
-    >>> outbuf = StringIO()
-    >>> write_po(outbuf, inbuf, locale_obj, project='FooBar',
-    ...          version='0.1', first_author='A Name', 
-    ...          first_author_email='user@domain.tld',
-    ...          plurals=(2, '(n != 1)'))
-    >>> print outbuf.getvalue() # doctest: +ELLIPSIS
-    # Portuguese (Portugal) translations for FooBar
-    # Copyright (C) 2007 ORGANIZATION
-    # This file is distributed under the same license as the
-    # FooBar project.
-    # A Name <user@domain.tld>, ...
-    #
-    #, fuzzy
-    msgid ""
-    msgstr ""
-    "Project-Id-Version: FooBar 0.1\n"
-    "POT-Creation-Date: 2007-06-07 22:54+0100\n"
-    "PO-Revision-Date: ...\n"
-    "Last-Translator: A Name <user@domain.tld>\n"
-    "Language-Team: LANGUAGE <LL@li.org>\n"
-    "MIME-Version: 1.0\n"
-    "Content-Type: text/plain; charset=utf-8\n"
-    "Content-Transfer-Encoding: 8bit\n"
-    "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-    "Generated-By: Babel ...\n"
-    <BLANKLINE>
-    #: base.py:83 templates/index.html:9
-    #: templates/index2.html:9
-    msgid "Home"
-    msgstr ""
-    <BLANKLINE>
-    #: base.py:84 templates/index.html:9
-    msgid "Accounts"
-    msgstr ""
-    <BLANKLINE>
-    >>>
-    """
-    
-    _first_author = ''
-    if first_author:
-        _first_author += first_author
-    if first_author_email:
-        _first_author += ' <%s>' % first_author_email
-
-    inlines = input_fileobj.readlines()
-    outlines = []
-    in_header = True
-    _date = datetime.now(LOCALTZ)
-    for index in range(len(inlines)):
-        if in_header:
-            if '# Translations template' in inlines[index]:
-                outlines.append('# %s translations for %s\n' % \
-                                (locale_obj.english_name, project))
-            elif '# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.' in inlines[index]:
-                if _first_author:
-                    outlines.append(
-                        '# %s, %s\n' % (_first_author, _date.strftime('%Y'))
-                    )
-                else:
-                    outlines.append(inlines[index])
-            elif '"PO-Revision-Date:' in inlines[index]:
-                outlines.append(
-                    '"PO-Revision-Date: %s\\n"\n' % \
-                    _date.strftime('%Y-%m-%d %H:%M%z')
-                )
-            elif '"Last-Translator:' in inlines[index]:
-                if _first_author:
-                    outlines.append(
-                        '"Last-Translator: %s\\n"\n' % _first_author
-                    )
-                else:
-                    outlines.append(inlines[index])
-            elif '"Content-Transfer-Encoding:' in inlines[index]:
-                outlines.append(inlines[index])
-                if '"Plural-Forms:' not in inlines[index+1]:
-                    outlines.append(
-                        '"Plural-Forms: nplurals=%s; plural=%s;\\n"\n' % plurals
-                    )
-            elif inlines[index].endswith('\\n"\n') and \
-                 inlines[index+1] == '\n':
-                in_header = False
-                outlines.append(inlines[index])
-            else:
-                outlines.append(inlines[index])
-        else:
-            outlines.extend(inlines[index:])
-            break
-    fileobj.writelines(outlines)
Copyright (C) 2012-2017 Edgewall Software