def test_dynamic_msgids(self):
     sample_source = """
         <p i18n:translate="">
           Some
           <span tal:replace="string:strange">dynamic</span>
           text.
         </p>
         <p i18n:translate="">
           A <a tal:attributes="href path:dynamic">link</a>.
         </p>
     """
     p = HTMLTALParser()
     p.parseString(sample_source)
     program, macros = p.getCode()
     engine = POEngine()
     engine.file = 'sample_source'
     POTALInterpreter(program,
                      macros,
                      engine,
                      stream=StringIO(),
                      metal=False)()
     msgids = []
     for domain in engine.catalog.values():
         msgids += list(domain)
     msgids.sort()
     self.assertEqual(msgids, [
         'A <a href="${DYNAMIC_CONTENT}">link</a>.',
         'Some ${DYNAMIC_CONTENT} text.'
     ])
Beispiel #2
0
 def test_dynamic_msgids(self):
     sample_source = """
         <p i18n:translate="">
           Some
           <span tal:replace="string:strange">dynamic</span>
           text.
         </p>
         <p i18n:translate="">
           A <a tal:attributes="href path:dynamic">link</a>.
         </p>
     """
     p = HTMLTALParser()
     p.parseString(sample_source)
     program, macros = p.getCode()
     engine = POEngine()
     engine.file = 'sample_source'
     POTALInterpreter(program, macros, engine, stream=StringIO(),
                      metal=False)()
     msgids = []
     for domain in engine.catalog.values():
         msgids += list(domain)
     msgids.sort()
     self.assertEqual(msgids,
         ['A <a href="${DYNAMIC_CONTENT}">link</a>.',
         'Some ${DYNAMIC_CONTENT} text.'])
Beispiel #3
0
    def test_translate(self):
        test_keys = ['foo', 'bar', 'blarf', 'washington']

        engine = POEngine()
        engine.file = 'foo.pt'
        for key in test_keys:
            engine.translate(key, 'domain')

        for key in test_keys:
            self.assertTrue(key in engine.catalog['domain'],
                        "POEngine catalog does not properly store message ids"
                        )
    def test_translate(self):
        test_keys = ['foo', 'bar', 'blarf', 'washington']

        engine = POEngine()
        engine.file = 'foo.pt'
        for key in test_keys:
            engine.translate(key, 'domain')

        for key in test_keys:
            self.assertIn(
                key, engine.catalog['domain'],
                "POEngine catalog does not properly store message ids")
Beispiel #5
0
def tal_strings(dir, domain="zope", include_default_domain=False, exclude=()):
    """Retrieve all TAL messages from `dir` that are in the `domain`.
    """
    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    import sys
    # i18n patch if templates using special characters
    reload(sys)
    sys.setdefaultencoding('UTF8')
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    for filename in (find_files(dir, '*.*pt', exclude=tuple(exclude)) +
                     find_files(dir, '*.html', exclude=tuple(exclude)) +
                     find_files(dir, '*.kupu', exclude=tuple(exclude)) +
                     find_files(dir, '*.pox', exclude=tuple(exclude)) +
                     find_files(dir, '*.xsl', exclude=tuple(exclude))):
        try:
            engine.file = filename
            name, ext = os.path.splitext(filename)
            if ext == '.html' or ext.endswith('pt'):
                p = HTMLTALParser()
            else:
                p = TALParser()
            p.parseFile(filename)
            program, macros = p.getCode()
            POTALInterpreter(program, macros, engine, stream=Devnull(),
                             metal=False)()
        except:  # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not domain in engine.catalog:
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        catalog.update(engine.catalog['default'])
    for msgid, locations in catalog.items():
        catalog[msgid] = [(l[0], l[1][0]) for l in locations]
    return catalog
