What Happened

I made a smol client-side syntax highlighter Custom Highlights API called MicroLighter. I’ I a I wanted to… ahem… highlight… features.

I broke syntax highlighting on my Jekyll blog. I’ve used a handful of syntax highlighters (Highlight.js, PrismJS, Rouge, Shiki, etc, etc) and I’-offs between different client-side and server-side implementations. Faced with picking another, I knew I wanted to explore Bramus’s technique of syntax highlighting Custom Highlights API.

There’s some limitations ::highlight() pseudo; no italics, no bold, no font swapping – but otherwise it’s pretty cool syntax to idiomatically express “I want to highlight this token” via CSS instead of injecting spans everywhere. Using the Highlight API means I mutation library shrinks down to: scan code blocks using regex patterns .highlights.set(category, textRanges) to highlight the code blocks.

I don’t need much syntax highlighting . samples are a whole fifteen . My struggle is that I swap languages often. I’, CSS, and JavaScript . A little bash here, a little ruby there, some markdown as a treat. languages grew the complexity beyond the limits -fu, so I decided Textmate’s established collections of patterns . And before I knew it, my little highlighter could do almost any language.

Why It Matters

Knowing I use different languages often, one principle I established language grammars should be auto-loaded on-demand to reduce configuration and bundle size. .

Inspired by PrismJS’s simplified token categories I flattened down Textmate’s granular token categories to a more human-friendly set, making it easier to style. In addition to that, one enormous nit-pick I have with codeblock styling themes are separate entities, so I merged -dark().

opinion I I wanted the syntax highlighter : infer language and highlight language. With that a guideline, I functionality (like line-numbers, etc) over to a web component. The vanilla web component adds about ~1 , but co-locating UI into a UI primitive like native custom elements ShadowDOM encapsulation separate presentational UI.

Obviously, I’m a web component pervert a great separation of concerns versus trying to cram everything into core library.

What Comes Next

To get started , I’d -initializing minified bundle, but I’m also shipping ESM and a web component.

npm install microlighter <script type="module" src="path/to/microlighter/microlighter.min.js"></script> Like I said above, syntax highlighting, so I import the script unless I know there’s a .

if(document.querySelector('pre>code').length) { import('path/to/microlighter/microlighter.min.js'); } version if you’ something fancy yourself:

import { highlightAll } from 'microlighter' highlightAll({ selector: 'pre.onlyTheseGetHighlights' }) component features I talked about:

<micro-lighter data-syntax-theme="github" line-numbers controls="copy"> <pre><code></code></pre> </micro-lighter> Web component classes are pretty extendible I don’t support something you need, you can “fork” it by extending adding your own features.

Explore more: Software & AI Guide