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