<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>highlighter</title>
  <link href="https://highlighter.edadma.dev/feed.xml" rel="self"/>
  <link href="https://highlighter.edadma.dev/"/>
  <id>https://highlighter.edadma.dev/feed.xml</id>
  <updated>2026-06-20T21:52:06.626409609Z</updated>
  <author><name>Ed Maxedon</name></author>
  <entry>
    <title>Tokens</title>
    <link href="https://highlighter.edadma.dev/guide/tokens/"/>
    <id>https://highlighter.edadma.dev/guide/tokens/</id>
    <updated>2026-06-20T21:52:06.626409609Z</updated>
    <summary>When you render to something other than a web page — a PDF, a terminal, a GUI — take the tokens directly instead of producing HTML and parsing it back…</summary>
    <content type="html">&lt;p&gt;When you render to something other than a web page — a PDF, a terminal, a GUI — take the tokens
directly instead of producing HTML and parsing it back apart. &lt;code&gt;tokens&lt;/code&gt; returns the same
information &lt;code&gt;highlight&lt;/code&gt; uses, structured rather than serialized.&lt;/p&gt;
&lt;h2 id=&quot;tokenizing&quot;&gt;Tokenizing&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;tokens(code)&lt;/code&gt; returns &lt;strong&gt;one list of tokens per source line&lt;/strong&gt;, with adjacent same-scope tokens
merged:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammar&lt;span class=&quot;hl-punctuation&quot;&gt;):&lt;/span&gt; @unchecked

&lt;span class=&quot;hl-keyword&quot;&gt;for&lt;/span&gt; line &lt;span class=&quot;hl-keyword&quot;&gt;&amp;lt;-&lt;/span&gt; hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;tokens&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;val x = 42&lt;/span&gt;&lt;span class=&quot;hl-variable&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;// note&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;hl-keyword&quot;&gt;for&lt;/span&gt; tok &lt;span class=&quot;hl-keyword&quot;&gt;&amp;lt;-&lt;/span&gt; line &lt;span class=&quot;hl-keyword&quot;&gt;do&lt;/span&gt;
    render&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;tok&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;categoryOf&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;tok&lt;span class=&quot;hl-punctuation&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each &lt;code&gt;Token&lt;/code&gt; is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;hl-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; scopes&lt;span class=&quot;hl-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The line grouping is preserved: &lt;code&gt;tokens(code).length&lt;/code&gt; is the number of lines, and
concatenating a line’s token texts reproduces that line exactly — so you control line breaks and
indentation yourself.&lt;/p&gt;
&lt;h2 id=&quot;categories-and-colours&quot;&gt;Categories and colours&lt;/h2&gt;
&lt;p&gt;A token’s effective scope is its innermost (last) one. &lt;code&gt;categoryOf&lt;/code&gt; collapses it to one of the
nine rendering categories — the same mapping the HTML back ends use — so you can drive your own
palette:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;def&lt;/span&gt; colour&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;tok&lt;span class=&quot;hl-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;MyColour&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt;
  hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;categoryOf&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;tok&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;match&lt;/span&gt;           &lt;span class=&quot;hl-comment&quot;&gt;// keyword | string | comment | number | type |&lt;/span&gt;
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; myKeyword      &lt;span class=&quot;hl-comment&quot;&gt;// function | variable | operator | punctuation | &amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;  &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; myString
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;comment&amp;quot;&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; myComment
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;number&amp;quot;&lt;/span&gt;  &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; myNumber
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; _         &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; myDefault&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An empty category (&lt;code&gt;&amp;quot;&amp;quot;&lt;/code&gt;) means the token carries no colour of its own — plain source text.
&lt;code&gt;category(scope)&lt;/code&gt; is the same mapping applied to a raw scope string, if you have one in hand.&lt;/p&gt;
&lt;h2 id=&quot;pairing-with-a-theme&quot;&gt;Pairing with a theme&lt;/h2&gt;
&lt;p&gt;The built-in &lt;a href=&quot;/guide/themes/&quot;&gt;themes&lt;/a&gt; are just category-to-hex maps, so you can reuse one as
your palette instead of hand-rolling colours:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; theme &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;OneDark&lt;/span&gt;
&lt;span class=&quot;hl-keyword&quot;&gt;def&lt;/span&gt; hex&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;tok&lt;span class=&quot;hl-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Token&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt;
  hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;categoryOf&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;tok&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;match&lt;/span&gt;
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;keyword&amp;quot;&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; theme&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;keyword
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;  &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; theme&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;string
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;number&amp;quot;&lt;/span&gt;  &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; theme&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;number
    &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; _         &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; theme&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;default&lt;/code&gt;&lt;/pre&gt;</content>
  </entry>
  <entry>
    <title>Themes</title>
    <link href="https://highlighter.edadma.dev/guide/themes/"/>
    <id>https://highlighter.edadma.dev/guide/themes/</id>
    <updated>2026-06-20T21:52:06.626409609Z</updated>
    <summary>A Theme maps each of the nine highlight categories to a colour. Themes are used by InlineMode to emit inline style colours, and you can read a theme yourself when…</summary>
    <content type="html">&lt;p&gt;A &lt;code&gt;Theme&lt;/code&gt; maps each of the nine highlight categories to a colour. Themes are used by
