🤖

Docusaurusで簡易的にdiff-highlight対応する

2022/08/07に公開

ドキュメントを作る際に便利な静的サイトジェネレータの1つであるDocusaurusだが、
下記のようなdiff-highlight(言語のハイライトに対応しながらdiff表示する)には対応していない。

diff-highlight

色々試行錯誤した結果、かなりHackyな方法ではあるが、対応できることが分かったのでメモとして残しておく。
(いつかはきちんと対応したい)

Docusaurusは何もカスタマイズしなくてもLine Highlightを行うことができるようになっている。

 ```js {2}
  function main() {
    return "Hello, world!";
  }
 ```

line highlight

これは、指定した行に docusaurus-highlight-code-line クラスを提供していることにより、
CSSでこのクラスに対するスタイルを指定できるようになっており、別途CSSでデザインを調整しているためである。

その処理は下記のコードで行っているため、行の先頭文字をチェックして、
更に追加のクラスをつけるように拡張する。

./node_modules/@docusaurus/theme-classic/lib-next/theme/CodeBlock/index.js

  ...
  const lineProps = getLineProps({
    line,
    key: i,
  });
  
  if (highlightLines.includes(i + 1)) {
    lineProps.className += ' docusaurus-highlight-code-line';
+   const content = line.map(l => l.content).join("");
+   if (content.startsWith("+")) {
+     lineProps.className += ' add';
+   } else if (content.startsWith("-")) {
+     lineProps.className += ' remove';
+   }
  }
  ...

ただし、これを変更してもキャッシュされているコードには影響がないため、
一度クリーンしておく必要がある。

$ npm run clean

カスタムのCSSも合わせて修正する。

./src/css/custom.css

  ...
  .docusaurus-highlight-code-line {
    background-color: rgba(0, 0, 0, 0.1);
    display: block;
    margin: 0 calc(-1 * var(--ifm-pre-padding));
    padding: 0 var(--ifm-pre-padding);
  }
+
+ .docusaurus-highlight-code-line.add {
+   background-color: rgba(0, 255, 127, 0.1);
+ }
+
+ .docusaurus-highlight-code-line.remove {
+   background-color: rgba(255, 0, 0, 0.1);
+ }

  html[data-theme='dark'] .docusaurus-highlight-code-line {
    background-color: rgba(0, 0, 0, 0.3);
  }
+
+ html[data-theme='dark'] .docusaurus-highlight-code-line.add {
+   background-color: rgba(0, 255, 127, 0.3);
+ }
+
+ html[data-theme='dark'] .docusaurus-highlight-code-line.remove {
+   background-color: rgba(255, 0, 0, 0.3);
+ }

先頭に-/+をつけてその行をハイライトすると、別のスタイルが適用される。

 ```js {2-3}
  function main() {
-   return "Hello, world!";
+   return "Hello, JavaScript!";
  }
 ```

line highlight (diff)

Discussion