数式をpreviewするUserScript
使い方
次のcodeを自分のページのscript.jsに書く
code:js
import('/api/code/programming-notes/数式をpreviewするUserScript/script.js');
もしくは以下の実行結果を自分のページのscript.jsから読み込めるように自分のprojectに書き込んでおく
code:sh
features
[$ ]内でTeXを打つと、どんな数式になるかpreviewしてくれるよ
こんな感じで$ E=mc^2
https://gyazo.com/52ef50b5ef74eb17cbaf365571af1d80
数式にミスが有ると、どこにミスが有るのか教えてくれるよ
{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}
https://gyazo.com/bd426c7ce9600b2eefe6fbd808f3b6f0
mobileの場合は、長押しすると出てくる
実装
お借りしたもの
2021-05-26 13:53:44 .formulaの監視部分をmemo化した
dependencies
code: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
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`
<style>
.error {color:#fd7373; }
.katex-display {
display: inline-block !important;
margin: 0 !important;
text-align: inherit !important;
}
</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}>
`;
};
code: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.icon