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
|
||||
|
||||
import re
|
||||
|
||||
class Parser:
|
||||
"""Parser implementation for template files"""
|
||||
|
||||
@ -24,9 +26,8 @@ class Parser:
|
||||
self.emitter = emitter
|
||||
|
||||
# Internal state
|
||||
self.cur_line_contains_handlebars = False
|
||||
self.cur_line_contains_nonblank_literal = False
|
||||
self.cur_line_leading_ws = '' # Buffer for leading whitespace
|
||||
self.start_of_line = True
|
||||
self.cur_line_suppress_whitespace = False
|
||||
self.in_html = False
|
||||
|
||||
def parse(self) -> None:
|
||||
@ -191,27 +192,16 @@ class Parser:
|
||||
raise SyntaxError('Unexpected text outside page block')
|
||||
|
||||
if s.isspace():
|
||||
if not self.cur_line_contains_nonblank_literal:
|
||||
if '\n' in s:
|
||||
# End of line which contains only nonblank literals
|
||||
if self.cur_line_contains_handlebars:
|
||||
# Do not print the whitespace
|
||||
self.reset_new_line()
|
||||
return
|
||||
else:
|
||||
# Not sure yet whether we should print the space - add to whitespace buffer
|
||||
self.cur_line_leading_ws += s
|
||||
return
|
||||
if self.start_of_line:
|
||||
# Whitespace at start of line
|
||||
self.cur_line_suppress_whitespace = line_contains_only_ws_or_handlebars(s, self.buffer)
|
||||
|
||||
if not self.cur_line_suppress_whitespace:
|
||||
self.emitter.output_literal_string(s)
|
||||
else:
|
||||
self.commit_leading_ws()
|
||||
self.cur_line_contains_nonblank_literal = True
|
||||
self.emitter.output_literal_string(s)
|
||||
|
||||
# Conditionally output the literal string
|
||||
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)
|
||||
self.start_of_line = False
|
||||
|
||||
if '\n' in s:
|
||||
self.reset_new_line()
|
||||
@ -219,16 +209,29 @@ class Parser:
|
||||
def reset_new_line(self) -> None:
|
||||
"""Reset the internal state for a new line"""
|
||||
|
||||
self.cur_line_contains_handlebars = False
|
||||
self.cur_line_contains_nonblank_literal = 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 = ''
|
||||
self.start_of_line = True
|
||||
self.cur_line_suppress_whitespace = False
|
||||
|
||||
class SyntaxError(Exception):
|
||||
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