Parser for stpl templates.
| 4418 | |
| 4419 | |
| 4420 | class StplParser(object): |
| 4421 | """ Parser for stpl templates. """ |
| 4422 | _re_cache = {} #: Cache for compiled re patterns |
| 4423 | |
| 4424 | # This huge pile of voodoo magic splits python code into 8 different tokens. |
| 4425 | # We use the verbose (?x) regex mode to make this more manageable |
| 4426 | |
| 4427 | _re_tok = r'''( |
| 4428 | [urbURB]* |
| 4429 | (?: ''(?!') |
| 4430 | |""(?!") |
| 4431 | |'{6} |
| 4432 | |"{6} |
| 4433 | |'(?:[^\\']|\\.)+?' |
| 4434 | |"(?:[^\\"]|\\.)+?" |
| 4435 | |'{3}(?:[^\\]|\\.|\n)+?'{3} |
| 4436 | |"{3}(?:[^\\]|\\.|\n)+?"{3} |
| 4437 | ) |
| 4438 | )''' |
| 4439 | |
| 4440 | _re_inl = _re_tok.replace(r'|\n', '') # We re-use this string pattern later |
| 4441 | |
| 4442 | _re_tok += r''' |
| 4443 | # 2: Comments (until end of line, but not the newline itself) |
| 4444 | |(\#.*) |
| 4445 | |
| 4446 | # 3: Open and close (4) grouping tokens |
| 4447 | |([\[\{\(]) |
| 4448 | |([\]\}\)]) |
| 4449 | |
| 4450 | # 5,6: Keywords that start or continue a python block (only start of line) |
| 4451 | |^([\ \t]*(?:if|for|while|with|try|def|class)\b) |
| 4452 | |^([\ \t]*(?:elif|else|except|finally)\b) |
| 4453 | |
| 4454 | # 7: Our special 'end' keyword (but only if it stands alone) |
| 4455 | |((?:^|;)[\ \t]*end[\ \t]*(?=(?:%(block_close)s[\ \t]*)?\r?$|;|\#)) |
| 4456 | |
| 4457 | # 8: A customizable end-of-code-block template token (only end of line) |
| 4458 | |(%(block_close)s[\ \t]*(?=\r?$)) |
| 4459 | |
| 4460 | # 9: And finally, a single newline. The 10th token is 'everything else' |
| 4461 | |(\r?\n) |
| 4462 | ''' |
| 4463 | |
| 4464 | # Match the start tokens of code areas in a template |
| 4465 | _re_split = r'''(?m)^[ \t]*(\\?)((%(line_start)s)|(%(block_start)s))''' |
| 4466 | # Match inline statements (may contain python strings) |
| 4467 | _re_inl = r'''%%(inline_start)s((?:%s|[^'"\n])*?)%%(inline_end)s''' % _re_inl |
| 4468 | |
| 4469 | # add the flag in front of the regexp to avoid Deprecation warning (see Issue #949) |
| 4470 | # verbose and dot-matches-newline mode |
| 4471 | _re_tok = '(?mx)' + _re_tok |
| 4472 | _re_inl = '(?mx)' + _re_inl |
| 4473 | |
| 4474 | |
| 4475 | default_syntax = '<% %> % {{ }}' |
| 4476 | |
| 4477 | def __init__(self, source, syntax=None, encoding='utf8'): |