vscode上でmarkdown pdf + katexで速攻で数式をpdf化

準備

とりあえずこれを入れよう

最近のvscodeはデフォルトでmath形式びmdファイルもちゃんと表示してくれるらしい

概要

vscode上でmarkdownをプレビューする時に数式を扱えるmarkdown mathやvscode内蔵のビュワーは,内部でkatexを動かしてレンダリングしながら表示しているらしく,またそのkatexはブラウザやサーバーサイドにおいてhtml+cssで完結して動くため,svgを弄ってmathmlを設定するmathjaxよりも更に軽量なアドオンらしく,そしてそのmarkdown pdfはmarkdownからhtml+cssを経由したのちにpdfに変換している…
つまりhtml+cssレンダリング処理に介入して(オプションを使って)katexを動作させれば,markdownを爆速でpdfへと変換できるね(デフォルトでは何も設定されていないため数式はレンダリングされないよ),という流れ

手順

  • コマンドパレットから拡張機能フォルダを開いてお目当てのtemplate.htmlを探す
    • macならば/Users/[ユーザー名]/.vscode/extensions/yzane.markdown-pdf-1.4.4/template/template.htmlに確実にあるはず,Windows?知らん
  • katex.org
    • をよく読む
  • katex.org
    • をよく読む
  • katex.org
    • をよく読む
  • そして以下をコピペ
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css" integrity="sha384-R4558gYOUz8mP9YWpZJjofhk+zx0AS11p36HnD2ZKj/6JR5z27gSSULCNHIRReVs" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js" integrity="sha384-z1fJDqw8ZApjGO3/unPWUPsIymfsJmyrDVWC8Tv/a1HeOtGmkwNd/7xUS0Xcnvsx" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/mathtex-script-type.min.js" integrity="sha384-jiBVvJ8NGGj5n7kJaiWwWp9AjC+Yh8rhZY3GtAX8yU28azcLgoRo4oukO87g7zDT" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/mhchem.min.js" integrity="sha384-UEY9IRPkV+TTTY7nK1wSrfhWPDJy9wr4PmYg3DLPcN5F4NDlIwGZkWtWveKR/45c"  crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/copy-tex.min.css" rel="stylesheet" type="text/css">
<script src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/copy-tex.min.js" integrity="sha384-Ep9Es0VCjVn9dFeaN2uQxgGcGmG+pfZ4eBaHxUpxXDORrrVACZVOpywyzvFRGbmv" crossorigin="anonymous"></script>
<script>
    document.addEventListener("DOMContentLoaded", function() {
        renderMathInElement(document.body, {
          delimiters: [
              {left: '$$', right: '$$', display: true},
              {left: '$', right: '$', display: false}
          ],
          throwOnError : false,
          output:"mathml",
          strict: false,
        });
    });
</script>
  • これらを{{{style}}}{{{mermaid}}}の間に(<head><\head>の中に)挟んでおく
  • {{{style}}}{{{mermaid}}}{{{content}}}レンダリング結果を注入するのに必要な起点なので消すと動かなくなる
  • delimiterは好みに書き換えても良いが困らなければこのままで良い(このままの方が良い)
  • 恐らくkatexのheadバージョンが変われば先のページも書き変わるので(srcに載ってるURLにもSSHのオプション引数が設定されているし),気が向いた際にちゃんと確認しておこう

注意点

ブラウザにレンダリングをさせるための工夫

throwOnError : falseoutput:"mathml"が必要,エラーはなるべくは無視してくれる方が良いし,"html"では後述のcopy-tex extensionが動作しなくなる,現状では"mathml"で困ることもなさそうなので

ディスプレイモードで改行を行うための工夫

strict: falseが必要かつ改行には\\\\が必要,前者はkatexの改行制限を外すため,後者は中間生成の時点で働く謎のエスケープ処理を回避するため
もし挙動が変だと思った時は一旦htmlで出力してデバッグするべし,markdown pdfの処理が自分の想定外である場合が大半

アンダースコア_の扱いの工夫

markdown pdfが強調タグ(<em><\em>)に変換しかねない,発生条件は定かではないが|_{}すると50%の確率で<em><\em>のペアに化かしてくる,必ずエスケープした\|\_{}を使う癖をつけるべし

字体の変化の正当な手順

現在のlatexでは\rm{}が正当なやり方とされているが,katexでは{\rm }を使わないと変な処理が起きて困る,理由は不明だが古い処理系を使っているせいと思われる

その他の環境を使いたい

ディスプレイモードに限定されるが,$$で囲った中身でbegin{xxx}end{xxx}を使う必要がある,そこを直で呼び出せるmathjaxとは訳が違うらしい
例)

$$
  \begin{align}
    x &= y \\\\
    &= z
  \end{align}
$$

もちろん改行には\\\\を使う

拡張機能

恐らくこれで全部のはず

mathJax後方互換

mathtex-script-type.min.jsを使う
mathタグで有効化することでmathjaxをまんま置き換えられるらしい

化学記法互換

mhchem.min.jsを使う
化学に関する記法を追加するらしい

mathmlコピペ互換

copy-tex.min.csscopy-tex.min.jsを使う
mdからhtmlに出力した際にクリップボードからlatex記法のコードをそのまま取り出せるようになる,pdfには対応していないが(ブラウザ上のclipboard apiに相当する機能がないので)htmlで見れる環境なら絶対に採用するべし