数式間で任意のマクロを共有するための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" 機能を有効化したいときはコメントアウトを消す
追記 : これを使いたいときはconst macros = {}の代わりに import { macros } from "../KatexPhysics/macros.js";としてmacroを読み込む
モンキーパッチなので動作は保証できない
追記:一行目に上の数式を書かなくてもパッチを有効化できるようになったが、ページの構造に依存するので書いたほうが無難と思う。
katex.__defineMacroはmacrosオブジェクトへの代入をしているだけであり, ここ以外でkatexを呼んでいないので適当に置き換え
code: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) {
}
}
}
}
const o_consolelog = console.log;
console.log = function logpatch(...args){
if (args.length == 5 && args2.type === "verb"){ o_consolelog("patch");
const macro_info = args2; 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.children10.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(){
app.onStoreChange();
app.onStoreChange();
}
forceUpdate();
実装メモ
1. katexのデバッグ用のbuilt-inマクロ \show では console.log にマクロの定義オブジェクトを流すのでこれを拾う
2. マクロの定義された関数を置き換えてパーサーのオブジェクトを拾う
3. プロパティを書き換える
4. [$ \show \verb ] [$ \verb{} ] をscrapboxにレンダリングさせるとモンキーパッチが通る。
右のメニューから呼べるhide dots時に再レンダリングされるのでこれをスクリプトから呼ぶことで実現