Beispiel #6
0
def tal_strings(dir, domain="zope", include_default_domain=False, exclude=()):
    """Retrieve all TAL messages from `dir` that are in the `domain`.
    """
    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    for filename in (find_files(dir, '*.*pt', exclude=tuple(exclude)) +
                     find_files(dir, '*.html', exclude=tuple(exclude)) +
                     find_files(dir, '*.kupu', exclude=tuple(exclude)) +
                     find_files(dir, '*.pox', exclude=tuple(exclude)) +
                     find_files(dir, '*.xsl', exclude=tuple(exclude))):
        try:
            engine.file = filename
            name, ext = os.path.splitext(filename)
            if ext == '.html' or ext.endswith('pt'):
                p = HTMLTALParser()
            else:
                p = TALParser()
            p.parseFile(filename)
            program, macros = p.getCode()
            POTALInterpreter(program,
                             macros,
                             engine,
                             stream=Devnull(),
                             metal=False)()
        except:  # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not domain in engine.catalog:
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        catalog.update(engine.catalog['default'])
    for msgid, locations in catalog.items():
        catalog[msgid] = [(l[0], l[1][0]) for l in locations]
    return catalog
 def test_potalinterpreter_translate_default(self):
     sample_source = '<p i18n:translate="">text</p>'
     p = HTMLTALParser()
     p.parseString(sample_source)
     program, macros = p.getCode()
     engine = POEngine()
     engine.file = 'sample_source'
     interpreter = POTALInterpreter(
         program, macros, engine, stream=StringIO(), metal=False)
     # We simply call this, to make sure we don't get a NameError
     # for 'unicode' in python 3.
     # The return value (strangely: 'x') is not interesting here.
     interpreter.translate('text')
     msgids = []
     for domain in engine.catalog.values():
         msgids += list(domain)
     self.assertIn('text', msgids)
 def test_translate_existing(self):
     engine = POEngine()
     # This tries to reproduce a big surfacing in a template of
     # PloneSoftwareCenter when using the i18ndude package to
     # extract translatable strings, which uses zope.tal.  The
     # relevant html snippet is this:
     #
     # <a href="#" title="Read more&hellip;"
     #    i18n:attributes="title label_read_more"
     #    tal:attributes="href release/absolute_url">
     #    <span i18n:translate="label_read_more">Read more&hellip;</span>
     # </a>
     #
     # Due to the different ways that i18n:attributes and
     # i18n:translate are handled, the attribute gets passed to the
     # translate method with the html entity interpreted as a
     # unicode, and the i18n:translate gets passed as a simple
     # string with the html entity intact.  That may need a fix
     # elsewhere, but at the moment it gives a warning.  The very
     # least we can do is make sure that this does not give a
     # UnicodeDecodeError, which is what we test here.
     engine.file = 'psc_release_listing.pt'
     # position is position in file.
     engine.translate('foo',
                      'domain',
                      default=u'Read more\u2026',
                      position=7)
     # Adding the same key with the same default is fine.
     engine.translate('foo',
                      'domain',
                      default=u'Read more\u2026',
                      position=13)
     # Adding the same key with a different default is bad and
     # triggers a warning.
     with warnings.catch_warnings(record=True) as log:
         warnings.simplefilter("always")
         engine.translate('foo',
                          'domain',
                          default='Read still more&hellip;',
                          position=42)
         self.assertEqual(len(log), 1)
         message = log[0].message
         with tempfile.TemporaryFile('w+') as printfile:
             print(message, file=printfile)
             printfile.seek(0)
             self.assertTrue("already exists with a different default" in
                             printfile.read())
 def test_potalinterpreter_translate_default(self):
     sample_source = '<p i18n:translate="">text</p>'
     p = HTMLTALParser()
     p.parseString(sample_source)
     program, macros = p.getCode()
     engine = POEngine()
     engine.file = 'sample_source'
     interpreter = POTALInterpreter(program,
                                    macros,
                                    engine,
                                    stream=StringIO(),
                                    metal=False)
     # We simply call this, to make sure we don't get a NameError
     # for 'unicode' in python 3.
     # The return value (strangely: 'x') is not interesting here.
     interpreter.translate('text')
     msgids = []
     for domain in engine.catalog.values():
         msgids += list(domain)
     self.assertIn('text', msgids)
Beispiel #10
0
def tal_strings(dir, domain="zope", include_default_domain=False):
    """Retrieve all TAL messages from `dir` that are in the `domain`.
    """
    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    for filename in find_files(dir, '*.pt'):
        try:
            engine.file = filename
            p = HTMLTALParser()
            p.parseFile(filename)
            program, macros = p.getCode()
            POTALInterpreter(program, macros, engine, stream=Devnull(),
                             metal=False)()
        except: # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not engine.catalog.has_key(domain):
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        catalog.update(engine.catalog['zope'])
    for msgid, locations in catalog.items():
        catalog[msgid] = map(lambda l: (l[0], l[1][0]), locations)
    return catalog
