Sugar High

Super lightweight syntax highlighter

/* super tiny syntax highlighter *//* super tiny syntax highlighter *//* super tiny syntax highlighter */
import { highlight } from 'sugar-high'import { highlight } from 'sugar-high'import { highlight } from 'sugar-high'
const code = highlight('const text = 1')const code = highlight('const text = 1')const code = highlight('const text = 1')
1export default function App() {2  return (3    <>4      <h1 id="title">5        Hello6        <span> world</span>7      </h1>8      <div style={styles.bar} />9    </>10  )11}1213
light.css
/* light.css */:root {  --sh-class: #8d85ff;  --sh-identifier: #354150;  --sh-sign: #8996a3;  --sh-string: #00a99a;  --sh-keyword: #f47067;  --sh-comment: #a19595;  --sh-jsxliterals: #bf7db6;  --sh-entity: #6eafad;  --sh-property: #4e8fdf;}
dark.css
/* dark.css */:root[data-theme='dark'] {  --sh-class: #7eb5ff;  --sh-identifier: #d4d4d4;  --sh-sign: #8b949e;  --sh-string: #88bbb6;  --sh-keyword: #ffada8;  --sh-comment: #8b8b8b;  --sh-jsxliterals: #d2a8ff;  --sh-entity: #56d4dd;  --sh-property: #79c0ff;}

Line highlighting

Each line is a .sh__line, so target lines with CSS selectors or a custom line class.

.sh__line:nth-child(5),
.sh__line--highlighted {
  background: #fff8c5;
}

Language presets

Import a preset when the source is not JavaScript or JSX, then pass it as the second argument to highlight.

import { highlight } from 'sugar-high'
import * as presets from 'sugar-high/presets'

const presetForTitle = (title) =>
  ({
    css: presets.css,
    py: presets.python,
    rs: presets.rust,
    diff: presets.diff,
  })[
    title.split('.').pop()
  ]

highlight('.card { color: red; }', presetForTitle('theme.css'))
highlight('def hi():\n    print("ok")', presetForTitle('main.py'))
#include <stdint.h> /* fixed-width ints */
#define MIX(x,y) (((x) & 0xffu) ^ ((y) >> 8) | (0xab00u)) // bit ops
typedef struct { uint16_t a; uint32_t b; } hdr_t; // packed header fields
static inline uint32_t rot(uint32_t x, int n) { return (x << n) | (x >> (32 - n)); } // rotate
package main
import "encoding/json"; import "fmt"; import "strings" // one line, three imports
type Row struct { ID string `json:"id"`; Tags []string `json:"tags,omitempty"` } // struct tags
func (r Row) Label() string { return fmt.Sprintf("%s [%s]", r.ID, strings.Join(r.Tags, ",")) } // Sprintf + Join
var _ json.Marshaler = (*Row)(nil) // interface satisfaction
// FQCN-heavy lines: generics, streams, method refs (no extra imports)
java.util.List<java.util.Map<String, Integer>> rows = java.util.List.of(java.util.Map.of("a", 1), java.util.Map.of("b", 2));
java.util.stream.Stream.of("x", "y").map(String::toUpperCase).filter(s -> !s.isEmpty()).forEach(System.out::println);
from __future__ import annotations  # postponed annotations
from itertools import chain, groupby  # stdlib
RE = r"(?x) ^\s* (?P<name> [A-Za-z_]\w* ) \s* = \s* (?P<val> .+ ) $ "  # verbose regex
def windows(xs: list[int], n: int) -> list[list[int]]: return [xs[i : i + n] for i in range(0, len(xs), n)]  # slices

Diff examples

Diff and patch files use presets.diff to mark added, removed, hunk, and metadata lines.

  export const theme = {
-   accent: '#f47067',
+   accent: '#2876db',
    surface: '#ffffff',
  }

Usage with remark.js

Remark.js is a powerful markdown processor, you can use the sugar-high remark plugin with remark.js to highlight code blocks in markdown.