rehype-pretty-code

repository·master·Indexed 23 days ago

https://github.com/rehype-pretty/rehype-pretty-code

A rehype plugin that provides high-quality, syntax-highlighted code block rendering for MD and MDX documentation. It integrates with Shiki and unified to support features such as line and character highlighting via meta strings, inline code highlighting, custom titles, captions, and CSS-based line numbers. The ecosystem includes @rehype-pretty/transformers for adding functionality like a customizable copy button.

Tokens
8.8K
Snippets
26
Records
41
Agent score
75%

What's inside rehype-pretty-code

  1. Highlight lines and characters using meta strings

    master

    You can control highlighting directly in Markdown code block fences using meta strings:

    Highlight Lines

    Use {} to specify a numeric range.

    • ```js {1-3,4} highlights lines 1 through 3, and line 4.
    • Styling: Highlighted lines receive a data-highlighted-line attribute.
    • Group by ID: Use # after the range to assign an ID: ```js {1,2}#a {3,4}#b.
    • Styling: Lines receive data-highlighted-line-id="<id>".

    Highlight Characters

    Use / or " as delimiters.

    • ```js /carrot/ highlights the word 'carrot'.
    • ```js /carrot/3-5 highlights the 3rd through 5th instances of 'carrot'.
    • Styling: Highlighted characters receive a data-highlighted-chars attribute.
    • Group by ID: Use # after the delimiter: ```js /age/#v.
    • Styling: Characters receive data-chars-id="<id>".
  2. Highlight inline code and plain text

    master

    Use special syntax to highlight code within text:

    Inline Code Highlighting

    Append {:lang} to the end of inline code to apply language highlighting.

    • Example: `[1, 2, 3]{:js}`

    Highlight Plain Text (Tokens)

    Append {: .token.name} to highlight text based on specific VS Code theme tokens.

    • Example: `getStringLength{:.entity.name.function}`
    • Tokens Map: You can use tokensMap in the plugin options to create aliases (e.g., fn: "entity.name.function"), allowing you to use `getStringLength{:.fn}`.
  3. Highlight characters in code blocks

    master

    Highlight specific words or character sequences using / or " delimiters in the meta string.

    Basic character highlighting

    ```js /carrot/
    
    ```

    Multiple segments and ranges

    You can highlight multiple segments or specify a range of occurrences (e.g., 3-5 for the 3rd to 5th instance).

    ```js /carrot/3-5 /apple/
    
    ```

    Group highlighted characters by ID

    Use # after the delimiter to assign an ID.

    ```js /age/#v /name/#v
    const [age, setName] = useState(50);
    ```

    Styling: The characters receive a data-chars-id="<id>" attribute.

    Styling Note

    Highlighted characters receive a data-highlighted-chars attribute.

  4. Implement Multiple Themes (Dark and Light Mode)

    master

    To support dual themes, pass an object to the theme option where keys represent the color mode (e.g., dark, light).

    When multiple themes are provided, the <code> and <pre> elements will have a data-theme attribute containing a space-separated list of the theme names (e.g., data-theme="github-dark-dimmed github-light").

    You can then use CSS to switch colors based on the prefers-color-scheme media query or by targeting the data-theme attribute.

    const options = {
      theme: {
        dark: "github-dark-dimmed",
        light: "github-light",
      },
    };
  5. Implement line numbers with CSS

    master

    The library is unstyled, but it provides attributes to help you implement line numbers via CSS counters.

    1. Use the showLineNumbers meta string to enable them: ```js showLineNumbers.
    2. To start at a specific number: ```js showLineNumbers{5}.
    3. The <code> element will receive data-line-numbers and data-line-numbers-max-digits="n" attributes.

    Example CSS Implementation:

    code[data-line-numbers] {
      counter-reset: line;
    }
    
    code[data-line-numbers] > [data-line]::before {
      counter-increment: line;
      content: counter(line);
      display: inline-block;
      width: 0.75rem;
      margin-right: 2rem;
      text-align: right;
      color: gray;
    }
    code[data-line-numbers] {
      counter-reset: line;
    }
    
    code[data-line-numbers] > [data-line]::before {
      counter-increment: line;
      content: counter(line);
      display: inline-block;
      width: 0.75rem;
      margin-right: 2rem;
      text-align: right;
      color: gray;
    }
    
    code[data-line-numbers-max-digits="2"] > [data-line]::before {
      width: 1.25rem;
    }
  6. Use rehype-pretty-code in React Server Components

    master

    You can use rehype-pretty-code within React Server Components (RSC) by processing the code string through a unified pipeline.

    Implementation Steps:

    1. Create an async function that uses unified, remark-parse, remark-rehype, rehype-pretty-code, and rehype-stringify to process the code.
    2. Return the processed string.
    3. Use dangerouslySetInnerHTML to render the result in your component.

    Example Component:

    import * as React from "react";
    import { unified } from "unified";
    import remarkParse from "remark-parse";
    import remarkRehype from "remark-rehype";
    import rehypeStringify from "rehype-stringify";
    import rehypePrettyCode from "rehype-pretty-code";
    
    export async function Code({ code }: { code: string }) {
      const highlightedCode = await highlightCode(code);
      return (
        <section
          dangerouslySetInnerHTML={{
            __html: highlightedCode,
          }}
        />
      );
    }
    
    async function highlightCode(code: string) {
      const file = await unified()
        .use(remarkParse)
        .use(remarkRehype)
        .use(rehypePrettyCode, {
          keepBackground: false,
        })
        .use(rehypeStringify)
        .process(code);
    
      return String(file);
    }
  7. View integration examples for various frameworks

    master

    Rehype Pretty Code provides specific integration examples for several popular web frameworks and environments. You can explore these examples to see how to set up the plugin in your specific stack:

    • SvelteKit: Integration for Svelte-based projects.
    • Astro: Integration for Astro-based projects.
    • CDN: A simple index.html example using CDN-based integration.
    • Next.js: Integration for Next.js projects.
  8. Use rehype-pretty-code in React Server Components (RSC)

    master

    You can use rehype-pretty-code within React Server Components by processing the code string through a unified pipeline.

    1. Create an async function that uses unified, remark-parse, remark-rehype, rehype-pretty-code, and rehype-stringify to process the code.
    2. Wrap the resulting HTML in a component using dangerouslySetInnerHTML.
    3. Import and use this component within your RSC pages.
    import * as React from "react";
    import { unified } from "unified";
    import remarkParse from "remark-parse";
    import remarkRehype from "remark-rehype";
    import rehypeStringify from "rehype-stringify";
    import rehypePrettyCode from "rehype-pretty-code";
    
    export async function Code({ code }: { code: string }) {
      const highlightedCode = await highlightCode(code);
      return (
        <section
          dangerouslySetInnerHTML={{
            __html: highlightedCode,
          }}
        />
      );
    }
    
    async function highlightCode(code: string) {
      const file = await unified()
        .use(remarkParse)
        .use(remarkRehype)
        .use(rehypePrettyCode, {
          keepBackground: false,
        })
        .use(rehypeStringify)
        .process(code);
    
      return String(file);
    }
    import * as React from "react";
    import { Code } from "./code.tsx";
    
    export default async function Page() {
      return (
        <main>
          <Code code="`const numbers = [1, 2, 3]{:js}`" />
        </main>
      );
    }