Lex a string into chunks: >>> lex('hey') ['hey'] >>> lex('hey {{you}}') ['hey ', ('you', (1, 7))] >>> lex('hey {{') Traceback (most recent call last): ... TemplateError: No }} to finish last expression at line 1 column 7
(s, name=None, trim_whitespace=True, line_offset=0, delimiters=None)
| 558 | |
| 559 | |
| 560 | def lex(s, name=None, trim_whitespace=True, line_offset=0, delimiters=None): |
| 561 | """ |
| 562 | Lex a string into chunks: |
| 563 | |
| 564 | >>> lex('hey') |
| 565 | ['hey'] |
| 566 | >>> lex('hey {{you}}') |
| 567 | ['hey ', ('you', (1, 7))] |
| 568 | >>> lex('hey {{') |
| 569 | Traceback (most recent call last): |
| 570 | ... |
| 571 | TemplateError: No }} to finish last expression at line 1 column 7 |
| 572 | >>> lex('hey }}') |
| 573 | Traceback (most recent call last): |
| 574 | ... |
| 575 | TemplateError: }} outside expression at line 1 column 7 |
| 576 | >>> lex('hey {{ {{') |
| 577 | Traceback (most recent call last): |
| 578 | ... |
| 579 | TemplateError: {{ inside expression at line 1 column 10 |
| 580 | |
| 581 | """ |
| 582 | if delimiters is None: |
| 583 | delimiters = ( |
| 584 | Template.default_namespace["start_braces"], |
| 585 | Template.default_namespace["end_braces"], |
| 586 | ) |
| 587 | in_expr = False |
| 588 | chunks = [] |
| 589 | last = 0 |
| 590 | last_pos = (line_offset + 1, 1) |
| 591 | |
| 592 | token_re = re.compile( |
| 593 | rf"{re.escape(delimiters[0])}|{re.escape(delimiters[1])}" |
| 594 | ) |
| 595 | for match in token_re.finditer(s): |
| 596 | expr = match.group(0) |
| 597 | pos = find_position(s, match.end(), last, last_pos) |
| 598 | if expr == delimiters[0] and in_expr: |
| 599 | raise TemplateError( |
| 600 | f"{delimiters[0]} inside expression", position=pos, name=name |
| 601 | ) |
| 602 | elif expr == delimiters[1] and not in_expr: |
| 603 | raise TemplateError( |
| 604 | f"{delimiters[1]} outside expression", position=pos, name=name |
| 605 | ) |
| 606 | if expr == delimiters[0]: |
| 607 | part = s[last:match.start()] |
| 608 | if part: |
| 609 | chunks.append(part) |
| 610 | in_expr = True |
| 611 | else: |
| 612 | chunks.append((s[last: match.start()], last_pos)) |
| 613 | in_expr = False |
| 614 | last = match.end() |
| 615 | last_pos = pos |
| 616 | if in_expr: |
| 617 | raise TemplateError( |
no test coverage detected