#!/usr/bin/env python2.7 import sys, os, re, json from lxml import etree, html import lxml.html.soupparser as soupparser BASEPATH = os.path.realpath(os.path.join(os.path.dirname(sys.argv[0]), '..')) INPUTPATH = os.path.realpath(sys.argv[1]) if not INPUTPATH.startswith(BASEPATH): raise IOError('File outside project path: ' + FILEPATH) FILEPATH = INPUTPATH[len(BASEPATH):].lstrip('/') OUTPUTPATH = os.path.join(sys.argv[2], FILEPATH[0:FILEPATH.rfind('.')] + '.c') namespaces = {'com': 'https://github.com/pradosoft/prado/com', 'prop': 'https://github.com/pradosoft/prado/prop', 'i18n': 'http://xml.zope.org/namespaces/i18n', 'tal': 'http://xml.zope.org/namespaces/tal'} prado_tag_regex = re.compile('<%.*%>') with open(INPUTPATH) as f: lines = f.readlines() parser = etree.XMLParser() parser.feed('\n') for line in lines: line = soupparser.unescape(prado_tag_regex.sub('', line).replace('->', '')).encode('utf-8') if not line.startswith(''); xml_content = parser.close() delim_regex = re.compile('(<%\[\s+|\s+]%>)') tag_open = False current_token = '' tokens = {} for lineno, line in enumerate(lines): linelabel = str(lineno+1) matches = delim_regex.split(line) for match in matches: if match.strip() == '<%[': if tag_open: raise ValueError('Nested tag in line: ' + linelabel) tag_open = True elif match.strip() == ']%>': if not tag_open: raise ValueError('Unexpected closing tag in line: ' + linelabel) tag_open = False if linelabel not in tokens: tokens[linelabel] = [] tokens[linelabel].append(current_token.strip()) current_token = '' else: if tag_open: current_token += match if tag_open: current_token += '\n' for ttranslate in xml_content.xpath('//com:TTranslate', namespaces=namespaces): token = ttranslate.text.strip() linelabel = str(ttranslate.sourceline-1) if linelabel not in tokens: tokens[linelabel] = [] tokens[linelabel].append(token) for taltag in xml_content.xpath('//*[@i18n:translate]', namespaces=namespaces): attrib = taltag.attrib['{%s}%s' % (namespaces['i18n'], 'translate')] if attrib.startswith('string:'): token = attrib[len('string:'):] else: for variable in taltag.xpath('//*[@i18n:name]', namespaces=namespaces): var_name = variable.attrib['{%s}%s' % (namespaces['i18n'], 'name')] variable.tail = ('{%s}' % (var_name)) + (variable.tail or '') parent = variable.getparent() prev = variable.getprevious() if prev is not None: prev.tail = (prev.tail or '') + variable.tail else: parent.text = (parent.text or '') + variable.tail parent.remove(variable) token = taltag.text.strip() linelabel = str(taltag.sourceline-1) if linelabel not in tokens: tokens[linelabel] = [] tokens[linelabel].append(token) if len(tokens): OUTPUTDIR = os.path.dirname(OUTPUTPATH) if not os.path.exists(OUTPUTDIR): try: os.makedirs(OUTPUTDIR) except OSError as e: if e.errno != errno.EEXIST: raise with open(OUTPUTPATH, 'w') as f: for line, token in tokens.iteritems(): for string in token: f.write('/* %s:%s */\n' % (FILEPATH, line)) f.write('gettext(%s);\n' % json.dumps(string)) f.write('\n')