&lt;code&gt;InlineMode&lt;/code&gt; to emit inline &lt;code&gt;style&lt;/code&gt; colours, and you can read a theme yourself when rendering
&lt;a href=&quot;/guide/tokens/&quot;&gt;tokens&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;built-in-themes&quot;&gt;Built-in themes&lt;/h2&gt;
&lt;p&gt;Three presets ship with the library:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-type&quot;&gt;InlineMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;OneDark&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;hl-comment&quot;&gt;// dark&lt;/span&gt;
&lt;span class=&quot;hl-type&quot;&gt;InlineMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;OneLight&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;hl-comment&quot;&gt;// light&lt;/span&gt;
&lt;span class=&quot;hl-type&quot;&gt;InlineMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Monokai&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;hl-comment&quot;&gt;// dark&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same Scala snippet under each — and every one of these blocks was produced by highlighter
itself, in inline mode:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OneDark&lt;/strong&gt;&lt;/p&gt;
&lt;pre style=&quot;background:#282c34;color:#abb2bf;padding:1rem 1.25rem;border-radius:8px;overflow-x:auto;font-size:.8rem;line-height:1.55;margin:1rem 0&quot;&gt;&lt;code&gt;&lt;span style=&quot;color:#5c6370&quot;&gt;// quicksort&lt;/span&gt;
&lt;span style=&quot;color:#c678dd&quot;&gt;def&lt;/span&gt; sort&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;xs&lt;span style=&quot;color:#abb2bf&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#e5c07b&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#e5c07b&quot;&gt;Int&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;]):&lt;/span&gt; &lt;span style=&quot;color:#e5c07b&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#e5c07b&quot;&gt;Int&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#c678dd&quot;&gt;=&lt;/span&gt; xs &lt;span style=&quot;color:#c678dd&quot;&gt;match&lt;/span&gt;
  &lt;span style=&quot;color:#c678dd&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color:#e5c07b&quot;&gt;Nil&lt;/span&gt; &lt;span style=&quot;color:#c678dd&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#e5c07b&quot;&gt;Nil&lt;/span&gt;
  &lt;span style=&quot;color:#c678dd&quot;&gt;case&lt;/span&gt; pivot &lt;span style=&quot;color:#c678dd&quot;&gt;::&lt;/span&gt; rest &lt;span style=&quot;color:#c678dd&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#c678dd&quot;&gt;val&lt;/span&gt; &lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;less&lt;span style=&quot;color:#abb2bf&quot;&gt;,&lt;/span&gt; more&lt;span style=&quot;color:#abb2bf&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#c678dd&quot;&gt;=&lt;/span&gt; rest&lt;span style=&quot;color:#abb2bf&quot;&gt;.&lt;/span&gt;partition&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;_ &lt;span style=&quot;color:#c678dd&quot;&gt;&amp;lt;&lt;/span&gt; pivot&lt;span style=&quot;color:#abb2bf&quot;&gt;)&lt;/span&gt;
    sort&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;less&lt;span style=&quot;color:#abb2bf&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#c678dd&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;pivot &lt;span style=&quot;color:#c678dd&quot;&gt;::&lt;/span&gt; sort&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;more&lt;span style=&quot;color:#abb2bf&quot;&gt;))&lt;/span&gt;

