-
Notifications
You must be signed in to change notification settings - Fork 14
Newline Fix #75
base: main
Are you sure you want to change the base?
Newline Fix #75
Conversation
nodes.py was returning a PlaintextNode upon encountering a carriage return and skipping the following newline character. Added check for '\r'.
Parser was missing newlines on Windows files as it was only checking for the line feed character ('\n'). This was causing it to return a PlaintextNode when encountering a carriage return ('\r'), causing all sorts of problems if the white space before the newline character didn't provide the correct level of indentation (such as collapsing all elements on a completely blank line and placing following content after the html element's end tag).
The way new line support usually works in Python is that |
It isn't in this case, because the file is being opened with codecs.open rather than open, which doesn't perform conversion on So with how it's working now, say you have a blank line between the head and body tags in your haml, and that blank line has no white space. The parser will return a PlaintextNode with an indentation of 0, closing all previously opened elements, and it will place the body tag after the closing html tag. It will only do this for a file with Windows line endings. It will render the same file normally if it's created with Unix line endings. (I actually like the behavior better like this, as long as all of your blank lines are indented to where they need to be. This way, blank lines after a tag will be placed after the closing tag in the rendered document rather than before it, and there's no longer the problem with duplicate newlines. The problem is that if you're not paying attention, one missing space on a blank line can completely screw up the output.) |
I guess I'd accidentally added white space to a couple empty lines when I last edited this, which is slightly ironic given the nature of the modification.
@@ -48,6 +48,16 @@ def read_node(stream, prev, compiler): | |||
if indent: | |||
indent = indent[0] * len(indent) | |||
|
|||
# empty lines with carriage returns are recorded as newlines on previous node | |||
# if followed by a newline, it is skipped | |||
if stream.text[stream.ptr] == '\r': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think it would be easier to understand this if it was happening at the stream level.. what if we added def is_newline()
and def read_newline()
to the Stream
class?
@AndrewHawes ah ok that makes sense - have added a comment |
The parser was only looking for the line feed character ('\n'), so when it encountered an empty line with a Windows-style newline beginning with a carriage return ('\r\n'), it would miss it and instead return a PlaintextNode. This would mess up the structure of the generated HTML if the indentation prior to the newline characters was incorrect. For example, a blank line with no indentation would collapse all previous elements and put the following content after the html closing tag.