Beispiel #11
0
 def test_translate_existing(self):
     engine = POEngine()
     # This tries to reproduce a big surfacing in a template of
     # PloneSoftwareCenter when using the i18ndude package to
     # extract translatable strings, which uses zope.tal.  The
     # relevant html snippet is this:
     #
     # <a href="#" title="Read more&hellip;"
     #    i18n:attributes="title label_read_more"
     #    tal:attributes="href release/absolute_url">
     #    <span i18n:translate="label_read_more">Read more&hellip;</span>
     # </a>
     #
     # Due to the different ways that i18n:attributes and
     # i18n:translate are handled, the attribute gets passed to the
     # translate method with the html entity interpreted as a
     # unicode, and the i18n:translate gets passed as a simple
     # string with the html entity intact.  That may need a fix
     # elsewhere, but at the moment it gives a warning.  The very
     # least we can do is make sure that this does not give a
     # UnicodeDecodeError, which is what we test here.
     engine.file = 'psc_release_listing.pt'
     # position is position in file.
     engine.translate('foo', 'domain',
                      default=u'Read more\u2026', position=7)
     # Adding the same key with the same default is fine.
     engine.translate('foo', 'domain',
                      default=u'Read more\u2026', position=13)
     # Adding the same key with a different default is bad and
     # triggers a warning.
     with warnings.catch_warnings(record=True) as log:
         warnings.simplefilter("always")
         engine.translate('foo', 'domain',
                          default='Read still more&hellip;', position=42)
         self.assertEqual(len(log), 1)
         message = log[0].message
         with tempfile.TemporaryFile('w+') as printfile:
             print(message, file=printfile)
             printfile.seek(0)
             self.assertTrue("already exists with a different default"
                             in printfile.read())
Beispiel #12
0
def tal_strings(dir,
                domain="zope",
                include_default_domain=False,
                exclude=(),
                filePattern='*.pt'):
    """Retrieve all TAL messages from `dir` that are in the `domain`.

      >>> from zope.app.locales import extract
      >>> import tempfile
      >>> dir = tempfile.mkdtemp()

    Let's create a page template in the i18n domain ``test``:
      >>> testpt = open(os.path.join(dir, 'test.pt'), 'w')
      >>> testpt.write('<tal:block i18n:domain="test" i18n:translate="">test</tal:block>')
      >>> testpt.close()

    And now one in no domain:
      >>> nopt = open(os.path.join(dir, 'no.pt'), 'w')
      >>> nopt.write('<tal:block i18n:translate="">no domain</tal:block>')
      >>> nopt.close()

    Now let's find the strings for the domain ``test``:

      >>> extract.tal_strings(dir, domain='test', include_default_domain=True)
      {u'test': [('...test.pt', 1)], u'no domain': [('...no.pt', 1)]}

    And now an xml file
      >>> xml = open(os.path.join(dir, 'xml.pt'), 'w')
      >>> xml.write('''<?xml version="1.0" encoding="utf-8"?>
      ... <rss version="2.0"
      ...     i18n:domain="xml"
      ...     xmlns:i18n="http://xml.zope.org/namespaces/i18n"
      ...     xmlns:tal="http://xml.zope.org/namespaces/tal"
      ...     xmlns="http://purl.org/rss/1.0/modules/content/">
      ...  <channel>
      ...    <link i18n:translate="">Link Content</link>
      ...  </channel>
      ... </rss>
      ... ''')
      >>> xml.close()
      >>> extract.tal_strings(dir, domain='xml')
      {u'Link Content': [('...xml.pt', 8)]}

    We also provide a file with a different file ending:

      >>> testpt = open(os.path.join(dir, 'test.html'), 'w')
      >>> testpt.write('<tal:block i18n:domain="html" i18n:translate="">html</tal:block>')
      >>> testpt.close()

      >>> extract.tal_strings(dir, domain='html', include_default_domain=True,
      ...                     filePattern='*.html')
      {u'html': [('...test.html', 1)]}

    Cleanup

      >>> import shutil
      >>> shutil.rmtree(dir)
    """

    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    for filename in find_files(dir, filePattern, exclude=tuple(exclude)):
        f = file(filename, 'rb')
        start = f.read(6)
        f.close()
        if start.startswith('<?xml'):
            parserFactory = TALParser
        else:
            parserFactory = HTMLTALParser
        try:
            engine.file = filename
            p = parserFactory()
            p.parseFile(filename)
            program, macros = p.getCode()
            POTALInterpreter(program,
                             macros,
                             engine,
                             stream=Devnull(),
                             metal=False)()
        except:  # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not engine.catalog.has_key(domain):
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        defaultCatalog = engine.catalog.get('default')
        if defaultCatalog == None:
            engine.catalog['default'] = {}
        catalog.update(engine.catalog['default'])
    for msgid, locations in catalog.items():
        catalog[msgid] = map(lambda l: (l[0], l[1][0]), locations)
    return catalog