&lt;span style=&quot;color:#c678dd&quot;&gt;val&lt;/span&gt; nums &lt;span style=&quot;color:#c678dd&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#e5c07b&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#d19a66&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#d19a66&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#d19a66&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#d19a66&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#d19a66&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#abb2bf&quot;&gt;)&lt;/span&gt;
println&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;sort&lt;span style=&quot;color:#abb2bf&quot;&gt;(&lt;/span&gt;nums&lt;span style=&quot;color:#abb2bf&quot;&gt;))&lt;/span&gt;  &lt;span style=&quot;color:#5c6370&quot;&gt;// List(1, 2, 5, 8, 9)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;OneLight&lt;/strong&gt;&lt;/p&gt;
&lt;pre style=&quot;background:#fafafa;color:#383a42;padding:1rem 1.25rem;border-radius:8px;overflow-x:auto;font-size:.8rem;line-height:1.55;margin:1rem 0&quot;&gt;&lt;code&gt;&lt;span style=&quot;color:#a0a1a7&quot;&gt;// quicksort&lt;/span&gt;
&lt;span style=&quot;color:#a626a4&quot;&gt;def&lt;/span&gt; sort&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;xs&lt;span style=&quot;color:#383a42&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#c18401&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#c18401&quot;&gt;Int&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;]):&lt;/span&gt; &lt;span style=&quot;color:#c18401&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#c18401&quot;&gt;Int&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#a626a4&quot;&gt;=&lt;/span&gt; xs &lt;span style=&quot;color:#a626a4&quot;&gt;match&lt;/span&gt;
  &lt;span style=&quot;color:#a626a4&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color:#c18401&quot;&gt;Nil&lt;/span&gt; &lt;span style=&quot;color:#a626a4&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#c18401&quot;&gt;Nil&lt;/span&gt;
  &lt;span style=&quot;color:#a626a4&quot;&gt;case&lt;/span&gt; pivot &lt;span style=&quot;color:#a626a4&quot;&gt;::&lt;/span&gt; rest &lt;span style=&quot;color:#a626a4&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#a626a4&quot;&gt;val&lt;/span&gt; &lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;less&lt;span style=&quot;color:#383a42&quot;&gt;,&lt;/span&gt; more&lt;span style=&quot;color:#383a42&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#a626a4&quot;&gt;=&lt;/span&gt; rest&lt;span style=&quot;color:#383a42&quot;&gt;.&lt;/span&gt;partition&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;_ &lt;span style=&quot;color:#a626a4&quot;&gt;&amp;lt;&lt;/span&gt; pivot&lt;span style=&quot;color:#383a42&quot;&gt;)&lt;/span&gt;
    sort&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;less&lt;span style=&quot;color:#383a42&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#a626a4&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;pivot &lt;span style=&quot;color:#a626a4&quot;&gt;::&lt;/span&gt; sort&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;more&lt;span style=&quot;color:#383a42&quot;&gt;))&lt;/span&gt;

&lt;span style=&quot;color:#a626a4&quot;&gt;val&lt;/span&gt; nums &lt;span style=&quot;color:#a626a4&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#c18401&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#986801&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#986801&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#986801&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#986801&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#986801&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#383a42&quot;&gt;)&lt;/span&gt;
println&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;sort&lt;span style=&quot;color:#383a42&quot;&gt;(&lt;/span&gt;nums&lt;span style=&quot;color:#383a42&quot;&gt;))&lt;/span&gt;  &lt;span style=&quot;color:#a0a1a7&quot;&gt;// List(1, 2, 5, 8, 9)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Monokai&lt;/strong&gt;&lt;/p&gt;
&lt;pre style=&quot;background:#272822;color:#f8f8f2;padding:1rem 1.25rem;border-radius:8px;overflow-x:auto;font-size:.8rem;line-height:1.55;margin:1rem 0&quot;&gt;&lt;code&gt;&lt;span style=&quot;color:#75715e&quot;&gt;// quicksort&lt;/span&gt;
&lt;span style=&quot;color:#f92672&quot;&gt;def&lt;/span&gt; sort&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;xs&lt;span style=&quot;color:#f8f8f2&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;Int&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;]):&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;Int&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; xs &lt;span style=&quot;color:#f92672&quot;&gt;match&lt;/span&gt;
  &lt;span style=&quot;color:#f92672&quot;&gt;case&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;Nil&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;Nil&lt;/span&gt;
  &lt;span style=&quot;color:#f92672&quot;&gt;case&lt;/span&gt; pivot &lt;span style=&quot;color:#f92672&quot;&gt;::&lt;/span&gt; rest &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#f92672&quot;&gt;val&lt;/span&gt; &lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;less&lt;span style=&quot;color:#f8f8f2&quot;&gt;,&lt;/span&gt; more&lt;span style=&quot;color:#f8f8f2&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; rest&lt;span style=&quot;color:#f8f8f2&quot;&gt;.&lt;/span&gt;partition&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;_ &lt;span style=&quot;color:#f92672&quot;&gt;&amp;lt;&lt;/span&gt; pivot&lt;span style=&quot;color:#f8f8f2&quot;&gt;)&lt;/span&gt;
    sort&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;less&lt;span style=&quot;color:#f8f8f2&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;pivot &lt;span style=&quot;color:#f92672&quot;&gt;::&lt;/span&gt; sort&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;more&lt;span style=&quot;color:#f8f8f2&quot;&gt;))&lt;/span&gt;

