highlightjs / highlight.js

JavaScript syntax highlighter with language auto-detection and zero dependencies.
https://highlightjs.org/
BSD 3-Clause "New" or "Revised" License
23.64k stars 3.58k forks source link

Support or guidance for Vue SFC "Language" needed. #3614

Closed suterma closed 2 years ago

suterma commented 2 years ago

I have read https://highlightjs.readthedocs.io/en/latest/language-requests.html and it's a somewhat special but I guess common issue, so I raise it here, as it mainly concerns Vue users.

How to highlight code for a Vue Single File Component (SFC)?

This is quite tricky because it can contain up to three languages

I was looking for a "Vue" or "SFC" language with highlight.js, but did not find one. So I wonder how best represent an SFC component, without splitting the code display.

Even if there is no plan or possibility to implement such a mixed-language, I would suggest addressing this issue and offering guidance somewhere. I searched quite around and found no mention of this in the official documentation.

joshgoebel commented 2 years ago

I moved this as a question about a Vue grammar really has no relation to our Vue component.


This is easy. See https://highlightjs.readthedocs.io/en/latest/mode-reference.html and sublanguage. Our xml grammar is a great example as it can include bounded CSS, JavaScript, etc... So you'd just need a rule to recognize each section and sublanguage them for the individual highlighting.

joshgoebel commented 2 years ago

Were you planning to work on a 3rd party grammar module for Vue SFC?

suterma commented 2 years ago

I am not. I was trying to write up some examples for my "Vue-peaks" SFC component and was wondering what the best/simplest/most common way was to achieve that. Here's the current public state of my docs, if you are interested, with the code examples currently still boring: https://suterma.github.io/vue-peaks/

joshgoebel commented 2 years ago

I wonder did you try highlighting as xml?

suterma commented 2 years ago

Sort of. Here's my main.ts file: https://github.com/suterma/vue-peaks/blob/94dc78eaf54dc8711e1418719efd05054df3ece7/src/main.ts

Actually, I have not yet been in the need to show a full SFC all at once, so I helped myself out with parts having the appropriate language set. I opened this issue because I believe many would be in a similar position and would benefit from some general guidance.

I had a brief look into the link with the sublanguage explained. However, without much time and dedication to get into this right now, I did not grasp it, and I will stick to what I have so far for now.

Note that the link to the public docs does not yet reflect the current state of the repo. I will deploy when it's nice looking locally.

joshgoebel commented 2 years ago

Vue SFC looks a lot like XML to me. Our existing xml grammar may just work out of the box. You'll have to try it.

suterma commented 2 years ago

Basically, it's HTML, which is also XML (mostly...) :-). Using the XML language works for the most part for me (locally on my machine), but then it seems to mess up the specific script tag which is used with the Vue3 composition API:

<script setup lang='ts'>
// -> here: typescript content which is considered plain text
</script>

The script content is not recognized as typescript, but just as a single text blob. This could be some kind of "bug" or missing detection.

The following screenshot shows the situation (see the lower large code element, and the dev tools on the right): Screenshot from 2022-09-11 22-19-47

joshgoebel commented 2 years ago

Are you using a version of HLJS with javascript built-in/loaded?

suterma commented 2 years ago

I did it as described here: https://github.com/highlightjs/vue-plugin#using-es6-modules--bundling, so I guess no languages are imported by default. I have the main.ts currently like this:

// Syntax highlighter
import hljs from 'highlight.js/lib/core';

import typescript from 'highlight.js/lib/languages/typescript';
hljs.registerLanguage('vue-typescript', typescript);

import xml from 'highlight.js/lib/languages/xml';
hljs.registerLanguage('vue-template', xml);
hljs.registerLanguage('vue-sfc', xml);

import css from 'highlight.js/lib/languages/css';
hljs.registerLanguage('css', css);

import hljsVuePlugin from '@highlightjs/vue-plugin';

// The style to use (see https://highlightjs.org/static/demo/ to choose)
import 'highlight.js/styles/a11y-dark.css';

createApp(App).use(hljsVuePlugin).mount('#app');
joshgoebel commented 2 years ago

so I guess no languages are imported by default. I have the main.ts currently like this:

You'll have to use javascript with xml... TypeScript isn't valid in HTML - it only supports JavaScript inside <script>... if you need Typescript you'll need to create your own custom grammar as I was suggesting earlier.

suterma commented 2 years ago

While researching a bit more, I stumbled upon this older issue https://github.com/highlightjs/highlight.js/issues/2062 which seems to have just implemented that, including typescript apparently. It's been even published here https://github.com/highlightjs/highlightjs-vue/

Would'nt this be exactly what I need?

I did not find anything specifically about vue and SFC in particular in the officially supported languages here: https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md Maybe this is just missing by mistake or just was forgotten?

joshgoebel commented 2 years ago

Yes, but it doesn't look like it's actively maintained - but you could probably hack it to get it to work - it's about what I expected.

Maybe this is just missing by mistake or just was forgotten?

If someone was to bring it up to our modern build standards we could most definitely add it to the list.

joshgoebel commented 2 years ago

Closing as that plugin looks like exactly what you need.

suterma commented 2 years ago

If someone was to bring it up to our modern build standards we could most definitely add it to the list.

This sounds like a worthwhile investment. I will put it on my list. However, there are other projects on top still.