generated at
数式をpreviewするUserScript
数式記法 (scrapbox)を記法むき出し状態のときにreal-timeでpreviewするUserScript
使い方
次のcodeを自分のページの script.js に書く
js
import('/api/code/programming-notes/数式をpreviewするUserScript/script.js');
もしくは以下の実行結果を自分のページの script.js から読み込めるように自分のprojectに書き込んでおく
UserScriptの危険性を考慮して自分のprojectからimportしたいけど、コードを何ファイルもコピペするのが面倒な人向け
sh
deno run -A --unstable https://scrapbox.io/api/code/takker/UserScriptをbundleするDeno_script/build.ts "https://scrapbox.io/api/code/programming-notes/数式をpreviewするUserScript/script.js" --bundle --minify --charset=utf8 --outfile=script.min.js

features
[$ ] 内でTeXを打つと、どんな数式になるかpreviewしてくれるよ
こんな感じでE=mc^2
数式にミスが有ると、どこにミスが有るのか教えてくれるよ
{aligned} とかもちゃんと表示できるよ
\begin{aligned}\int\sin\theta\mathrm{d}\theta=&\int\mathrm{d}(-\cos\theta)\\=&-\cos\theta+C\quad.\mathrm{for}\exist C\in\Bbb{R}\end{aligned}
mobileの場合は、長押しすると出てくる

実装
popupに数式を出してみるに微調節を加えただけ

お借りしたもの
これをベースにpopup-container@0.1.0を実装しました

2021-07-16 19:35:12 update to popup-container@0.1.1
2021-05-26 13:53:44 .formula の監視部分をmemo化した
2021-05-25 15:53:28 custom elementをやめてElement.shadowRootにReact appをmountする

dependencies
script.js
import {html, render} from '../htm@3.0.4%2Fpreact/script.js'; import {useKaTeX} from '../use-KaTeX/script.js'; import {useState} from '../preact@10.5.13/hooks.js'; import {tag} from '../popup-container@0.1.2/script.js'; import {useCursorObserver} from '../use-cursor-observer/script.js'; const App = () => { const {ref, error, setFormula} = useKaTeX(''); // 数式rendering用hook const [open, setOpen] = useState(false); // popupの開閉 const [cursor, setCursor] = useState({ top: 0, left: 0, }); // cursorの位置 // .formula内にcursorが来たらpreviewを開始する useCursorObserver(({ cursorRect: {left}, parentRect: {top: editorTop, left: editorLeft}, elements }) => { const formulaDOM = elements.find(element => element.classList.contains('formula')); if (!formulaDOM) { setOpen(false); return; } setOpen(true); setFormula(formulaDOM.textContent.slice(3, -1)); // popupを出すy座標は、[$ ]の上端に合わせる const {top: formulaTop} = formulaDOM.getBoundingClientRect(); setCursor({ top: formulaTop - editorTop, left: left - editorLeft, }); }); return html` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.css" /> <style> .error {color:#fd7373; } .katex-display { display: inline-block !important; margin: 0 !important; text-align: inherit !important; color: #eee; } </style> <${tag} cursor-top="${cursor.top}" cursor-left="${cursor.left}" open="${open}"> ${error && html`<span class="error">${error}</span>`} <span class="katex-display" ref="${ref}" /> </${tag}> `; };

script.js
const app = document.createElement('div'); app.dataset.userscriptName= 'katex-previewer'; document.getElementById('editor').append(app); app.attachShadow({mode: 'open'}); render(html`<${App} />`, app.shadowRoot);

Deno