&lt;span style=&quot;color:#f92672&quot;&gt;val&lt;/span&gt; nums &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;List&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#ae81ff&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color:#ae81ff&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#f8f8f2&quot;&gt;)&lt;/span&gt;
println&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;sort&lt;span style=&quot;color:#f8f8f2&quot;&gt;(&lt;/span&gt;nums&lt;span style=&quot;color:#f8f8f2&quot;&gt;))&lt;/span&gt;  &lt;span style=&quot;color:#75715e&quot;&gt;// List(1, 2, 5, 8, 9)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;custom-themes&quot;&gt;Custom themes&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Theme&lt;/code&gt; is a plain case class with a default colour per category, so override only what you
want:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; mine &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;
  keyword     &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#ff0000&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  string      &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#00aa00&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  comment     &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#888888&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  number      &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#d19a66&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  `&lt;span class=&quot;hl-keyword&quot;&gt;type&lt;/span&gt;`      &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#e5c07b&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  function    &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#61afef&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  variable    &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#e06c75&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  operator    &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#56b6c2&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  punctuation &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#abb2bf&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;
  default     &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;#abb2bf&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt;   &lt;span class=&quot;hl-comment&quot;&gt;// anything with no category of its own&lt;/span&gt;
&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammar&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;InlineMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;mine&lt;span class=&quot;hl-punctuation&quot;&gt;)):&lt;/span&gt; @unchecked&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;keyword&lt;/code&gt; covers control words and storage modifiers; &lt;code&gt;default&lt;/code&gt; is used for text that carries a
scope highlighter doesn’t map to a category. (&lt;code&gt;type&lt;/code&gt; is a Scala keyword, so it is written
&lt;code&gt;`type`&lt;/code&gt; in source.)&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>HTML Rendering</title>
    <link href="https://highlighter.edadma.dev/guide/rendering/"/>
    <id>https://highlighter.edadma.dev/guide/rendering/</id>
    <updated>2026-06-20T21:52:06.626409609Z</updated>
    <summary>highlight(code) returns an HTML string with one &lt;span&gt; per highlighted run. How those spans are styled depends on the render mode you pass when building the highlighter. Text is HTML-escaped,…</summary>
    <content type="html">&lt;p&gt;&lt;code&gt;highlight(code)&lt;/code&gt; returns an HTML string with one &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; per highlighted run. How those spans
