| 418 | """ |
| 419 | |
| 420 | def __init__(self, environment): |
| 421 | # shortcuts |
| 422 | c = lambda x: re.compile(x, re.M | re.S) |
| 423 | e = re.escape |
| 424 | |
| 425 | # lexing rules for tags |
| 426 | tag_rules = [ |
| 427 | (whitespace_re, TOKEN_WHITESPACE, None), |
| 428 | (float_re, TOKEN_FLOAT, None), |
| 429 | (integer_re, TOKEN_INTEGER, None), |
| 430 | (name_re, TOKEN_NAME, None), |
| 431 | (string_re, TOKEN_STRING, None), |
| 432 | (operator_re, TOKEN_OPERATOR, None) |
| 433 | ] |
| 434 | |
| 435 | # assemble the root lexing rule. because "|" is ungreedy |
| 436 | # we have to sort by length so that the lexer continues working |
| 437 | # as expected when we have parsing rules like <% for block and |
| 438 | # <%= for variables. (if someone wants asp like syntax) |
| 439 | # variables are just part of the rules if variable processing |
| 440 | # is required. |
| 441 | root_tag_rules = compile_rules(environment) |
| 442 | |
| 443 | # block suffix if trimming is enabled |
| 444 | block_suffix_re = environment.trim_blocks and '\\n?' or '' |
| 445 | |
| 446 | # strip leading spaces if lstrip_blocks is enabled |
| 447 | prefix_re = {} |
| 448 | if environment.lstrip_blocks: |
| 449 | # use '{%+' to manually disable lstrip_blocks behavior |
| 450 | no_lstrip_re = e('+') |
| 451 | # detect overlap between block and variable or comment strings |
| 452 | block_diff = c(r'^%s(.*)' % e(environment.block_start_string)) |
| 453 | # make sure we don't mistake a block for a variable or a comment |
| 454 | m = block_diff.match(environment.comment_start_string) |
| 455 | no_lstrip_re += m and r'|%s' % e(m.group(1)) or '' |
| 456 | m = block_diff.match(environment.variable_start_string) |
| 457 | no_lstrip_re += m and r'|%s' % e(m.group(1)) or '' |
| 458 | |
| 459 | # detect overlap between comment and variable strings |
| 460 | comment_diff = c(r'^%s(.*)' % e(environment.comment_start_string)) |
| 461 | m = comment_diff.match(environment.variable_start_string) |
| 462 | no_variable_re = m and r'(?!%s)' % e(m.group(1)) or '' |
| 463 | |
| 464 | lstrip_re = r'^[ \t]*' |
| 465 | block_prefix_re = r'%s%s(?!%s)|%s\+?' % ( |
| 466 | lstrip_re, |
| 467 | e(environment.block_start_string), |
| 468 | no_lstrip_re, |
| 469 | e(environment.block_start_string), |
| 470 | ) |
| 471 | comment_prefix_re = r'%s%s%s|%s\+?' % ( |
| 472 | lstrip_re, |
| 473 | e(environment.comment_start_string), |
| 474 | no_variable_re, |
| 475 | e(environment.comment_start_string), |
| 476 | ) |
| 477 | prefix_re['block'] = block_prefix_re |