markdown-it&prismjs&nextjs
Diff-highlight with markdown-it-prism
- markdown-it-prism 形式ではDOMをいじる形式のプラグインはすべて使えない
- DOMが生成される前にmarkdown-itの処理が完了するが、その中でprismjsとpluginの処理がよばれてしまうため (https://github.com/jGleitz/markdown-it-prism/issues/71)
- なんならSSRなら尚更使えない
- Diff-highlightプラグインも
-
diff
としてパースされたものを正規表現でcode段階までもどす - 本来の言語でハイライト
- diffに合わせて追加でcssのclassをさしこむ
-
の形で処理しているのでzenn-cliではそのままつかえない
-> 実は使えるかもしれない...(後述)
逆にいえば、同じ処理をDOM非依存で完結させてしまえばzennのようなprismをnodejsパッケージとして組み込むプログラムでもdiff+languageのハイライトが入れられる
をベースに- https://prismjs.com/docs/global.html#GrammarToken
- https://prismjs.com/docs/Token.html
- https://prismjs.com/docs/global.html#TokenStream
- https://prismjs.com/docs/Token.html#type
- https://prismjs.com/docs/Prism.hooks.html
あたりを参考にしつつ処理を実装する。
envがそのままだと使えないのでかなり面倒だが理論的には出来そう
-> PrismのHookのcallbackの形式がたまたま通ったので使えちゃった......(後述)
今回問題のwrap
処理は https://prismjs.com/docs/prism-core.js.html#line816 でよばれていそう
拡張機能で渡される env
のタイプ(実際はこの中の部分集合)
export interface Environment extends Record<string, any> {
selector?: string;
element?: Element;
language?: string;
grammar?: Grammar;
code?: string;
highlightedCode?: string;
type?: string;
content?: string;
tag?: string;
classes?: string[];
attributes?: Record<string, string>;
parent?: Array<string | Token>;
}
diff-highlight
, どうも生成されたDOMをいじるのはいじるが、Renderされたもの(HTMLElement)をいじるのではなく'string'の段階のものをいじるので使えるはずではないか?と思った
都合の良いことに、diff-highlight
の追加するcallbackのhookとPrism.highlight
の呼び出すhook がぴったり同じだったのでmarkdown-itのプラグイン内で先に必要なlanguage-diff
と共に読み込みさえしてしまえば使えそう
ということで型を上のprismjs
のDocから拝借して強制的に型をしばったりごまかしたりして(本当は絶対によくないが型定義ファイルをいじりたくなかった)
Done.->
ちなみに、見れば見る程「markdown-it-prismが仮にdiff-highlightを読み込めるならそのまま使えるんじゃね?」という気持ちになった。
ただ普通にzenn-editor
のmdPrism
にloadPrismPluginを復元しても手元では動かなかったのでまた別の問題がありそう,とりあえず目的は達成できたのでclose.