generated at
数式間で任意のマクロを共有するためのUserScript
概要
数式間で保持されるマクロ定義ができるようにする
(= 無効化されているKatexの機能を有効にする)

how to use
任意のページの一行目に \show \verb \verb{} と書く
import "/api/code/RrMg4Kn7Pgk-HQwximSddmt9/katex-patch/patch.js"
自分用に公開プロジェクトからimportできるようにまとめた。

アップデート
2022/08/17 : 一行目に上の数式を書かなくてもパッチを有効化できるようになった
2022/09/08 : tagが別々の数式ブロック間で共有されてしまう問題を修正
2022/10/12 : tagのリフレッシュ処理の問題を修正

備考
"raw HTML" 機能を有効化したいときはコメントアウトを消す
GitHub - balthild/katex-physics: Implemented some commands in LaTeX physics package for KaTeX のマクロはそのままコピペして正常に動作した
追記 : これを使いたいときは const macros = {} の代わりに import { macros } from "../KatexPhysics/macros.js"; としてmacroを読み込む
モンキーパッチなので動作は保証できない
追記:一行目に上の数式を書かなくてもパッチを有効化できるようになったが、ページの構造に依存するので書いたほうが無難と思う。
katex.__defineMacro はmacrosオブジェクトへの代入をしているだけであり, ここ以外でkatexを呼んでいないので適当に置き換え

script.js
const macros = {} function deco_parse(o_parse) { return function parse(){ const hasdeftag = macros.hasOwnProperty("\\df@tag"); this.settings.macros = this.gullet.macros.current = macros; try { const res = o_parse.call(this); return res } finally { if (hasdeftag) { delete macros["\\df@tag"] } } } } const o_consolelog = console.log; console.log = function logpatch(...args){ if (args.length == 5 && args[2].type === "verb"){ o_consolelog("patch"); const macro_info = args[2]; let o_handler = macro_info.handler; macro_info.handler = function(t, i, s){ const o_parse = Object.getPrototypeOf(t.parser).parse; Object.getPrototypeOf(t.parser).parse = deco_parse(o_parse); //Object.getPrototypeOf(t.parser.settings).isTrusted = _=>true; console.log = o_consolelog; macro_info.handler = o_handler; } } else { o_consolelog(...args) } } const patch_code = "[$ \\show \\verb ][$ \\verb{} ]" function enablepatch() { switch (scrapbox.Layout) { case "page":   const line = getReactFiber(document.querySelector("#editor > div > div.lines > div:nth-child(2)"))   .return.stateNode   line.props.children = patch_code   line.props.codeBlock = undefined   line.props.tableBlock = undefined   line.props.cli = undefined   line.props.helpfeel = undefined line.updater.enqueueForceUpdate(line) break case "list": getReactFiber(document.querySelector("li > a > div.content")) .child.sibling.type({page:{}}).type({page:{descriptions:[""]}}) .props.children[1][0].type({children:patch_code}) break case "stream": console.log("stream") getReactFiber(document.querySelector( "div.stream > div.lazy-render > div.time-range > div.page > div.lines > div:last-child")) .child.type({children:""}).props.children.type({children: patch_code}) break default: break } } enablepatch() const app = document.querySelector("#app-container")._reactRootContainer._internalRoot.current.child.stateNode; const display_style = app._stores.find(obj=>obj.constructor.name=="DisplayStyle"); function forceUpdate(){ display_style.style['hide-dots'] = true; app.onStoreChange(); display_style.style['hide-dots'] = false; app.onStoreChange(); } forceUpdate();


実装メモ
1. katexのデバッグ用のbuilt-inマクロ \show では console.log にマクロの定義オブジェクトを流すのでこれを拾う
2. マクロの定義された関数を置き換えてパーサーのオブジェクトを拾う
3. プロパティを書き換える
4. [$ \show \verb ] [$ \verb{} ] をscrapboxにレンダリングさせるとモンキーパッチが通る。
右のメニューから呼べるhide dots時に再レンダリングされるのでこれをスクリプトから呼ぶことで実現