iconguccigu blog

2025/05/04
[Rehype Pretty Code] 行数表示や行ハイライトをできるようにする

このブログではコードブロックのシンタックスハイライトに Rehype Pretty Code を使っています
Rehype Pretty Code はさらに以下などもできます

  • タイトル設定
  • 行数表示
  • 行ハイライト

ただ、これらは HTML 内に必要な情報を追加してくれるのみでスタイルは自身であてる必要があります

例えば以下のようなコードブロックを書いた場合、

 ```typescript {4} title="_404.ts" showLineNumbers
 import type { NotFoundHandler } from "hono";
 
 const handler: NotFoundHandler = (c) => {
   c.status(404);
   return c.render("404 Not Found");
 };
 
 export default handler;
 ```

以下の HTML が生成されます
(省略してますが span タグが各行のテキストになります)

<figure data-rehype-pretty-code-figure="">
    <figcaption data-rehype-pretty-code-title="" data-language="typescript" data-theme="one-dark-pro">_404.ts</figcaption>
    <pre style="background-color:#282c34;color:#abb2bf" tabindex="0" data-language="typescript" data-theme="one-dark-pro">
      <code data-line-numbers="" data-language="typescript" data-theme="one-dark-pro" style="display:grid" data-line-numbers-max-digits="1">
        <span data-line="">...</span>
        <span data-line="">...</span>
        <span data-line="">...</span>
        <span data-line="" data-highlighted-line="">...</span>
        <span data-line="">...</span>
        <span data-line="">...</span>
        <span data-line="">...</span>
        <span data-line="">...</span>
      </code>
    </pre>
</figure>
  • タイトル設定
    • title="タイトル" で指定
    • data-rehype-pretty-code-title 属性をもつ figcaption タグの要素としてタイトルが追加される
  • 行数表示
    • showLineNumbers で指定
    • code タグに data-line-numbersdata-line-numbers-max-digits 属性が追加される
      • data-line-numbers-max-digits 属性の値は行番号の最大桁数が設定される
        • ⇒ これは CSS で行数表示ブロックの幅サイズを指定する際に使う
  • 行ハイライト
    • {行番号} で指定
      • 複数行のときは {2-4} のように指定 (これは2行目から4行目となる)
    • 対象行の span タグに data-highlighted-line 属性が追加される

これらの追加された属性などに用いて CSS を書くことになります
現状では以下のようにしました

figcaption[data-rehype-pretty-code-title] {
  @apply py-2 px-4 rounded-t-md text-white bg-neutral-600;
}
 
figcaption[data-rehype-pretty-code-title] + pre {
  @apply rounded-t-none;
}
 
figure[data-rehype-pretty-code-figure] [data-highlighted-line] {
  @apply bg-sky-500/10;
}
 
code[data-line-numbers] {
  counter-reset: line;
}
 
code[data-line-numbers] > [data-line]::before {
  content: counter(line);
  counter-increment: 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;
}
 
code[data-line-numbers-max-digits="3"] > [data-line]::before {
  width: 1.75rem;
}
 
code[data-line-numbers-max-digits="4"] > [data-line]::before {
  width: 2.25rem;
}

行番号表示部分はドキュメントにサンプルがあったのでそのまま使用しました
https://rehype-pretty.pages.dev/#line-numbers

すると先ほどの例だと以下のように表示されます

_404.ts
import type { NotFoundHandler } from "hono";
 
const handler: NotFoundHandler = (c) => {
  c.status(404);
  return c.render("404 Not Found");
};
 
export default handler;

文字ハイライトなど他にもできることがありそうですがそれはまた必要になったとき対応しようと思います