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.' ])
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_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 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 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
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