|
17 | 17 | :license: BSD, see LICENSE for more details. |
18 | 18 | """ |
19 | 19 |
|
| 20 | +import io |
20 | 21 | import os |
21 | 22 | from os.path import relpath |
22 | 23 | import sys |
@@ -521,8 +522,10 @@ def extract_javascript(fileobj, keywords, comment_tags, options): |
521 | 522 | :param options: a dictionary of additional options (optional) |
522 | 523 | Supported options are: |
523 | 524 | * `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. |
526 | 529 | """ |
527 | 530 | from babel.messages.jslexer import Token, tokenize, unquote_string |
528 | 531 | funcname = message_lineno = None |
@@ -551,7 +554,11 @@ def extract_javascript(fileobj, keywords, comment_tags, options): |
551 | 554 | call_stack = 0 |
552 | 555 | token = Token('operator', ')', token.lineno) |
553 | 556 |
|
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 == '(': |
555 | 562 | if funcname: |
556 | 563 | message_lineno = token.lineno |
557 | 564 | call_stack += 1 |
@@ -643,3 +650,43 @@ def extract_javascript(fileobj, keywords, comment_tags, options): |
643 | 650 | funcname = token.value |
644 | 651 |
|
645 | 652 | 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