are styled depends on the &lt;strong&gt;render mode&lt;/strong&gt; you pass when building the highlighter. Text is
HTML-escaped, and adjacent runs with the same scope are merged into one span.&lt;/p&gt;
&lt;h2 id=&quot;class-mode&quot;&gt;Class mode&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ClassMode(prefix)&lt;/code&gt; emits &lt;code&gt;&amp;lt;span class=&amp;quot;prefix-category&amp;quot;&amp;gt;&lt;/code&gt;, where the category is one of nine
names. You supply the colours in your own stylesheet:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammar&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;ClassMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;hl-&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)):&lt;/span&gt; @unchecked
hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;highlight&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;val x = 42&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl-comment&quot;&gt;// &amp;lt;span class=&amp;quot;hl-keyword&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt; x = &amp;lt;span class=&amp;quot;hl-number&amp;quot;&amp;gt;42&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the prefix to match your CSS:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-type&quot;&gt;ClassMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;hl-&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;hl-comment&quot;&gt;// &amp;lt;span class=&amp;quot;hl-keyword&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;hl-type&quot;&gt;ClassMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;code-&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;hl-comment&quot;&gt;// &amp;lt;span class=&amp;quot;code-keyword&amp;quot;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The nine categories are: &lt;code&gt;keyword&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;comment&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;function&lt;/code&gt;,
&lt;code&gt;variable&lt;/code&gt;, &lt;code&gt;operator&lt;/code&gt;, &lt;code&gt;punctuation&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;inline-mode&quot;&gt;Inline mode&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;InlineMode(theme)&lt;/code&gt; emits &lt;code&gt;&amp;lt;span style=&amp;quot;color:#hex&amp;quot;&amp;gt;&lt;/code&gt; straight from a theme, so the output is
self-contained — no stylesheet required:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammar&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;InlineMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Theme&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;OneDark&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)):&lt;/span&gt; @unchecked
hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;highlight&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;val x = 42&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;hl-comment&quot;&gt;// &amp;lt;span style=&amp;quot;color:#c678dd&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt; x = &amp;lt;span style=&amp;quot;color:#d19a66&amp;quot;&amp;gt;42&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This very page is built that way: the plain fenced &lt;code&gt;```scala&lt;/code&gt; blocks here are highlighted at
build time by the same library, through the site generator’s &lt;code&gt;codeHighlighter&lt;/code&gt; hook:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-comment&quot;&gt;// quicksort&lt;/span&gt;
&lt;span class=&quot;hl-keyword&quot;&gt;def&lt;/span&gt; sort&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;xs&lt;span class=&quot;hl-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;]):&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; xs &lt;span class=&quot;hl-keyword&quot;&gt;match&lt;/span&gt;
  &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Nil&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Nil&lt;/span&gt;
  &lt;span class=&quot;hl-keyword&quot;&gt;case&lt;/span&gt; pivot &lt;span class=&quot;hl-keyword&quot;&gt;::&lt;/span&gt; rest &lt;span class=&quot;hl-keyword&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;less&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; more&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; rest&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;partition&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;_ &lt;span class=&quot;hl-keyword&quot;&gt;&amp;lt;&lt;/span&gt; pivot&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;
    sort&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;less&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;pivot &lt;span class=&quot;hl-keyword&quot;&gt;::&lt;/span&gt; sort&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;more&lt;span class=&quot;hl-punctuation&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; nums &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;
println&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;sort&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;nums&lt;span class=&quot;hl-punctuation&quot;&gt;))&lt;/span&gt;  &lt;span class=&quot;hl-comment&quot;&gt;// List(1, 2, 5, 8, 9)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See &lt;a href=&quot;/guide/themes/&quot;&gt;Themes&lt;/a&gt; for the built-in schemes and how to define your own.&lt;/p&gt;
&lt;h2 id=&quot;lines&quot;&gt;Lines&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;highlight&lt;/code&gt; joins lines with &lt;code&gt;\n&lt;/code&gt;; each source line is highlighted independently and a
multi-line &lt;code&gt;begin&lt;/code&gt;/&lt;code&gt;end&lt;/code&gt; span carries its scope across the break. If you are rendering to
something other than HTML — and want the line structure handed to you — use the
&lt;a href=&quot;/guide/tokens/&quot;&gt;token API&lt;/a&gt; instead.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Quick Start</title>
    <link href="https://highlighter.edadma.dev/getting-started/quick-start/"/>
    <id>https://highlighter.edadma.dev/getting-started/quick-start/</id>
    <updated>2026-06-20T21:52:06.626409609Z</updated>
    <summary>Highlighting takes three steps: load a grammar, pick how you want the output, and pass it some code.</summary>
    <content type="html">&lt;p&gt;Highlighting takes three steps: load a grammar, pick how you want the output, and pass it some
