Sugar High

repository·main·Indexed 22 days ago

https://github.com/huozhi/sugar-high

A lightweight (~1 kB) syntax highlighter for JavaScript, JSX, and other languages via presets. It generates HTML strings for use in browsers and JS runtimes. Includes the remark-sugar-high plugin for integrating syntax highlighting into remark processing pipelines, supporting specific line highlighting via markdown meta fields.

Tokens
4.3K
Snippets
20
Records
25
Agent score
77%

What's inside sugar-high

  1. Highlight specific lines in markdown code blocks

    main

    You can highlight specific lines in a code block by adding curly braces with line numbers after the language identifier in your markdown. For example, ```javascript {2,5} will apply highlighting to lines 2 and 5.

    // Here is a simple function
    async function hello() {
        console.log('Hello, world from JavaScript!')
        return 123 // return a number
    }
    
    await hello()
  2. Add line numbers to code blocks

    main

    To implement a gutter with line numbers, use a CSS ::before counter on the .sh__line class.

    pre code {
      counter-reset: sh-line-number;
    }
    
    .sh__line::before {
      counter-increment: sh-line-number 1;
      content: counter(sh-line-number);
      margin-right: 24px;
      text-align: right;
      color: #a4a4a4;
    }
  3. Highlight specific lines

    main

    You can highlight specific lines using two methods:

    1. CSS nth-child: Target a line using .sh__line:nth-child(<n>) (where <n> is 1-based).
    2. Manual class: Apply the .sh__line--highlighted class to a line if you are managing highlight classes yourself.
    /* Target the 5th line */
    .sh__line:nth-child(5) {
      background: #fff8c5;
    }
    
    /* Target via custom class */
    .sh__line--highlighted {
      background: #fff8c5;
    }
  4. How Sugar High tokenization works

    main

    Sugar High uses a heuristic-based approach to tokenize code, prioritizing speed over full AST parsing. It supports:

    • Automatic Language Detection: It uses a scoring system to detect if code is likely TypeScript (looking for interface, type, enum, etc.) and adjusts the keyword set accordingly.
    • JSX/TSX Support: It handles JSX tags, attributes, and expressions ({...}) by tracking a JSX stack and state. It includes heuristics to distinguish between TypeScript generic parameter lists (e.g., <T>) and JSX tags.
    • String and Regex Handling: It correctly identifies single-quoted, double-quoted, and template literal strings, as well as regular expressions, ensuring content inside them is not misidentified as keywords.
    • Line-based Generation: The generate phase converts tokens into a structured object model representing lines, where each line is a span containing token span elements.
  5. Use the diff language preset for syntax highlighting

    main

    The diff language preset provides syntax highlighting and line-level CSS classes for diff files. It identifies specific line types based on standard diff markers (like +, -, @@, and metadata headers) and assigns corresponding CSS classes. This allows you to style added lines, removed lines, hunk headers, and metadata differently in your documentation.

    /* 
    Note: This is a configuration preset used internally by sugar-high. 
    When using sugar-high to process code blocks marked as 'diff', 
    it will apply the following CSS classes to lines:
    
    - Added lines (+): `sh__line--diff-add`
    - Removed lines (-): `sh__line--diff-remove`
    - Hunk headers (@@): `sh__line--diff-hunk`
    - Metadata (diff --git, index, ---, +++): `sh__line--diff-meta`
    */
  6. Style sugar-high using CSS custom properties

    main

    Sugar High uses CSS custom properties for theming. You can set these variables on an ancestor element (like :root) to control the colors of different syntax tokens. Each line is wrapped in a sh__line class.

    Available CSS variables:

    • --sh-class
    • --sh-identifier
    • --sh-sign
    • --sh-property
    • --sh-entity
    • --sh-jsxliterals
    • --sh-string
    • --sh-keyword
    • --sh-comment
    :root {
      --sh-class: #2d5e9d;
      --sh-identifier: #354150;
      --sh-sign: #8996a3;
      --sh-property: #0550ae;
      --sh-entity: #249a97;
      --sh-jsxliterals: #6266d1;
      --sh-string: #00a99a;
      --sh-keyword: #f47067;
      --sh-comment: #a19595;
    }
  7. Highlight specific lines in code blocks

    main

    You can highlight specific lines in a code block by providing a range specification in the code block's meta field using the format {line1,line2-lineN}.

    When a line is highlighted, the plugin adds the CSS class sh__line--highlighted to the line container.

    Supported formats for the meta field:

    • Single lines: {1,3,5}
    • Ranges: {1,3-5}
    • Combined: {1,3-5,7}
    ```javascript {1,3-5}
    const x = 10; // Line 1 (highlighted)
    const y = 20;
    const z = 30; // Line 3 (highlighted)
    const a = 40; // Line 4 (highlighted)
    const b = 50; // Line 5 (highlighted)
  8. Use remark-sugar-high in a remark pipeline

    main

    To use the plugin, import the highlight function and add it to your remark processor using .use(highlight). This will transform markdown code blocks into highlighted HTML structures compatible with Sugar High's CSS.

    const { highlight } = require('remark-sugar-high');
    
    await remark()
      .use(highlight)
      .use(require('remark-html'))
      .process(file, (err, file) => console.log(String(file)));
  9. Use the highlight() function

    main

    Import highlight from sugar-high to convert raw code strings into HTML strings. The output can be injected into any element that accepts HTML (like innerHTML). By default, it targets JavaScript and JSX.

    import { highlight } from 'sugar-high'
    
    const codeHTML = highlight(code)
    
    document.querySelector('pre > code').innerHTML = codeHTML