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

Highlight HTML, CSS, Markdown, GraphQL in JS tagged template literals #1930

Open
karlhorky opened this issue Jun 7, 2019 · 13 comments
Open

Comments

@karlhorky
Copy link
Contributor

karlhorky commented Jun 7, 2019

Motivation

Prism doesn't highlight supported languages when they are in a tagged template literal with common tags.

Screen Shot 2019-06-07 at 11 25 17

Description

Support for common tagged template literals such as:

// HTML
html`...`

// CSS
css`...`

// React Components CSS
styled.foo``
Component.extend``
styled.foo.attr({})``
Component.extend.attr({)``
styled(Component).attr({})``
css.global``
css.resolve``

// Markdown
md`...`
markdown`...`

// GraphQL
gql`...`
graphql`...`
graphql.experimental`...`

// SQL
sql`SELECT * FROM users WHERE id = ${id}`

To allow this highlighting behavior without adding a tag call, one option is to also support comments in the place of tags:

/* HTML */`...`
/* CSS */`...`

There are also other non-template literal syntaxes which are potentially desired:

// Angular Components HTML + CSS
@Component({
  template: `<div>...</div>`,
  styles: [`h1 { color: blue; }`]
})

// styled-jsx CSS
<style jsx>{`div{color:red}`}</style>

Prettier has some AST tests for these things which could probably be repurposed here (or at least, could inspire a solution):

HTML tagged template literals:

CSS tagged template literals:

Markdown tagged template literals:

GraphQL tagged template literals:


Edit: It seems like #1714 has part of (all of) the styled-components implementations, and maybe this could be repurposed to achieve all the other languages.

@RunDevelopment
Copy link
Member

Great suggestion!

There is one thing I want to add to the list of non-tagged literals:

div.innerHTML = `
    <em>Foo</em>
`;

(Even GitHub highlights this)


To allow this highlighting behavior without adding a tag call, one option is to also support comments in the place of tags:

/* HTML */`...`
/* CSS */`...`

I really don't like the idea of Prism specific syntax for the sole purpose of highlighting.
I get why this is desirable but no other editor (at least not that I'm aware of) supports this and adjusting your code specifically for Prism is not something which should have to do.

@karlhorky
Copy link
Contributor Author

Cool, sounds great :)

no other editor (at least not that I'm aware of) supports this

Prettier formats HTML and GraphQL with these comments. But yeah, not such a big deal.

@karlhorky
Copy link
Contributor Author

It seems like #1714 has part of (all of) the styled-components implementations, and maybe this could be repurposed to achieve all the other languages.

@RunDevelopment
Copy link
Member

I would vote to add the eventual change with all languages as part of the main default JS language, since tagged template strings with different languages are common in places other than React / JSX / other frameworks. source

While it's true that these tagged literals are quite common for frameworks, they are not part of the JS language spec and therefore should be an optional opt-in feature IMO.
A more technical reason as to why handling tagged template strings with different languages in the main JS language is not optimal are dependencies. JS will have to require all included languages meaning that to highlight a small snippet of JS code (which might not even contain templates) you have to (down-)load all these languages. While I could tolerate CSS and Markup being required, I don't see why JS has to require GraphQL, Markdown, or other languages we'll include later.

My preferred solution here is a new language which handles all languages embedded in JS templates. I'm thinking of something along the lines of JS Templates. This makes the whole thing opt-in and keeps main JS lang light.

@lunalusy
Copy link

css`...`

is it not suport highlight ${} ?
my text
${hiDPI(1.5)} {
${content(.75, 1.5)}
}
highlight text
${hiDPI(1.5)} {
CSS_1
}

@RunDevelopment
Copy link
Member

@lunalusy I can't reproduce your issue. What is the exact code that is highlighted incorrectly?

@karlhorky
Copy link
Contributor Author

karlhorky commented Jun 13, 2021

@RunDevelopment I just realized I didn't have SQL in the list above - just added it:

const users = await sql`
  SELECT * FROM users WHERE id = ${id}
`;

What do you think about also supporting SQL template literals? I tried enabling it with require('prismjs/components/prism-sql');, and it didn't seem to work...

@karlhorky
Copy link
Contributor Author

By the way, I couldn't figure out how to use this on the Test Drive, as I was trying to test whether Prism already had support for SQL tagged template literals. I tried the following code, which I believe should work... 🤔

const a = css`a { color: #25F; }`

I tried it by enabling the languages in this order (not sure this is correct):

  1. CSS
  2. CSS Extras
  3. JS Extras
  4. JS Templates
  5. JavaScript

@RunDevelopment
Copy link
Member

No, SQL isn't supported yet. I'll add it.


This load order is correct and works for me. Did you maybe not start with CSS when the page was loaded?

@karlhorky
Copy link
Contributor Author

Did you maybe not start with CSS when the page was loaded?

Ah maybe, yep! I may have actually started with JS, and then done the list above. For some reason, I thought that if I continued to load, then they would bootstrap themselves correctly. But I guess reloading the page before step 1 with CSS was the right trick here.

@karlhorky
Copy link
Contributor Author

No, SQL isn't supported yet. I'll add it.

Amazing, thanks!

@karlhorky
Copy link
Contributor Author

karlhorky commented Jul 4, 2021

Great, looks like it's working with prism@1.24.0 🎉

const users = await sql`
  SELECT * FROM users WHERE id = ${id}
`;

Screen Shot 2021-07-04 at 17 57 21

In order to achieve this, I had to load the following languages (in this order):

  1. SQL
  2. JS Templates
  3. JavaScript

@redbar0n
Copy link

Syntax highlighting for tagged template literals would be very helpful, especially in languages close to JS such as ReScript:

Example:

https://rescript-relay-documentation.vercel.app/docs/tutorial/tutorial-fragments-1#step-1--define-a-fragment

Compare with:

https://relay.dev/docs/tutorial/fragments-1/#step-1--define-a-fragment

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

No branches or pull requests

4 participants