def test_gettext(self): template = FileMock(b""" <div> {{ gettext('Foo') }} </div> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(result), [(3, u'gettext', u"Foo", [])])
def test_underscore(self): template = FileMock(b""" <div> {{ _("Bar") }} </div> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(result), [(3, '_', u'Bar', [])])
def test_no_messages(self): template = FileMock(b""" <div> <h1>Foo</h1> <p>Lore ipsum delore gettext() ...</p> </div> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(), list(result))
def test_directives_with_inner_colon_tag(self): template = FileMock(""" <div :text="gettext('Sometext')"> {{ gettext('Hello') }} </div> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertListEqual(list(result), [(2, u'gettext', u'Sometext', []), (3, u'gettext', u'Hello', [])])
def test_ngettext(self): template = FileMock(""" <div> {{ ngettext('Foo', 'Foos', 1) }} </div> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(result), [ (3, u'ngettext', (u"Foo", u"Foos"), []), ])
def test_commas(self): template = FileMock(b""" {{ gettext('Hello, User') }} {{ gettext("You're") }} {{ gettext("You\\"re") }} """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(result), [ (2, u'gettext', u'Hello, User', []), (3, u'gettext', u"You're", []), (4, u'gettext', u"You\"re", []), ])
def test_gettext_with_parameter(self): template = FileMock(b""" <li> {{ gettext('{number} season').replace("{number}", season) }} {{ gettext('Processed by filter')|somefilter }} {{ somefunc(gettext('Processed by function')) }} {{ gettext('Foo') + gettext('bar') }} </li> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(result), [ (3, u'gettext', u'{number} season', []), (4, u'gettext', u'Processed by filter', []), (5, u'gettext', u'Processed by function', []), (6, u'gettext', u'Foo', []), (6, u'gettext', u'bar', []), ])
def initialize_options(self): self.charset = 'utf-8' self.keywords = '' self._keywords = DEFAULT_KEYWORDS.copy() self.no_default_keywords = False self.mapping_file = None self.no_location = False self.omit_header = False self.output_file = None self.input_dirs = None self.width = None self.no_wrap = False self.sort_output = False self.sort_by_file = False self.msgid_bugs_address = None self.copyright_holder = None self.add_comments = None self._add_comments = [] self.strip_comments = False
def extract_extrajs(fileobj, keywords, comment_tags, options): """Extract template literal placeholders and filters from Javascript files. :param fileobj: the file-like the messages should be extracted from :param keywords: a list of keywords (i.e. function names) that should be recognize as translation functions :param comment_tags: a list of translator tags to search for and include in the results :param options: a dictionary of additional options (optional) :return: an iterator over ``(lineno, funcname, message, comments)`` :rtype: ``iterator`` """ encoding = options.get('encoding', 'utf-8') c = fileobj.read().decode(encoding=encoding) filtpat = re.compile('t\._f\("gettext"\)', re.UNICODE) c = filtpat.sub('gettext', c) comppat = re.compile(r'(\$\{gettext\((.*?)\)\})', re.UNICODE) c = comppat.sub(r'`+gettext(\g<2>)+`', c, re.UNICODE) for i in extract_javascript(BytesIO(c.encode(encoding=encoding)), DEFAULT_KEYWORDS.keys(), comment_tags, options): if i: yield (i[0], i[1], i[2], i[3])
def extract(self, argv): """Subcommand for extracting messages from source files and generating a POT file. :param argv: the command arguments """ parser = OptionParser(usage=self.usage % ('extract', 'dir1 <dir2> ...'), description=self.commands['extract']) parser.add_option('--charset', dest='charset', help='charset to use in the output (default ' '"%default")') parser.add_option('-k', '--keyword', dest='keywords', action='append', help='keywords to look for in addition to the ' 'defaults. You can specify multiple -k flags on ' 'the command line.') parser.add_option('--no-default-keywords', dest='no_default_keywords', action='store_true', help="do not include the default keywords") parser.add_option('--mapping', '-F', dest='mapping_file', help='path to the extraction mapping file') parser.add_option('--no-location', dest='no_location', action='store_true', help='do not include location comments with filename ' 'and line number') parser.add_option('--omit-header', dest='omit_header', action='store_true', help='do not include msgid "" entry in header') parser.add_option('-o', '--output', dest='output', help='path to the output POT file') parser.add_option('-w', '--width', dest='width', type='int', help="set output line width (default 76)") parser.add_option('--no-wrap', dest='no_wrap', action = 'store_true', help='do not break long message lines, longer than ' 'the output line width, into several lines') parser.add_option('--sort-output', dest='sort_output', action='store_true', help='generate sorted output (default False)') parser.add_option('--sort-by-file', dest='sort_by_file', action='store_true', help='sort output by file location (default False)') parser.add_option('--msgid-bugs-address', dest='msgid_bugs_address', metavar='EMAIL@ADDRESS', help='set report address for msgid') parser.add_option('--copyright-holder', dest='copyright_holder', help='set copyright holder in output') parser.add_option('--project', dest='project', help='set project name in output') parser.add_option('--version', dest='version', help='set project version in output') parser.add_option('--add-comments', '-c', dest='comment_tags', metavar='TAG', action='append', help='place comment block with TAG (or those ' 'preceding keyword lines) in output file. One ' 'TAG per argument call') parser.add_option('--strip-comment-tags', '-s', dest='strip_comment_tags', action='store_true', help='Strip the comment tags from the comments.') parser.set_defaults(charset='utf-8', keywords=[], no_default_keywords=False, no_location=False, omit_header = False, width=None, no_wrap=False, sort_output=False, sort_by_file=False, comment_tags=[], strip_comment_tags=False) options, args = parser.parse_args(argv) if not args: parser.error('incorrect number of arguments') if options.output not in (None, '-'): outfile = open(options.output, 'wb') else: outfile = sys.stdout keywords = DEFAULT_KEYWORDS.copy() if options.no_default_keywords: if not options.keywords: parser.error('you must specify new keywords if you disable the ' 'default ones') keywords = {} if options.keywords: keywords.update(parse_keywords(options.keywords)) if options.mapping_file: fileobj = open(options.mapping_file, 'U') try: method_map, options_map = parse_mapping(fileobj) finally: fileobj.close() else: method_map = DEFAULT_MAPPING options_map = {} if options.width and options.no_wrap: parser.error("'--no-wrap' and '--width' are mutually exclusive.") elif not options.width and not options.no_wrap: options.width = 76 if options.sort_output and options.sort_by_file: parser.error("'--sort-output' and '--sort-by-file' are mutually " "exclusive") try: catalog = Catalog(project=options.project, version=options.version, msgid_bugs_address=options.msgid_bugs_address, copyright_holder=options.copyright_holder, charset=options.charset) for dirname in args: if not os.path.isdir(dirname): parser.error('%r is not a directory' % dirname) def callback(filename, method, options): if method == 'ignore': return filepath = os.path.normpath(os.path.join(dirname, filename)) optstr = '' if options: optstr = ' (%s)' % ', '.join(['%s="%s"' % (k, v) for k, v in options.items()]) self.log.info('extracting messages from %s%s', filepath, optstr) extracted = extract_from_dir(dirname, method_map, options_map, keywords, options.comment_tags, callback=callback, strip_comment_tags= options.strip_comment_tags) for filename, lineno, message, comments in extracted: filepath = os.path.normpath(os.path.join(dirname, filename)) catalog.add(message, None, [(filepath, lineno)], auto_comments=comments) if options.output not in (None, '-'): self.log.info('writing PO template file to %s' % options.output) write_po(outfile, catalog, width=options.width, no_location=options.no_location, omit_header=options.omit_header, sort_output=options.sort_output, sort_by_file=options.sort_by_file) finally: if options.output: outfile.close()
def finalize_options(self): if self.input_dirs: if not self.input_paths: self.input_paths = self.input_dirs else: raise DistutilsOptionError( 'input-dirs and input-paths are mutually exclusive') if self.no_default_keywords: keywords = {} else: keywords = DEFAULT_KEYWORDS.copy() keywords.update(parse_keywords(listify_value(self.keywords))) self.keywords = keywords if not self.keywords: raise DistutilsOptionError('you must specify new keywords if you ' 'disable the default ones') if not self.output_file: raise DistutilsOptionError('no output file specified') if self.no_wrap and self.width: raise DistutilsOptionError( "'--no-wrap' and '--width' are mutually " "exclusive") if not self.no_wrap and not self.width: self.width = 76 elif self.width is not None: self.width = int(self.width) if self.sort_output and self.sort_by_file: raise DistutilsOptionError("'--sort-output' and '--sort-by-file' " "are mutually exclusive") if self.input_paths: if isinstance(self.input_paths, string_types): self.input_paths = re.split(',\s*', self.input_paths) elif self.distribution is not None: self.input_paths = dict.fromkeys([ k.split('.', 1)[0] for k in (self.distribution.packages or ()) ]).keys() else: self.input_paths = [] if not self.input_paths: raise DistutilsOptionError( "no input files or directories specified") for path in self.input_paths: if not os.path.exists(path): raise DistutilsOptionError("Input path: %s does not exist" % path) self.add_comments = listify_value(self.add_comments or (), ",") if self.distribution: if not self.project: self.project = self.distribution.get_name() if not self.version: self.version = self.distribution.get_version() if self.add_location == 'never': self.no_location = True elif self.add_location == 'file': self.include_lineno = False
def generate_keywords(): """Generates gettext keywords list""" keywords = set(BABEL_KEYWORDS.keys()) keywords.add('_lazy') # FIXME: Add other keywords here return list(keywords)
def finalize_options(self): if self.input_dirs: if not self.input_paths: self.input_paths = self.input_dirs else: raise DistutilsOptionError( 'input-dirs and input-paths are mutually exclusive' ) if self.no_default_keywords: keywords = {} else: keywords = DEFAULT_KEYWORDS.copy() keywords.update(parse_keywords(listify_value(self.keywords))) self.keywords = keywords if not self.keywords: raise DistutilsOptionError('you must specify new keywords if you ' 'disable the default ones') if not self.output_file: raise DistutilsOptionError('no output file specified') if self.no_wrap and self.width: raise DistutilsOptionError("'--no-wrap' and '--width' are mutually " "exclusive") if not self.no_wrap and not self.width: self.width = 76 elif self.width is not None: self.width = int(self.width) if self.sort_output and self.sort_by_file: raise DistutilsOptionError("'--sort-output' and '--sort-by-file' " "are mutually exclusive") if self.input_paths: if isinstance(self.input_paths, string_types): self.input_paths = re.split(',\s*', self.input_paths) elif self.distribution is not None: self.input_paths = dict.fromkeys([ k.split('.', 1)[0] for k in (self.distribution.packages or ()) ]).keys() else: self.input_paths = [] if not self.input_paths: raise DistutilsOptionError("no input files or directories specified") for path in self.input_paths: if not os.path.exists(path): raise DistutilsOptionError("Input path: %s does not exist" % path) self.add_comments = listify_value(self.add_comments or (), ",") if self.distribution: if not self.project: self.project = self.distribution.get_name() if not self.version: self.version = self.distribution.get_version()
def test_token_without_content(self): template = FileMock(b""" {{ }} """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(result), [])
def extract(self, argv): """Subcommand for extracting messages from source files and generating a POT file. :param argv: the command arguments """ parser = OptionParser(usage=self.usage % ('extract', 'dir1 <dir2> ...'), description=self.commands['extract']) parser.add_option('--charset', dest='charset', help='charset to use in the output (default ' '"%default")') parser.add_option('-k', '--keyword', dest='keywords', action='append', help='keywords to look for in addition to the ' 'defaults. You can specify multiple -k flags on ' 'the command line.') parser.add_option('--no-default-keywords', dest='no_default_keywords', action='store_true', help="do not include the default keywords") parser.add_option('--mapping', '-F', dest='mapping_file', help='path to the extraction mapping file') parser.add_option('--no-location', dest='no_location', action='store_true', help='do not include location comments with filename ' 'and line number') parser.add_option('--omit-header', dest='omit_header', action='store_true', help='do not include msgid "" entry in header') parser.add_option('-o', '--output', dest='output', help='path to the output POT file') parser.add_option('-w', '--width', dest='width', type='int', help="set output line width (default 76)") parser.add_option('--no-wrap', dest='no_wrap', action='store_true', help='do not break long message lines, longer than ' 'the output line width, into several lines') parser.add_option('--sort-output', dest='sort_output', action='store_true', help='generate sorted output (default False)') parser.add_option('--sort-by-file', dest='sort_by_file', action='store_true', help='sort output by file location (default False)') parser.add_option('--msgid-bugs-address', dest='msgid_bugs_address', metavar='EMAIL@ADDRESS', help='set report address for msgid') parser.add_option('--copyright-holder', dest='copyright_holder', help='set copyright holder in output') parser.add_option('--project', dest='project', help='set project name in output') parser.add_option('--version', dest='version', help='set project version in output') parser.add_option('--add-comments', '-c', dest='comment_tags', metavar='TAG', action='append', help='place comment block with TAG (or those ' 'preceding keyword lines) in output file. One ' 'TAG per argument call') parser.add_option('--strip-comment-tags', '-s', dest='strip_comment_tags', action='store_true', help='Strip the comment tags from the comments.') parser.set_defaults(charset='utf-8', keywords=[], no_default_keywords=False, no_location=False, omit_header = False, width=None, no_wrap=False, sort_output=False, sort_by_file=False, comment_tags=[], strip_comment_tags=False) options, args = parser.parse_args(argv) if not args: parser.error('incorrect number of arguments') keywords = DEFAULT_KEYWORDS.copy() if options.no_default_keywords: if not options.keywords: parser.error('you must specify new keywords if you disable the ' 'default ones') keywords = {} if options.keywords: keywords.update(parse_keywords(options.keywords)) if options.mapping_file: with open(options.mapping_file, 'U') as fileobj: method_map, options_map = parse_mapping(fileobj) else: method_map = DEFAULT_MAPPING options_map = {} if options.width and options.no_wrap: parser.error("'--no-wrap' and '--width' are mutually exclusive.") elif not options.width and not options.no_wrap: options.width = 76 if options.sort_output and options.sort_by_file: parser.error("'--sort-output' and '--sort-by-file' are mutually " "exclusive") catalog = Catalog(project=options.project, version=options.version, msgid_bugs_address=options.msgid_bugs_address, copyright_holder=options.copyright_holder, charset=options.charset) data_iter = ((dirname, method_map, options_map) for dirname in args) try: operations.extract_to_catalog(catalog, data_iter, keywords, options.comment_tags, options.strip_comment_tags, log=self.log) except operations.ConfigureError as e: parser.error(e.message) catalog_charset = catalog.charset if options.output not in (None, '-'): self.log.info('writing PO template file to %s' % options.output) outfile = open(options.output, 'wb') close_output = True else: outfile = sys.stdout # This is a bit of a hack on Python 3. stdout is a text stream so # we need to find the underlying file when we write the PO. In # later versions of Babel we want the write_po function to accept # text or binary streams and automatically adjust the encoding. if not PY2 and hasattr(outfile, 'buffer'): catalog.charset = outfile.encoding outfile = outfile.buffer.raw close_output = False try: write_po(outfile, catalog, width=options.width, no_location=options.no_location, omit_header=options.omit_header, sort_output=options.sort_output, sort_by_file=options.sort_by_file) finally: if close_output: outfile.close() catalog.charset = catalog_charset
def test_empty_template(self): template = FileMock("") result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertEqual(list(), list(result))
def setup(self): self.keywords = DEFAULT_KEYWORDS.keys()
def extract(self, argv): """Subcommand for extracting messages from source files and generating a POT file. :param argv: the command arguments """ parser = OptionParser(usage=self.usage % ('extract', 'dir1 <dir2> ...'), description=self.commands['extract']) parser.add_option('--charset', dest='charset', help='charset to use in the output (default ' '"%default")') parser.add_option('-k', '--keyword', dest='keywords', action='append', help='keywords to look for in addition to the ' 'defaults. You can specify multiple -k flags on ' 'the command line.') parser.add_option('--no-default-keywords', dest='no_default_keywords', action='store_true', help="do not include the default keywords") parser.add_option('--mapping', '-F', dest='mapping_file', help='path to the extraction mapping file') parser.add_option('--no-location', dest='no_location', action='store_true', help='do not include location comments with filename ' 'and line number') parser.add_option('--omit-header', dest='omit_header', action='store_true', help='do not include msgid "" entry in header') parser.add_option('-o', '--output', dest='output', help='path to the output POT file') parser.add_option('-w', '--width', dest='width', type='int', help="set output line width (default 76)") parser.add_option('--no-wrap', dest='no_wrap', action = 'store_true', help='do not break long message lines, longer than ' 'the output line width, into several lines') parser.add_option('--sort-output', dest='sort_output', action='store_true', help='generate sorted output (default False)') parser.add_option('--sort-by-file', dest='sort_by_file', action='store_true', help='sort output by file location (default False)') parser.add_option('--msgid-bugs-address', dest='msgid_bugs_address', metavar='EMAIL@ADDRESS', help='set report address for msgid') parser.add_option('--copyright-holder', dest='copyright_holder', help='set copyright holder in output') parser.add_option('--project', dest='project', help='set project name in output') parser.add_option('--version', dest='version', help='set project version in output') parser.add_option('--add-comments', '-c', dest='comment_tags', metavar='TAG', action='append', help='place comment block with TAG (or those ' 'preceding keyword lines) in output file. One ' 'TAG per argument call') parser.add_option('--strip-comment-tags', '-s', dest='strip_comment_tags', action='store_true', help='Strip the comment tags from the comments.') parser.set_defaults(charset='utf-8', keywords=[], no_default_keywords=False, no_location=False, omit_header = False, width=None, no_wrap=False, sort_output=False, sort_by_file=False, comment_tags=[], strip_comment_tags=False) options, args = parser.parse_args(argv) if not args: parser.error('incorrect number of arguments') if options.output not in (None, '-'): outfile = open(options.output, 'wb') else: outfile = sys.stdout keywords = DEFAULT_KEYWORDS.copy() if options.no_default_keywords: if not options.keywords: parser.error('you must specify new keywords if you disable the ' 'default ones') keywords = {} if options.keywords: keywords.update(parse_keywords(options.keywords)) if options.mapping_file: fileobj = open(options.mapping_file, 'U') try: method_map, options_map = parse_mapping(fileobj) finally: fileobj.close() else: method_map = DEFAULT_MAPPING options_map = {} if options.width and options.no_wrap: parser.error("'--no-wrap' and '--width' are mutually exclusive.") elif not options.width and not options.no_wrap: options.width = 76 if options.sort_output and options.sort_by_file: parser.error("'--sort-output' and '--sort-by-file' are mutually " "exclusive") try: catalog = Catalog(project=options.project, version=options.version, msgid_bugs_address=options.msgid_bugs_address, copyright_holder=options.copyright_holder, charset=options.charset) for dirname in args: if not os.path.isdir(dirname): parser.error('%r is not a directory' % dirname) def callback(filename, method, options): if method == 'ignore': return filepath = os.path.normpath(os.path.join(dirname, filename)) optstr = '' if options: optstr = ' (%s)' % ', '.join(['%s="%s"' % (k, v) for k, v in options.items()]) self.log.info('extracting messages from %s%s', filepath, optstr) extracted = extract_from_dir(dirname, method_map, options_map, keywords, options.comment_tags, callback=callback, strip_comment_tags= options.strip_comment_tags) for filename, lineno, message, comments, context in extracted: filepath = os.path.normpath(os.path.join(dirname, filename)) catalog.add(message, None, [(filepath, lineno)], auto_comments=comments, context=context) if options.output not in (None, '-'): self.log.info('writing PO template file to %s' % options.output) write_po(outfile, catalog, width=options.width, no_location=options.no_location, omit_header=options.omit_header, sort_output=options.sort_output, sort_by_file=options.sort_by_file) finally: if options.output: outfile.close()
def setup(self): self.keywords = list(DEFAULT_KEYWORDS.keys())
def test_colon_directives(self): template = FileMock(b""" <div :html="gettext('Sometext')"></div> """) result = extract_vue(template, DEFAULT_KEYWORDS.keys(), [], TEST_OPTIONS) self.assertListEqual(list(result), [(2, u'gettext', u'Sometext', [])])