tdammers / ginger

A Haskell implementation of the Jinja template language.
MIT License
77 stars 13 forks source link

Implement whitespace control #8

Closed agreif closed 7 years ago

agreif commented 7 years ago

template: Hello, {{ name }},\nwelcome in {{ location|upper }}! result: Hello, Alice, welcome in WONDERLAND!

but if in the first line the variable is the last thing on the line, then the \n is removed:

template: Hello, {{ name }}\nwelcome in {{ location|upper }}! result: Hello, Alicewelcome in WONDERLAND!

is this a bug? Or Do I need another syntax for the variable closing token?

Alex.

agreif commented 7 years ago

it seems to be the same with the statement end token %}.

tdammers commented 7 years ago

This is by design, in order to match Jinja2's default behavior, as described here. Advanced whitespace control has not been implemented yet, with the exception of dashes to manually remove whitespace (the {%- and -%} flavors of tag delimiters). This mechanism works exactly the same for other curly-braced constructs (interpolations: {{- and -}}; and comments: {#- and -#}), and is handled in the parser.

Eventually, I would of course want this to be configurable as options to the parser, however I have limited time on my hands, and this is not very high on my priority list right now. Accepting the + flavor of opening/closing tags wouldn't be hard to implement; if this is important to you, feel free to either patch it in yourself, or ping me about it and I might look into it myself. Adding whitespace control options is going to be a bit more work, but should be somewhat straightforward as well.

tdammers commented 7 years ago

Implement whitespace control as described in http://jinja.pocoo.org/docs/2.9/templates/#whitespace-control:

agreif commented 7 years ago

Thanks for the explanation. Now I understand why ginger works like this. I only tested on http://jinja2test.tk/ and it seems that even they dont seem to adhere the defaults, and trailing newline is preserved

Hello {{name}}
foo

generates

Hello John
foo

In my situation I use ginger to generate haskell and hamlet code for yesod apps. Currently I always have to append a space (' ') at the end of lines which end with }} or %}. This is a totally ugly workaround. Being able to use 'keep_trailing_newline' would save my day.

tdammers commented 7 years ago

e35dd23 adds a keepTrailingNewline option that can be passed to the parser.

tdammers commented 7 years ago

1df5568 changes trailing newline behavior to match Jinja: only {% %} eats trailing newlines, {{ }} keeps them intact.

agreif commented 7 years ago

thanks for the quick change. with with 'poKeepTrailingNewline = False' the newlines are kept.

It seems that even with 'poKeepTrailingNewline = False' the following template Hello, {{ name }}\nwelcome in {{ location|upper }}!

keeps the newline too. So it is contrary to the jinja2 default, that you mentioned.

agreif commented 7 years ago

I found another issue: with 'poKeepTrailingNewline = True' the main template keeps the newline but the included templates still swallow it. Here is a sample... my template: line1: {{v1}}\nline2: {% include 'line2inc' %}\nline3: {{v2}}!\nline4: {% for i in [1,2,3] %}{{i}}{% endfor %}\nline5 with this include: {% for i in [1,2,3] %}{{i}}{% endfor %}\n(2nd inc line)

produces this: line1: v1 line2: 123(2nd inc line) line3: v2! line4: 123 line5

but it should keep the newline in front of '(2nd inc line)'

tdammers commented 7 years ago

It seems that even with 'poKeepTrailingNewline = False' the following template Hello, {{ name }}\nwelcome in {{ location|upper }}!

keeps the newline too. So it is contrary to the jinja2 default, that you mentioned.

Hmm, I followed the jinja2 documentation here, which only talks about blocks, not interpolations (what jinja calls 'variables'), so I made it swallow newlines only after %}, but not after }}. I'd have to check against actual jinja to confirm whether this is the correct interpretation.

I found another issue: with 'poKeepTrailingNewline = True' the main template keeps the newline but the included templates still swallow it.

Ah, this might be an actual bug. I'll move it to a separate issue if you don't mind.