code.&lt;/p&gt;
&lt;h2 id=&quot;a-first-grammar&quot;&gt;A first grammar&lt;/h2&gt;
&lt;p&gt;A TextMate grammar is JSON describing the patterns of a language. A tiny one is enough to
start — keywords, numbers, strings, and line comments:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;import&lt;/span&gt; io&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;github&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;edadma&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;highlighter&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-keyword&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; grammar &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;&amp;quot;&amp;quot;{&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;  &amp;quot;scopeName&amp;quot;: &amp;quot;source.example&amp;quot;,&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;  &amp;quot;patterns&amp;quot;: [&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;    { &amp;quot;match&amp;quot;: &amp;quot;\\b(val|def|if|else)\\b&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;keyword.control&amp;quot; },&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;    { &amp;quot;match&amp;quot;: &amp;quot;\\b\\d+\\b&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;constant.numeric&amp;quot; },&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;    { &amp;quot;begin&amp;quot;: &amp;quot;\&amp;quot;&amp;quot;, &amp;quot;end&amp;quot;: &amp;quot;\&amp;quot;&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;string.quoted.double&amp;quot; },&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;    { &amp;quot;match&amp;quot;: &amp;quot;//.*$&amp;quot;, &amp;quot;name&amp;quot;: &amp;quot;comment.line&amp;quot; }&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;  ]&lt;/span&gt;
&lt;span class=&quot;hl-string&quot;&gt;}&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;build-a-highlighter&quot;&gt;Build a highlighter&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Highlighter.fromJson&lt;/code&gt; parses the grammar and returns &lt;code&gt;Either[String, Highlighter]&lt;/code&gt; — a &lt;code&gt;Left&lt;/code&gt;
carries a parse error message, so this never throws on a bad grammar:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammar&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;ClassMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;hl-&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)):&lt;/span&gt; @unchecked&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;highlight-some-code&quot;&gt;Highlight some code&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;println&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;highlight&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;val x = 42&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;hl-comment&quot;&gt;// &amp;lt;span class=&amp;quot;hl-keyword&amp;quot;&amp;gt;val&amp;lt;/span&amp;gt; x = &amp;lt;span class=&amp;quot;hl-number&amp;quot;&amp;gt;42&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the whole loop. From here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/guide/grammars/&quot;&gt;Loading Grammars&lt;/a&gt;&lt;/strong&gt; — use a real VS Code &lt;code&gt;.tmLanguage.json&lt;/code&gt;, and the
grammar features highlighter supports.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/guide/rendering/&quot;&gt;HTML Rendering&lt;/a&gt;&lt;/strong&gt; — CSS-class output versus inline theme colours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/guide/themes/&quot;&gt;Themes&lt;/a&gt;&lt;/strong&gt; — the built-in colour schemes and writing your own.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/guide/tokens/&quot;&gt;Tokens&lt;/a&gt;&lt;/strong&gt; — skip the HTML and render the tokens yourself.&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Installation</title>
    <link href="https://highlighter.edadma.dev/getting-started/installation/"/>
    <id>https://highlighter.edadma.dev/getting-started/installation/</id>
    <updated>2026-06-20T21:52:06.626409609Z</updated>
    <summary>highlighter is cross-published for the JVM, Scala.js, and Scala Native. Add it with the %%% operator so sbt selects the right platform artifact:</summary>
    <content type="html">&lt;p&gt;highlighter is cross-published for the JVM, Scala.js, and Scala Native. Add it with the &lt;code&gt;%%%&lt;/code&gt;
operator so sbt selects the right platform artifact:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;libraryDependencies &lt;span class=&quot;hl-keyword&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;io.github.edadma&amp;quot;&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;%%%&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;highlighter&amp;quot;&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hl-string&quot;&gt;&amp;quot;0.0.10&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is published to Maven Central, so no extra resolver is needed.&lt;/p&gt;
&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;highlighter is a pure-Scala library — its only dependencies are
&lt;a href=&quot;https://github.com/zio/zio-json&quot;&gt;&lt;code&gt;zio-json&lt;/code&gt;&lt;/a&gt; for reading grammar files and the pure-Scala
&lt;a href=&quot;https://github.com/edadma/oniguruma&quot;&gt;&lt;code&gt;oniguruma&lt;/code&gt;&lt;/a&gt; regex engine. There is &lt;strong&gt;no native
dependency&lt;/strong&gt;, so the same code links and runs on the JVM, in the browser through Scala.js, and
as a Scala Native binary.&lt;/p&gt;
&lt;h2 id=&quot;importing&quot;&gt;Importing&lt;/h2&gt;
&lt;p&gt;Everything lives in one package:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;import&lt;/span&gt; io&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;github&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;edadma&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;highlighter&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-keyword&quot;&gt;*&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That brings in &lt;code&gt;Highlighter&lt;/code&gt;, the render modes (&lt;code&gt;ClassMode&lt;/code&gt;, &lt;code&gt;InlineMode&lt;/code&gt;), &lt;code&gt;Theme&lt;/code&gt;, and the
&lt;code&gt;Token&lt;/code&gt; type. The next page highlights a snippet end to end.&lt;/p&gt;</content>
  </entry>
  <entry>
    <title>Loading Grammars</title>
    <link href="https://highlighter.edadma.dev/guide/grammars/"/>
    <id>https://highlighter.edadma.dev/guide/grammars/</id>
    <updated>2026-06-20T21:52:06.626409609Z</updated>
    <summary>highlighter reads TextMate grammars — the .tmLanguage.json files that VS Code and TextMate use to describe a language. Any VS Code-compatible grammar works unchanged.</summary>
    <content type="html">&lt;p&gt;highlighter reads &lt;strong&gt;TextMate grammars&lt;/strong&gt; — the &lt;code&gt;.tmLanguage.json&lt;/code&gt; files that VS Code and TextMate
