動機
本投稿の公開時点では、拡張機能を適用しても Markdown+ $\TeX$ の環境が不満。
-- | $\TeX$ マクロの共有 | html 形式でエクスポート | Markdown ファイルのインクルード |
---|---|---|---|
VSCode の規定 | ファイル内はブロック間で可能。ファイル間は ~/.config/Code/User/settings.json ファイルの "markdown.math.macros" に記載。 |
不可 | 不可 |
主要な Markdown 拡張 | ブロック間、ファイル間ともに不可 | 一部可能 | 一部可能 |
本投稿の対策後 | エクスポート後の共有について、拡張をカスタマイズして実現 | 拡張の規定機能 | 拡張の規定機能 |
解決策
- Markdown PDF拡張をインストール。
- Markdown PDF拡張は $\TeX$ 未サポートなのをいいことに、$\TeX$ マクロが共有できるよう、エクスポートhtmlのテンプレートをカスタマイズしながらサポートさせる。
.vscode/extensions/yzane.markdown-pdf-1.5.0/template/template.html
<!DOCTYPE html>
<html>
<head>
<title>{{{title}}}</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
{{{style}}}
<!-- mermaidが不要なら、読み込みが遅いと思うのでコメントする。 -->
<!-- {{{mermaid}}} -->
<!-- 追加ここから -->
<!-- KaTeXリソース3個をCDNから取得。最新の定義は https://katex.org/docs/autorender を参照のこと。 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" integrity="sha384-zh0CIslj+VczCZtlzBcjt5ppRcsAmDnRem7ESsYwWwg3m/OaJ2l4x7YBZl9Kxxib" crossorigin="anonymous">
<!-- The loading of KaTeX is deferred to speed up page rendering -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js" integrity="sha384-Rma6DA2IPUwhNxmrB/7S3Tno0YY7sFu9WSYMCuulLhIqYSGZ2gKCJWIqhBWqMQfh" crossorigin="anonymous"></script>
<!-- To automatically render math in text elements, include the auto-render extension: -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/contrib/auto-render.min.js" integrity="sha384-hCXGrW6PitJEwbkoStFjeJxv+fSOOQKOPbJxSfM6G5sWZjAyWhXiTIIAmQqnlLlh" crossorigin="anonymous"></script>
<script>
// マクロをオブジェクトに、キー:値形式で保持する。
const macros = {
// ~/.config/Code/User/settings.json ファイルの "markdown.math.macros" キーの値と同じ形式。容易に同期を取ることができる。
"\\iv": "^{-1}", // 例
};
document.addEventListener("DOMContentLoaded", function() {
const makeIterable = function*(xpath) {
const xPathResult = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < xPathResult.snapshotLength; i++) {
yield xPathResult.snapshotItem(i);
}
};
// Markdown PDF 拡張でディスプレイ定義がこのxpathが示す要素に変換される。
for (const e of makeIterable('//pre[@class="hljs"]/code/div')) {
const v = e.innerText.trim();
// 中身がTeXであるか判定し、満たすならレンダリングする。
// TeX 以外のプログラミング言語もこの要素になるため、あなたが利用する言語の種類により調整してください。
if (v.startsWith('\\') && v.includes('{') && v.includes('}')) {
katex.render(v, e, {
displayMode: true,
throwOnError: false,
macros: macros, // I/O :マクロが定義されるとこのオブジェクトに追加されるため、1個のmacrosオブジェクトを流用している。
globalGroup: true, // マクロ定義を外でも利用可能にするフラグ。
});
}
}
// インラインモードのTeX定義はauto-render.min.jsの機能を利用してレンダリングする。
// 制限:インラインモードで定義したマクロが、ディスプレイ定義内で利用できない。
renderMathInElement(document.body, {
delimiters: [
{left: '$', right: '$', display: false},
// https://katex.org/docs/autorender にはディスプレイモードの定義があるが、Markdown PDF 拡張の動作と不整合なので、取り除く。
],
throwOnError: false,
output: "mathml",
strict: false,
macros: macros,
});
});
</script>
<!-- 追加ここまで -->
</head>
<body>
<!-- mermaidが不要なら、読み込みが遅いと思うのでコメントする。 -->
<!--
<script>
mermaid.initialize({
startOnLoad: true,
theme: document.body.classList.contains('vscode-dark') || document.body.classList.contains('vscode-high-contrast')
? 'dark'
: 'default'
});
</script>
-->
{{{content}}}
</body>
</html>