tkzwhr's notes

tkzwhrの技術、中国語などのメモです。

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

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

f:id:tkzwhr:20210627140723p:plain
diff-highlight

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

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

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

f:id:tkzwhr:20210627142214p:plain
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!";
   }
 ```

f:id:tkzwhr:20210627144110p:plain
line highlight (diff)