Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP 🚧: Support Whitespace Control For all Tags and Objects #67

Closed

Conversation

Jcambass
Copy link
Contributor

@Jcambass Jcambass commented Apr 17, 2021

This patch is still very much WIP and a bit exploration but I opened it as a draft for visability and maybe gathering some needed inputs.

Also don't try to understand the random comments, that's just me trying to note my thoughts (which are very likely nonsense in many cases but I still want them to verify before just ignoring them :) ).

The major problems at the moment are:

  • for loops
  • capture tags
  • raw tags

See: #10

@Jcambass Jcambass force-pushed the whitespace_support_for_tags branch 10 times, most recently from d9bc98b to 974e81a Compare April 18, 2021 16:05
@edgurgel
Copy link
Owner

Thanks for starting this! I think it's the hardest part of rendering Liquid templates! Happy to help with anything I can

@Jcambass Jcambass force-pushed the whitespace_support_for_tags branch 3 times, most recently from 7e61313 to 1ef605e Compare April 24, 2021 09:05
@Jcambass
Copy link
Contributor Author

Jcambass commented Apr 24, 2021

@edgurgel Thanks for offering your help!

I will now first try to add test cases for every tag with (hopefully) all whitespace situations.
This makes some test case files such as the one for if tags quite big (see test case 114).

I hope that's ok with you. I though about generating those cases but I think it's clearer to understand with the explicit approach.

I will add some checkboxes for stuff that is working/not working once all test cases are here :)

@Jcambass Jcambass force-pushed the whitespace_support_for_tags branch 7 times, most recently from 23bb4ea to b0d9ce1 Compare May 13, 2021 16:31
@Jcambass Jcambass force-pushed the whitespace_support_for_tags branch from b0d9ce1 to 5f33dfb Compare June 2, 2021 05:54
Jcambass pushed a commit to Jcambass/solid that referenced this pull request Jun 2, 2021
While implementing [whitespace support](edgurgel#67) I came to the conclusion that it
makes sense to auto generate different whitespace trimming variants of
a given template to gain a good test coverage of edge cases while keeping test maintainable.

One problem I encountered, was that since the templates where generated
I didn't know the actual input that was used when comparing the render results of liquid and solid.

My solution was adding a new `assert_render` macro that renders the template in liquid and solid
and then compares them (as we do already with `cases_test`), but then includes the passed template in the assertion output if there is an missmatch.

I'm trying to keep the main patch for the whitespace support as small and revieable as possible.
Since this particular change can stand alone and IMHO makes also sense outside of the context of whitespace support I've opened this PR.

Sample output:
```
  1) test case 113 (:"Elixir.Solid.Integration.Cases.113Test")
     test/integration/cases_test.exs:17
     Render result was different!
     Input:
     {% if enabled? %}
     ON
     {% else %}
     OFF
     {% endif %}

     code:  liquid_output == solid_output
     left:  "\nON\n\n"
     right: "\nOFF\n\n"
     stacktrace:
       test/integration/cases_test.exs:21: (test)
```
Jcambass pushed a commit to Jcambass/solid that referenced this pull request Jun 2, 2021
While implementing [whitespace support](edgurgel#67) I came to the conclusion that it
makes sense to auto generate different whitespace trimming variants of
a given template to gain a good test coverage of edge cases while keeping test maintainable.

One problem I encountered, was that since the templates where generated
I didn't know the actual input that was used when comparing the render results of liquid and solid.

My solution was adding a new `assert_render` macro that renders the template in liquid and solid
and then compares them (as we do already with `cases_test`), but then includes the passed template in the assertion output if there is an missmatch.

I'm trying to keep the main patch for the whitespace support as small and revieable as possible.
Since this particular change can stand alone and IMHO makes also sense outside of the context of whitespace support I've opened this PR.

Sample output:
```
  1) test case 113 (:"Elixir.Solid.Integration.Cases.113Test")
     test/integration/cases_test.exs:17
     Render result was different!
     Input:
     {% if enabled? %}
     ON
     {% else %}
     OFF
     {% endif %}

     code:  liquid_output == solid_output
     left:  "\nON\n\n"
     right: "\nOFF\n\n"
     stacktrace:
       test/integration/cases_test.exs:21: (test)
```
@Jcambass
Copy link
Contributor Author

Jcambass commented Jul 6, 2021

I currently hit a wall with this PR.
It's mostly related to the way Solid does parsing and rendering compared to the approach the Liquid gem takes.
I will try to find some time to better explore and explain the differences between the two approaches but for now I just wanted to leave this comment for clarity on the current progress.

@edgurgel
Copy link
Owner

@Jcambass thanks for the heads-up. I will have a look at the PR this weekend and see if I can help somehow.

@Jcambass
Copy link
Contributor Author

Jcambass commented Jul 15, 2021

@edgurgel Sounds good. Be aware that it lacks some proper structure and direction.

I was switching the place where trimming happens multiple times up and down the layers but didn't find the right spot.

The liquid gem parses in a way where it operates more directly on the whole tag instead of first parsing it into clear datastructures like we do with nimbleparsec. It feels like there is some fancy term like small step semantics vs big steps semantics that might describe the difference but I'm not fully sure.

I have a hard time mapping the solution liquid applies to a solution that could work for solid while keeping the exact semantics without adding hardcased edge cases.

So before you get lost in this PR it might be better to have a look at liquids whitespace handling and think about how it conceptionally would transition to solid.

@Jcambass Jcambass force-pushed the whitespace_support_for_tags branch from 5f33dfb to ed55d22 Compare July 15, 2021 06:29
@edgurgel
Copy link
Owner

@Jcambass Here's an idea... what if we "annotate" the places where we must trim whitespaces and then on a second pass (after everything has been parsed and rendered we go through the whole rendered binary to trim the whitespaces?

Parse -> render -> trim whitespaces ? It's not super efficient but at it seems more feasible and at least the feature gets implemented? We could then in the future try to optimise it.

I haven't tried doing this as a separate step but I wonder if it would work 🤔

@Jcambass
Copy link
Contributor Author

Jcambass commented Sep 2, 2021

Closed in favor of #84.

@Jcambass Jcambass closed this Sep 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants