Learn Shiki Rehype Pretty Code - Meta Strings & Caption
Episode 6 of 23

Learn Shiki Rehype Pretty Code - Meta Strings & Caption

The meta string on a fenced code block is a rich configuration language: title, caption, showLineNumbers, lines, and diff. This episode dissects the meta string parsing format and its impact on the markup generated by rehype-pretty-code.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Behind the simplicity of a fenced code block there's a hidden power: the meta string. The line after the opening backtick can contain instructions like title, caption, line numbering, highlight ranges, even diff mode. rehype-pretty-code reads these instructions and translates them into HTML structure.

Episode 6 dissects how meta strings and captions work: their writing format, how the plugin parses them, and their impact on the generated markup. After this episode, you'll see fenced code blocks as a gateway to remarkable visual features.

What Is a Meta String

The Basic Format of title and caption

A meta string is the text that follows the language on the opening line of a fenced code block. Its format resembles HTML attributes. The two most frequently used are title and caption. To add both, write them on the opening line like title="app.ts" caption="Application entry point code".

JSCode with title and caption
console.log("mulai");

When title is present, rehype-pretty-code adds a title element above the <pre>. Meanwhile, caption is shown below the block. The title usually contains the file name, while the caption explains the context of the code to the reader.

How the Plugin Parses Meta

rehype-pretty-code splits the meta string with rules similar to attribute parsing: key="value" pairs for values containing spaces, and single tokens for features without a value like diff or showLineNumbers. You can combine multiple instructions in one meta line, for example showLineNumbers together with title and caption.

JSCode with showLineNumbers
export function today(): string {
  return new Date().toISOString();
}

The order of instructions doesn't matter much. What determines the result is the presence of the instructions themselves, not their position on the meta line.

The Most Frequently Used Meta Features

showLineNumbers: Showing Line Numbers

The showLineNumbers instruction brings up a number on each line. When active, the <code> element gets the data-line-numbers attribute.

JSWith showLineNumbers
const daftar = [1, 2, 3];
const total = daftar.reduce((a, b) => a + b, 0);
console.log(total);

Line numbers are very helpful when you discuss specific parts of a code in your article text, for example saying "see line 3".

lines: Highlight Ranges

The lines instruction specifies which lines are highlighted. Its syntax uses curly braces and can accept a range or a comma-separated list, like lines={2,4-6} on the opening line.

JSCode with highlighted lines
function hitung(a: number, b: number): number {
  const hasil = a + b;
  if (hasil > 10) {
    console.log("besar");
  }
  return hasil;
}

Selected lines will be marked with the data-highlighted-line attribute on the markup. This is the foundation of the line highlighting feature fully dissected in episode 7.

diff: Marking Changes

The diff instruction activates comparison mode. You then mark lines that were added or removed with the // + and // - markers on the lines themselves.

JSCode with diff markers
const a = 1;
const b = 2;
// +console.log(a + b);
// -console.log(a * b);

rehype-pretty-code translates these markers into attributes like data-added-line and data-removed-line, ready to be given green and red colors in CSS. We'll go deeper into diff in episode 8.

The Impact of Meta on Markup

From Meta to Data Attributes

Every meta instruction ends up as data attributes in the final markup. Here's the map:

  • title adds a <figcaption> element or a title div inside the <figure>.
  • caption adds a caption element below the block.
  • showLineNumbers adds data-line-numbers on <code>.
  • lines adds data-highlighted-line on the selected lines.
  • diff adds data-changed-line, data-added-line, or data-removed-line.

Because everything is attribute-based, styling doesn't need extra classes. You just target attributes in CSS.

Inspecting the Markup in DevTools

The best way to understand the impact of meta is to inspect the result directly:

Render and inspect the output
node highlight.mjs
JSFilter highlighted lines
const baris = html
  .split("\n")
  .filter((line) => line.includes("data-highlighted-line"));
console.log(baris.join("\n"));

By filtering lines containing data-highlighted-line, you can confirm that the lines meta really is translated into markup. Inspection techniques like this will be used often for debugging.

Conclusion

Key takeaways:

  • The meta string follows the language on the opening line of a fenced code block.
  • title and caption give visual context to the code block.
  • showLineNumbers shows line numbers via the data-line-numbers attribute.
  • lines selects lines for highlighting with the data-highlighted-line attribute.
  • diff activates markers for added and removed lines.
  • Every meta instruction is translated into data attributes ready for styling.

In episode 7 you'll focus on line highlighting and word highlight: combining ranges like lines={2-4,6}, CSS styling for data-highlighted-line, and marking specific words or characters with data-highlighted-chars.

Learn Shiki Rehype Pretty Code - Meta Strings & Caption | Learn Shiki Rehype Pretty Code