How to keep giallo from rewriting unknown langs to "plain"

Background

I use a third-party library Klipse (link below) to augment code blocks for some languages, usually JavaScript and Clojure. It uses CSS selectors to find specific code blocks in a page and attaching dynamic logic to them. I was using it under Cryogen when I came over to Zola.

In previous versions of Zola, the old highlighting engine would take whatever string I put next to the markdown codeblocks and use it as a CSS class name for the rendered element.

Eg, this content:

```klipse-js
var flooble = "whatsit";
```

Would create the following HTML when rendered:

<pre class="language-klipse-js" data-lang="klipse-js">
    ...
    <code class="language-klipse-js" data-lang="klipse-js">...</code>
    ...
</pre>

This allowed me to use the CSS selector .language-klipse-js in my config to let Klipse find my code blocks.

I don’t think this was ever officially supported, but it was convenient for my purposes, and everything worked.

How It’s Going

As the release notes and docs describe, the old highlighting engine has been replaced by a new crate, giallo, and it’s working very well for normal highlighting.

I could even use a different CSS selector to use the data-lang attribute instead of the class, except that Giallo is picky about languages it doesn’t support.

If I set error_on_missing_language = false, and try to use languages like klipse-js again, it silently rewrites the ::before headers to PLAIN, and changes the tag attributes to data-lang=”plain” as well.

My Workaround

I’m currently able to work around this by creating dummy grammars for the bogus languages like this:

// extra_grammars/klipse-js.json
{"name": "klipse-js", "scopeName": "source.js"}

It doesn’t do much, obviously but it’s the bare minimum JSON required to declare a grammar, so that giallo doesn’t rewrite it to plain.

The Request

Like I said, this is a functional workaround, but it’s really fragile and requires me to create 20+ dummy grammar files for each langauge the Klipse library supports.

Is there a way to prevent Giallo from rewriting unrecognized/unknown languages to “plain”? A configuration option I haven’t been able to find?

If not, is there any interest in supporting this? Something like

[markdown.highlighting]
rewrite_unknown_languages_as_plain = true

…or something, that defaults to true but can be disabled?

I may even be able to help implement and/or test it if there this sounds useful, but wanted to gauge interest before dropping a PR in people’s laps.

The Klipse repo can be found here: https://github.com/viebel/klipse

And you can see it in action here (via an older build of Zola): Give Me a Sine | lexical snark

Thanks for your time! And thank you for such an amazing framework!

-Tim

You can pass any metadata to the markdown fence and it will pass that as data- attributes on the <code> element. so you can do

```klipse=js
my code here
```

it will mark it as plain so no highlighting but you can then get the data-klipse=”js” attribute on the code

1 Like

Oh! That is beautiful!

I didn’t notice at first that you wrote klipse=js instead of klipse-js, but I can confirm it does create a data-klipse=”js” attribute!

THANK YOU!

For others trying to integrate Klipse with Zola v0.22+, here’s what I’ve done and confirmed works.

For the markdown fence, I’m using:

```clj,klipse=cljs
(defonce an-atom (atom 1))
```

```js,klipse=js
const stuff = ['thing1', 'thing2'];
```

This way it gracefully falls back to giallo’s highlighting if the client has javascript disabled.

For the CSS selector, I’m matching on the outer <pre> tag, so I used selectors of this form in the klipse config:

selector: 'pre:has(code[data-klipse="cljs"])',
selector_eval_js: 'pre:has(code[data-klipse="js"])',
// etc.

Thank you so much for your help, @keats!
-Tim

1 Like