generated at
popupに数式を出してみる
popup-container@0.1.0use-KaTeXを合わせたテスト
js
import('/api/code/programming-notes/popupに数式を出してみる/script.js');
2021-05-21 00:49:43 テストのつもりが完成してしまった……
Preact楽すぎだろtakker

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}

script.js
import {html} 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 {PopupContainer, CSS} from '../popup-container@0.1.0/script.js'; import register from '../preact-custom-element@4.2.1/script.js'; import {scrapboxDOM} from '../scrapbox-dom-accessor/script.js'; import {useMutationObserver} from '../useMutationObserver/script.js'; import {throttle} from '../custom-throttle/script.js'; const App = ({formula}) => { const {ref, error, setFormula} = useKaTeX(formula); // 数式rendering用hook const [open, setOpen] = useState(false); // popupの開閉 const [cursorPosition, setCursorPosition] = useState({ styleTop: 0, styleLeft: 0, }); // cursorの位置 // .formula内にcursorが来たらpreviewを開始する // 負荷低減のために、throttleで少し間引いている const callback = throttle((mutation) => { const cursor = mutation.target; const {top, left} = cursor.getBoundingClientRect(); const elements = document.elementsFromPoint(left, top); const formulaDOM = elements.find(element => element.matches('.formula')); if (!formulaDOM) { setOpen(false); return; } setOpen(true); setFormula(formulaDOM.textContent.slice(3, -1)); setCursorPosition({ styleTop: +cursor.style.top.slice(0, -2), styleLeft: +cursor.style.left.slice(0, -2), }); }, 100); useMutationObserver([{current: scrapboxDOM.cursor}], ([mutation]) => callback(mutation), {attributes: true}); return html` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.css" /> <${CSS} /> <style> .error {color:#fd7373; } .katex-display {color: #eee;} </style> <${PopupContainer} cursorPosition="${cursorPosition}" open="${open}"> ${error && html`<span class="error">${error}</span>`} <span class="katex-display" ref="${ref}" /> <//> `; }; register(App, 'userscript-katex-test', ['formula'], {shadow: true}); document.getElementById('editor') .insertAdjacentHTML('beforeend', '<userscript-katex-test formula="E=mc^2"></userscript-katex-test>');