Skip to content

Commit 28e7b15

Browse files
committed
Improved javascript template string expression extracting
1 parent 7ebdf5a commit 28e7b15

1 file changed

Lines changed: 50 additions & 3 deletions

File tree

babel/messages/extract.py

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
:license: BSD, see LICENSE for more details.
1818
"""
1919

20+
import io
2021
import os
2122
from os.path import relpath
2223
import sys
@@ -521,8 +522,10 @@ def extract_javascript(fileobj, keywords, comment_tags, options):
521522
:param options: a dictionary of additional options (optional)
522523
Supported options are:
523524
* `jsx` -- set to false to disable JSX/E4X support.
524-
* `template_string` -- set to false to disable ES6
525-
template string support.
525+
* `template_string` -- if `True`, supports gettext(`key`)
526+
* `parse_template_string` -- if `True` will parse the
527+
contents of javascript
528+
template strings.
526529
"""
527530
from babel.messages.jslexer import Token, tokenize, unquote_string
528531
funcname = message_lineno = None
@@ -551,7 +554,11 @@ def extract_javascript(fileobj, keywords, comment_tags, options):
551554
call_stack = 0
552555
token = Token('operator', ')', token.lineno)
553556

554-
if token.type == 'operator' and token.value == '(':
557+
if options.get('parse_template_string') and not funcname and token.type == 'template_string':
558+
for item in parse_template_string(token.value, fileobj, keywords, comment_tags, options):
559+
yield item
560+
561+
elif token.type == 'operator' and token.value == '(':
555562
if funcname:
556563
message_lineno = token.lineno
557564
call_stack += 1
@@ -643,3 +650,43 @@ def extract_javascript(fileobj, keywords, comment_tags, options):
643650
funcname = token.value
644651

645652
last_token = token
653+
654+
655+
def parse_template_string(template_string, fileobj, keywords, comment_tags, options):
656+
657+
prev_character = None
658+
level = 0
659+
inside_str = False
660+
expression_contents = ''
661+
662+
for character in template_string[1:-1]:
663+
664+
if not inside_str and character in ('"', "'", '`'):
665+
inside_str = character
666+
elif inside_str == character and prev_character != r'\\':
667+
inside_str = False
668+
669+
if level:
670+
expression_contents += character
671+
672+
if not inside_str:
673+
674+
if character == '{' and prev_character == '$':
675+
level += 1
676+
677+
elif level and character == '}':
678+
679+
level -= 1
680+
681+
if level == 0 and expression_contents:
682+
683+
expression_contents = expression_contents[0:-1]
684+
685+
fake_file_obj = io.BytesIO(expression_contents.encode())
686+
687+
for item in extract_javascript(fake_file_obj, keywords, comment_tags, options):
688+
yield item
689+
690+
expression_contents = ''
691+
692+
prev_character = character

0 commit comments

Comments
 (0)