use to describe a language. Any VS Code-compatible grammar works unchanged.&lt;/p&gt;
&lt;h2 id=&quot;loading-a-vs-code-grammar&quot;&gt;Loading a VS Code grammar&lt;/h2&gt;
&lt;p&gt;Read the grammar file as a string and hand it to &lt;code&gt;fromJson&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; grammarJson &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; scala&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;io&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-type&quot;&gt;Source&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromFile&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;JavaScript.tmLanguage.json&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;).&lt;/span&gt;mkString
&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammarJson&lt;span class=&quot;hl-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;ClassMode&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;code-&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;)):&lt;/span&gt; @unchecked

println&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;highlight&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-string&quot;&gt;&amp;quot;const x = 42;&amp;quot;&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On Scala.js or Scala Native, load the grammar however that platform reads text — a bundled
resource, an HTTP fetch, a file — and pass the resulting string in the same way.&lt;/p&gt;
&lt;h2 id=&quot;supported-grammar-features&quot;&gt;Supported grammar features&lt;/h2&gt;
&lt;p&gt;The grammar engine is a regex state machine, not a flat list of patterns. It supports the
features real-world grammars rely on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;match&lt;/code&gt; patterns with a &lt;code&gt;name&lt;/code&gt; and numbered &lt;code&gt;captures&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;begin&lt;/code&gt;/&lt;code&gt;end&lt;/code&gt; patterns with &lt;code&gt;beginCaptures&lt;/code&gt;, &lt;code&gt;endCaptures&lt;/code&gt;, and nested &lt;code&gt;patterns&lt;/code&gt;, so a
construct can span lines (a block comment, a multi-line string).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contentName&lt;/code&gt; to scope the region &lt;em&gt;between&lt;/em&gt; a begin and end separately from the delimiters.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;repository&lt;/code&gt; of named rule sets, referenced with &lt;code&gt;include&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include&lt;/code&gt; references: &lt;code&gt;#ruleName&lt;/code&gt; for a repository rule and &lt;code&gt;$self&lt;/code&gt; for the whole grammar —
recursive and cyclic includes are handled with cycle detection.&lt;/li&gt;
&lt;li&gt;POSIX character classes (&lt;code&gt;[:alpha:]&lt;/code&gt;, &lt;code&gt;[:digit:]&lt;/code&gt;, …), translated per platform.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;when-a-pattern-can-t-compile&quot;&gt;When a pattern can’t compile&lt;/h2&gt;
&lt;p&gt;A grammar occasionally uses an Oniguruma regex feature that doesn’t translate. Rather than fail
the whole grammar, highlighter skips the offending pattern and records a diagnostic:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-scala&quot;&gt;&lt;span class=&quot;hl-keyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;hl&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;hl-keyword&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-type&quot;&gt;Highlighter&lt;/span&gt;&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;fromJson&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;grammarJson&lt;span class=&quot;hl-punctuation&quot;&gt;):&lt;/span&gt; @unchecked
hl&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;loadWarnings&lt;span class=&quot;hl-punctuation&quot;&gt;.&lt;/span&gt;foreach&lt;span class=&quot;hl-punctuation&quot;&gt;(&lt;/span&gt;println&lt;span class=&quot;hl-punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;hl-comment&quot;&gt;// empty when every pattern compiled cleanly&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The buffer is captured when the highlighter is built, so reading it is free. Print it once at
load time to see whether any patterns were dropped.&lt;/p&gt;</content>
  </entry>
</feed>
