Skip to content
This repository has been archived by the owner on Nov 5, 2021. It is now read-only.

Add basic language support for Liquid #128

Merged
merged 3 commits into from
May 11, 2021
Merged

Conversation

mattvague
Copy link
Contributor

@mattvague mattvague commented Apr 5, 2021

Using the Handlebars language implementation as a base, added support for Shopify's Liquid templating language.

One thing I wanted to ask is: what are the current best practices for languages that can implemented inside other languages? From what I can see in Handlebars, Markdown, etc is that basically they had to re-implement support for HTML as I did. I was wondering though if it'd be possible to instead extend for example the HTML or CSS language implementations and then use nextEmbedded to add support for Liquid?

Cheers! Looking forward to some feedback on my first contribution 😄

@ghost
Copy link

ghost commented Apr 5, 2021

CLA assistant check
All CLA requirements met.

@mattvague mattvague marked this pull request as ready for review April 5, 2021 00:05
@mattvague mattvague changed the title Add support for Liquid Add basic language support for Liquid Apr 5, 2021
@Prinzhorn
Copy link

Prinzhorn commented May 10, 2021

Neat, I'm using Liquid as well and wanted to look into this. Could you add a test for the white-space-controlling tags? E.g. {%- and -%} (https://shopify.github.io/liquid/basics/whitespace/)? Just from looking at your code I'm not sure they'd behave as expected. Note that they can be asymmetric (e.g. only trim on the left).

@Prinzhorn
Copy link

I was wondering though if it'd be possible to instead extend for example the HTML or CSS language implementations and then use nextEmbedded to add support for Liquid?

Liquid explicitly can be used for other things than HTML, which is why escape is not default:

Why you should use Liquid: You need a template engine which does HTML just as well as emails.

I personally am using Liquid in a completely different context, because it gives control about whitespace and thus is suited to render arbitrary text based content.

I think this is a general question if templating languages should have both a liquid and liquid-html version in Monaco (same for handlebars maybe)? I personally don't need or want HTML syntax highlighting in my Liquid templates.

@alexdima
Copy link
Member

@mattvague The reason some of these rules get repeated in Monarch is because Monarch does not support injections like for example Textmate does.

@Prinzhorn I recommend that we merge this PR in and then that we tackle subsequent issues in separate issues/PRs.

@alexdima alexdima added this to the April 2021 milestone May 11, 2021
@alexdima alexdima merged commit ab8e37a into microsoft:main May 11, 2021
@mattvague
Copy link
Contributor Author

Thanks guys!

@mattvague
Copy link
Contributor Author

Neat, I'm using Liquid as well and wanted to look into this. Could you add a test for the white-space-controlling tags? E.g. {%- and -%} (https://shopify.github.io/liquid/basics/whitespace/)? Just from looking at your code I'm not sure they'd behave as expected. Note that they can be asymmetric (e.g. only trim on the left).

Can def do that in a followup PR (can't promise when though).

I think this is a general question if templating languages should have both a liquid and liquid-html version in Monaco (same for handlebars maybe)? I personally don't need or want HTML syntax highlighting in my Liquid templates.

Yeah I guess that's kind of what I was thinking: have the liquid lang on it's own, and then liquid-html, liquid-CSS, liquid-X.

@mattvague
Copy link
Contributor Author

mattvague commented May 11, 2021

@mattvague The reason some of these rules get repeated in Monarch is because Monarch does not support injections like for example Textmate does.

@alexdima I'm not 100% sure what injections in textmate do, but could we not accomplish what was laid out above with nextEmbedded?

@alexdima
Copy link
Member

alexdima commented May 11, 2021

I'm not 100% sure what injections in textmate do, but could we not accomplish what was laid out above with nextEmbedded?

That works for certain cases, namely cases like JavaScript embedded inside HTML where each <script> tag enters the initial JS state e.g.:

<script>//a comment that is not continued</script><h1>Hello</h1><script>const x = 3;</script>

Notice how the </script> terminates JS and then <script> begins JS again, but the second script is not in a comment state.

Now, looking at something like php, this is no longer the case e.g.:

<div class="<?php echo $myvar; ?> someother"></div>

Notice how the HTML after ?> continues in the HTML attribute state, so HTML is not really an embedded language inside PHP in the same way JS is an embedded language inside HTML. It is more the other way around, PHP is an embedded language inside HTML, as each PHP <? block begins in the initial PHP tokenization state.

In TextMate, this is handled by creating a new PHP grammar that consists of injecting a rule for <? / <?php in pretty much all the HTML states, while in Monarch this feature does not exist.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants