MathML用 スニペット

以前[MathMLの使い方を解説した記事](https://qiita.com/Clomy17/items/083aa771a4f7c6eb12d7)を書きました．
実際にMathMLを記述したい場合，ベタ書きの大変さはHTMLの比ではありません．

もちろんベタ書きではなく，TeX等の文法で書いてコンバータをかます方法もあります．しかし，不可視のUnicode文字たち（`<mo>&af;</mo>`や`<mo>&it;</mo>`）等の問題が存在するため限度がありますし，確認のために同じ数式をもう一度読むハメになるかもしれません．

そこで，ベタ書きのために当然使うことになるスニペットの例を紹介します．

ちなみに自分は[denippet.vim](https://zenn.dev/uga_rosa/articles/494805861d774a)を使っていて，設定ファイルはtomlなので，スニペットの例の紹介もtomlになっています．json等の形式には適宜変換してください．

## 基本的なMathML要素のタグ
MathMLをベタ書きするような人なら，`<math>`と入力すれば閉じタグ`</math>`が自動で挿入されるようになっていると思います．ただ`<>`すら面倒だったり，使用頻度の割に文字数が多かったり（`<msubsup>`とか…）するので一通り登録しておいた方が楽だと思います：
```toml:mrowの例
[mrow]
prefix = 'mr'
body = """
<mrow>
\t$1
</mrow>$0"""
```

## 特殊文字入力
∀（U+2200）や斜体の𝑥（U+1D465）といった数学用の文字や記号などを入力する際，いちいち覚えていられない数値実体参照（`<mo>&#x2200;</mo>``<mi>&#x1d465;</mi>`等々）は論外として，文字実体参照でも入力ミスがプレビューを見るまで気付きにくい等の欠点があります．
そのため文字の直接入力がおすすめです．

それを入力するスニペットの実装方法として，それを囲むMathML要素を含むか含まないかの2通りあり，
- 含む場合は，圏論などで`<mi>𝐒𝐞𝐭</mi>`と書くのが面倒
- 含まない場合は，ほとんどの場合でスニペットの展開コマンドが1回増える

とそれぞれ利点と欠点はありますが，自分は前者を採用し，`<mi>𝐒𝐞𝐭</mi>`のようなものを使いたくなったら，一時的に登録して対応しています．
```toml:例
[2200]
prefix = 'moforall'
body = '<mo>∀</mo>'

[1D465]
prefix = 'mix'
body = '<mi>𝑥</mi>'
```
Unicodeにおける数学用の文字と記号の一覧は[Wikipediaの記事](https://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unicode)に大体あるので，そこら辺を参照してもらうのがいいと思います．

よく使う分だけでも結構な量があるので，適当にpythonにでもスニペットの設定ファイルをテキスト出力してもらいましょう．
ただし，prefixは[文字実体参照のリスト](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references)から引っ張ってくるのもありですが，どうせ覚えることになるので手入力した方がいいかと思います．
（自分のは文字実体参照とかTexコマンドとか更に簡略した形とかまちまちなので，もう少し整理できたら公開します…）
```python:Mathematical Alphanumeric Symbols blockの例
import html
element = "mi"
## 順に太字立体，斜体，太字斜体，スクリプト体，フラクトゥール体，黒板太字体．このあとサンセリフ体が続くが，使っていないので省略．
command = ["bn", "", "b", "r", "fr", "opf"]
Hex = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
hex = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
Eng = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
Gre = ["A","B","G","D","E","Z","H","U","I","K","L","M","N","J","O","P","R","Usymbol","S","T","Y","F","X","C","V","nabla","a","b","g","d","e","z","h","u","i","k","l","m","n","j","o","p","r","sfinal","s","t","y","f","x","c","v","partial","esymbol","usymbol","ksymbol","fsymbol","rsymbol","psymbol"]
k = 0
com_index = 0
for i in range(16):
    for j in range(16):
        print("[U+1D4" + Hex[i] + Hex[j] + "]\nprefix = '" + element + command[com_index] + Eng[k] + "'\nbody = \"<" + element + ">" + html.unescape("&#x22"+str(hex[i])+str(hex[j])+";") + "</" + element + ">\"")
        k += 1
        if k > 51:
            com_index += 1
            k = 0
for i in range(16):
    for j in range(10):
        print("[U+1D5" + Hex[i] + Hex[j] + "]\nprefix = '" + element + command[com_index] + Eng[k] + "'\nbody = \"<" + element + ">" + html.unescape("&#x22"+str(hex[i])+str(hex[j])+";") + "</" + element + ">\"")
        k += 1
        if k > 51:
            com_index += 1
            k = 0
```
斜体のℎに対応するU+1D45xが欠番でU+210Eにそれがあるなど，ところどころ穴があるので，手動で変える必要があります．
ちなみに，スクリプト体の大文字は[異体字として丸文字と花文字が実装されている](https://www.unicode.org/charts/PDF/U1D400.pdf#page=25)のですが，対応するフォント指定が面倒なのでサボってます．（エディタのフォントもいじらないといけないので，ちょっと面倒…）

## その他
`()`とか`[]`も普通は自動入力してくれないし，`<mo></mo>`を登録しておいて中に入れる，というのも毎回2回やるのは面倒なので，丸ごと登録した方が楽です：
```toml:[]の例
[005B005D]
prefix = 'mo[]'
body = """
<mo>[</mo>
$0
<mo>]</mo>"""
```