Beispiel #13
0
def tal_strings(dir, domain="zope", include_default_domain=False, exclude=()):
    """Retrieve all TAL messages from `dir` that are in the `domain`.
    """
    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.pagetemplate.pagetemplatefile import sniff_type
    from zope.pagetemplate.pagetemplatefile import XML_PREFIX_MAX_LENGTH
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    filenames = find_files(dir, '*.pt', exclude=tuple(exclude)) \
              + find_files(dir, '*.html', exclude=tuple(exclude)) \
              + find_files(dir, '*.xml', exclude=tuple(exclude))

    for filename in sorted(filenames):
        # This is taken from zope/pagetemplate/pagetemplatefile.py (r40504)
        f = open(filename, "rb")
        try:
            text = f.read(XML_PREFIX_MAX_LENGTH)
        except:
            f.close()
            raise
        type_ = sniff_type(text)
        if type_ == "text/xml":
            text += f.read()
        else:
            # For HTML, we really want the file read in text mode:
            f.close()
            f = open(filename)
            text = f.read()
        f.close()

        try:
            engine.file = filename
            if type_ != "text/xml":
                p = HTMLTALParser()
            else:
                p = TALParser()
            p.parseString(text)
            program, macros = p.getCode()
            POTALInterpreter(program, macros, engine, stream=Devnull(),
                             metal=False)()
        except: # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not engine.catalog.has_key(domain):
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        catalog.update(engine.catalog['zope'])
    for msgid, locations in catalog.items():
        catalog[msgid] = map(lambda l: (l[0], l[1][0]), locations)
    return catalog
Beispiel #14
0
def tal_strings(dir, domain="zope", include_default_domain=False, exclude=()):
    """Retrieve all TAL messages from `dir` that are in the `domain`.
    """
    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.pagetemplate.pagetemplatefile import sniff_type
    from zope.pagetemplate.pagetemplatefile import XML_PREFIX_MAX_LENGTH
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    filenames = find_files(dir, '*.pt', exclude=tuple(exclude)) \
              + find_files(dir, '*.html', exclude=tuple(exclude)) \
              + find_files(dir, '*.xml', exclude=tuple(exclude))

    for filename in sorted(filenames):
        # This is taken from zope/pagetemplate/pagetemplatefile.py (r40504)
        f = open(filename, "rb")
        try:
            text = f.read(XML_PREFIX_MAX_LENGTH)
        except:
            f.close()
            raise
        type_ = sniff_type(text)
        if type_ == "text/xml":
            text += f.read()
        else:
            # For HTML, we really want the file read in text mode:
            f.close()
            f = open(filename)
            text = f.read()
        f.close()

        try:
            engine.file = filename
            if type_ != "text/xml":
                p = HTMLTALParser()
            else:
                p = TALParser()
            p.parseString(text)
            program, macros = p.getCode()
            POTALInterpreter(program,
                             macros,
                             engine,
                             stream=Devnull(),
                             metal=False)()
        except:  # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not engine.catalog.has_key(domain):
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        defaultCatalog = engine.catalog.get('default')
        if defaultCatalog == None:
            engine.catalog['default'] = {}
        catalog.update(engine.catalog['default'])
    for msgid, locations in catalog.items():
        catalog[msgid] = map(lambda l: (l[0], l[1][0]), locations)
    return catalog
