Fix detection of lines containing only whitespace and handlebars
Previous implementation failed for lines containing text after handlebars
This commit is contained in:
parent
8e97698b85
commit
ffd5ac52e7
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
from .emitter import Emitter
|
from .emitter import Emitter
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
"""Parser implementation for template files"""
|
"""Parser implementation for template files"""
|
||||||
|
|
||||||
@ -24,9 +26,8 @@ class Parser:
|
|||||||
self.emitter = emitter
|
self.emitter = emitter
|
||||||
|
|
||||||
# Internal state
|
# Internal state
|
||||||
self.cur_line_contains_handlebars = False
|
self.start_of_line = True
|
||||||
self.cur_line_contains_nonblank_literal = False
|
self.cur_line_suppress_whitespace = False
|
||||||
self.cur_line_leading_ws = '' # Buffer for leading whitespace
|
|
||||||
self.in_html = False
|
self.in_html = False
|
||||||
|
|
||||||
def parse(self) -> None:
|
def parse(self) -> None:
|
||||||
@ -191,27 +192,16 @@ class Parser:
|
|||||||
raise SyntaxError('Unexpected text outside page block')
|
raise SyntaxError('Unexpected text outside page block')
|
||||||
|
|
||||||
if s.isspace():
|
if s.isspace():
|
||||||
if not self.cur_line_contains_nonblank_literal:
|
if self.start_of_line:
|
||||||
if '\n' in s:
|
# Whitespace at start of line
|
||||||
# End of line which contains only nonblank literals
|
self.cur_line_suppress_whitespace = line_contains_only_ws_or_handlebars(s, self.buffer)
|
||||||
if self.cur_line_contains_handlebars:
|
|
||||||
# Do not print the whitespace
|
if not self.cur_line_suppress_whitespace:
|
||||||
self.reset_new_line()
|
self.emitter.output_literal_string(s)
|
||||||
return
|
|
||||||
else:
|
|
||||||
# Not sure yet whether we should print the space - add to whitespace buffer
|
|
||||||
self.cur_line_leading_ws += s
|
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
self.commit_leading_ws()
|
self.emitter.output_literal_string(s)
|
||||||
self.cur_line_contains_nonblank_literal = True
|
|
||||||
|
|
||||||
# Conditionally output the literal string
|
self.start_of_line = False
|
||||||
if not self.cur_line_contains_nonblank_literal and self.cur_line_contains_handlebars:
|
|
||||||
# If the current line contains handlebars and whitespace only, do not emit literal string
|
|
||||||
return
|
|
||||||
|
|
||||||
self.emitter.output_literal_string(s)
|
|
||||||
|
|
||||||
if '\n' in s:
|
if '\n' in s:
|
||||||
self.reset_new_line()
|
self.reset_new_line()
|
||||||
@ -219,16 +209,29 @@ class Parser:
|
|||||||
def reset_new_line(self) -> None:
|
def reset_new_line(self) -> None:
|
||||||
"""Reset the internal state for a new line"""
|
"""Reset the internal state for a new line"""
|
||||||
|
|
||||||
self.cur_line_contains_handlebars = False
|
self.start_of_line = True
|
||||||
self.cur_line_contains_nonblank_literal = False
|
self.cur_line_suppress_whitespace = False
|
||||||
self.cur_line_leading_ws = ''
|
|
||||||
|
|
||||||
def commit_leading_ws(self) -> None:
|
|
||||||
"""Commit cur_line_leading_ws buffer to output"""
|
|
||||||
|
|
||||||
if self.cur_line_leading_ws:
|
|
||||||
self.emitter.output_literal_string(self.cur_line_leading_ws)
|
|
||||||
self.cur_line_leading_ws = ''
|
|
||||||
|
|
||||||
class SyntaxError(Exception):
|
class SyntaxError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def line_contains_only_ws_or_handlebars(s: str, buffer: str) -> bool:
|
||||||
|
"""Return True if the given line contains only whitespace or handlebars"""
|
||||||
|
|
||||||
|
if not s.isspace():
|
||||||
|
return False
|
||||||
|
|
||||||
|
if '\n' in s:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Read until the next newline or EOF
|
||||||
|
stop_reading_idx = buffer.index('\n') + 1 if '\n' in buffer else len(buffer)
|
||||||
|
remaining_line = buffer[:stop_reading_idx]
|
||||||
|
|
||||||
|
# Remove all handlebars
|
||||||
|
text_in_remaining_line = re.sub(r'\{\{.*?\}\}|\{!.*?!\}|\{%.*?%\}|\{#.*?#\}', r'', remaining_line)
|
||||||
|
|
||||||
|
if not text_in_remaining_line:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return text_in_remaining_line.isspace()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user