雑に書かれた数式文字列を、MathJax で使いやすいインライン数式へ変換する PopClip 拡張です。
- 選択中の数式テキストを
$...$形式のインライン数式へ整える - 変換ロジックを JavaScript の純関数
transform(input, options)に集約する - PopClip 側は最小限の配線だけにして保守しやすくする
extension/Config.plist: PopClip 拡張定義extension/replace.sh: Convert & Replace アクションextension/copy.sh: Convert & Copy アクションextension/transform-cli.js: PopClip から変換関数を呼ぶ薄い CLIextension/transform.js: 変換本体tests/transform.test.js: Node 標準テストsamples/examples.md: サンプル入出力一覧
extension/ディレクトリをText to MathJax.popclipextのような名前の拡張バンドルとしてまとめます。- その中に
Config.plist,replace.sh,copy.sh,transform-cli.js,transform.jsを含めます。 - PopClip に読み込ませます。
- ローカルで Node.js が使える環境であることを確認してください。
- 選択文字列を変換し、結果をその場で置換します。
- 選択文字列を変換し、結果をクリップボードへ送ります。
- 元の文字列は置換しません。
transform() は次の順序で処理します。
normalizeUnicode()normalizeSpaces()convertEllipsis()convertFunctions()convertGreekLetters()convertSymbols()convertRoots()convertFractionsAndDivision()convertExponentiation()convertSpacedXMultiplication()cleanupSpacing()wrapInlineMath()
- Unicode 正規化と全角半角補正を先に行います
- 連続空白は 1 個に縮約します
/は空白ありなら\div、空白なしなら分数候補として扱います√は直後の単項、または括弧付きグループにだけ適用します^は右辺が複雑なら^{...}に正規化します- 関数名変換は単語境界を見て、既存の
\sinなどは二重変換しません - ギリシャ文字や関係記号は対応表ベースで変換します
xを\timesにするのは、空白を伴う中置記法だけに限定します- 曖昧なケースは安全側を優先して変換を控えます
4.05/3.5->$\frac{4.05}{3.5}$4.05 / 3.5->$4.05 \div 3.5$√x+1->$\sqrt{x}+1$√(x+1)->$\sqrt{x+1}$a ≠ b->$a \neq b$sin^2 x + cos^2 x->$\sin^2 x+\cos^2 x$θ = π/2->$\theta=\frac{\pi}{2}$3 x 5->$3 \times 5$πr^2->$\pi r^2$
詳細な例は samples/examples.md にまとめています。
npm testNode 標準の node:test を使っているため、追加ライブラリは不要です。
- 厳密な数式構文解析はしていません
- 複雑なネスト分数は限定対応です
- 多行入力は 1 行として扱います
alignなどの複数行 MathJax 環境には対応していません- 意味的に曖昧な式は安全側で変換を控える場合があります
xを\timesとみなす判定は保守的です
*を安全に\timesへ寄せる条件を追加する- より深い分数ネストを扱う簡易トークナイザを入れる
- 上付きだけでなく下付き
_の安全変換も追加する - 既存の LaTeX コマンド列をより丁寧に保護する
- PopClip のオプションから出力ラッパーや空白方針を切り替えられるようにする