Beispiel #15
0
def tal_strings(dir,
                domain="zope",
                include_default_domain=False,
                exclude=(),
                filePattern='*.pt'):
    """Retrieve all TAL messages from `dir` that are in the `domain`.

      >>> from zope.app.locales import extract
      >>> import tempfile
      >>> dir = tempfile.mkdtemp()

    Let's create a page template in the i18n domain ``test``:
      >>> testpt = open(os.path.join(dir, 'test.pt'), 'w')
      >>> testpt.write('<tal:block i18n:domain="test" i18n:translate="">test</tal:block>')
      >>> testpt.close()

    And now one in no domain:
      >>> nopt = open(os.path.join(dir, 'no.pt'), 'w')
      >>> nopt.write('<tal:block i18n:translate="">no domain</tal:block>')
      >>> nopt.close()

    Now let's find the strings for the domain ``test``:

      >>> extract.tal_strings(dir, domain='test', include_default_domain=True)
      {u'test': [('...test.pt', 1)], u'no domain': [('...no.pt', 1)]}

    And now an xml file
      >>> xml = open(os.path.join(dir, 'xml.pt'), 'w')
      >>> xml.write('''<?xml version="1.0" encoding="utf-8"?>
      ... <rss version="2.0"
      ...     i18n:domain="xml"
      ...     xmlns:i18n="http://xml.zope.org/namespaces/i18n"
      ...     xmlns:tal="http://xml.zope.org/namespaces/tal"
      ...     xmlns="http://purl.org/rss/1.0/modules/content/">
      ...  <channel>
      ...    <link i18n:translate="">Link Content</link>
      ...  </channel>
      ... </rss>
      ... ''')
      >>> xml.close()
      >>> extract.tal_strings(dir, domain='xml')
      {u'Link Content': [('...xml.pt', 8)]}

    We also provide a file with a different file ending:

      >>> testpt = open(os.path.join(dir, 'test.html'), 'w')
      >>> testpt.write('<tal:block i18n:domain="html" i18n:translate="">html</tal:block>')
      >>> testpt.close()

      >>> extract.tal_strings(dir, domain='html', include_default_domain=True,
      ...                     filePattern='*.html')
      {u'html': [('...test.html', 1)]}

    Cleanup

      >>> import shutil
      >>> shutil.rmtree(dir)
    """

    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    engine = POEngine()

    class Devnull(object):
        def write(self, s):
            pass

    for filename in find_files(dir, filePattern, exclude=tuple(exclude)):
        f = file(filename,'rb')
        start = f.read(6)
        f.close()
        if start.startswith('<?xml'):
            parserFactory = TALParser
        else:
            parserFactory = HTMLTALParser
        try:
            engine.file = filename
            p = parserFactory()
            p.parseFile(filename)
            program, macros = p.getCode()
            POTALInterpreter(program, macros, engine, stream=Devnull(),
                             metal=False)()
        except: # Hee hee, I love bare excepts!
            print 'There was an error processing', filename
            traceback.print_exc()

    # See whether anything in the domain was found
    if not engine.catalog.has_key(domain):
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        defaultCatalog = engine.catalog.get('default')
        if defaultCatalog == None:
            engine.catalog['default'] = {}
        catalog.update(engine.catalog['default'])
    for msgid, locations in catalog.items():
        catalog[msgid] = map(lambda l: (l[0], l[1][0]), locations)
    return catalog
Beispiel #16
0
def tal_strings(dir, domain="zope", include_default_domain=False, exclude=()):
    """Retrieve all TAL messages from `dir` that are in the `domain`.
    """
    # We import zope.tal.talgettext here because we can't rely on the
    # right sys path until app_dir has run
    from zope.tal.talgettext import POEngine, POTALInterpreter
    from zope.tal.htmltalparser import HTMLTALParser
    from zope.tal.talparser import TALParser
    engine = POEngine()

    class Devnull(object):

        def write(self, s):
            pass

    for filename in (find_files(dir, '*.*pt', exclude=tuple(exclude)) +
                     find_files(dir, '*.html', exclude=tuple(exclude)) +
                     find_files(dir, '*.kupu', exclude=tuple(exclude)) +
                     find_files(dir, '*.pox', exclude=tuple(exclude)) +
                     find_files(dir, '*.xsl', exclude=tuple(exclude))):
        engine.file = filename
        name, ext = os.path.splitext(filename)
        # First try with standard zope.tal parsers.
        if ext == '.html' or ext.endswith('pt'):
            parser = HTMLTALParser()
        else:
            parser = TALParser()
        try:
            parser.parseFile(filename)
            program, macros = parser.getCode()
            POTALInterpreter(program, macros, engine, stream=Devnull(),
                             metal=False)()
        except KeyboardInterrupt:
            raise
        except:  # Hee hee, I love bare excepts!
            if ext == '.html' or ext.endswith('pt'):
                # We can have one retry with our own generator.
                gen = DudeGenerator(xml=0)
                parser = HTMLTALParser(gen=gen)
                try:
                    parser.parseFile(filename)
                    program, macros = parser.getCode()
                    POTALInterpreter(program, macros, engine, stream=Devnull(),
                                     metal=False)()
                except:  # Hee hee, I love bare excepts!
                    print 'There was an error processing', filename
                    traceback.print_exc()
            else:
                print 'There was an error processing', filename
                traceback.print_exc()

    # See whether anything in the domain was found
    if domain not in engine.catalog:
        return {}
    # We do not want column numbers.
    catalog = engine.catalog[domain].copy()
    # When the Domain is 'default', then this means that none was found;
    # Include these strings; yes or no?
    if include_default_domain:
        catalog.update(engine.catalog['default'])
    for msgid, locations in catalog.items():
        catalog[msgid] = [(l[0], l[1][0]) for l in locations]
    return catalog