上付き文字、下付き文字への変換[例 Ex1 → ᴱˣ¹, Ex1 → ᴇₓ₁]

# Emacs-Lisp

## 上付き文字への変換

コマンド <code>M-x replace-to-superscript-region</code> で、範囲指定したテキストの中に

```text:変換対象文字
0123456789
ABCDEFGHIJKLMNOPQRTUVW
abcdefghijklmnopqrstuvwxyz
()-=+

ÆæðøĦħŋœƎƫǀǁǂȢɐɑɒɓɔɕɖɗɘəɛɜɜɞ
ɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɻ
ɽɾʀʁʂʃʄʈʉʊʋʍʎʏʐʑʒʕʘʙʛʜʝʟʡʢʣʤ
ʥʦʧʨʩʪʫːˑβγδθφχабвгдежзиклмн
опрстуфхцчшъыьэюіјҫүұӏәөნᴂᴖᴗ
ᴜᴝᴥᵻᶅᶑⱱⵡꙑꚉꜧꝯꞎꬷꭒꭦꭧ𝼄𝼅𝼆𝼈𝼊𝼞
```

があった場合は

```text:上付き文字
⁰¹²³⁴⁵⁶⁷⁸⁹
ᴬᴮꟲᴰᴱꟳᴳᴴᴵᴶᴷᴸᴹᴺᴼᴾꟴᴿᵀᵁⱽᵂ
ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖ𐞥ʳˢᵗᵘᵛʷˣʸᶻ
⁽⁾⁻⁼⁺

ᴭ𐞃ᶞ𐞢ꟸ𐞕ᵑꟹᴲᶵ𐞶𐞷𐞸ᴽᵄᵅᶛ𐞅ᵓᶝ𐞋𐞌𐞎ᵊᵋᵌᵌ𐞏
ᶡ𐞓ᶢ𐞒ˠ𐞑ᶣʱ𐞗ᶤᶥᶦꭞ𐞛ᶩ𐞞ᵚᶭᶬᶮᶯᶰᶱ𐞣𐞤ᶲʴʵ
𐞨𐞩𐞪ʶᶳᶴ𐞘𐞯ᶶᶷᶹꭩ𐞠𐞲ᶼᶽᶾˤ𐞵𐞄𐞔𐞖ᶨᶫ𐞳𐞴𐞇𐞊
𐞉𐞬𐞮𐞫𐞐𐞙𐞚𐞁𐞂ᵝᵞᵟᶿᵠᵡ𞀰𞀱𞀲𞀳𞀴𞀵𞀶𞀷𞀸𞀹𞀺𞀻ᵸ
𞀼𞀽𞀾𞀿𞁀𞁁𞁂𞁃𞁄𞁅𞁆ꚜ𞁇ꚝ𞁈𞁉𞁌𞁍𞁫𞁏𞁭𞁐𞁋𞁎ჼᵆᵔᵕ
ᶸᵙᵜᶧᶪ𐞍𐞰ⵯ𞁬𞁊ꭜꝰ𐞝ꭝꭟ𐞈𐞭𐞜𐞟𐞡𐞧𐞹𐞺
```

に変換します。

コマンド <code>M-x replace-to-superscript</code> はその場の１文字を変換します。

逆変換では以下のコマンドを用意しています。
- <code>M-x replace-from-superscript</code>
- <code>M-x replace-from-superscript-region</code>

<code>M-x ucs-normalize-NFKC-region</code> でも可能ですが、U+207B <code>⁻</code> が半角 U+002D <code>-</code> ではなく全角 U+2212 <code>−</code> になるので注意してください。

## 下付き文字への変換

コマンド <code>M-x replace-to-subscript-region</code> で、範囲指定したテキストの中に

```text:変換対象文字
0123456789
ABCDEFGHIJKLMNOPQRSTUVWYZ
aehijklmnoprstuvx()+-
=əβγρφχабвгдежзиклопсуфхцчшъыѕіџґ
```

があった場合は

```text:下付き文字
₀₁₂₃₄₅₆₇₈₉
ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘꞯʀꜱᴛᴜᴠᴡʏᴢ
ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ₍₎₊₋
₌ₔᵦᵧᵨᵩᵪ𞁑𞁒𞁓𞁔𞁕𞁖𞁗𞁘𞁙𞁚𞁛𞁜𞁝𞁞𞁟𞁠𞁡𞁢𞁣𞁤𞁥𞁦𞁩𞁨𞁪𞁧
```

に変換します。

コマンド <code>M-x replace-to-subscript</code> はその場の１文字を変換します。

逆変換では以下のコマンドを用意しています。
- <code>M-x replace-from-subscript</code>
- <code>M-x replace-from-subscript-region</code>

&lt;sub&gt; 指定ではない文字を割り当てているので、 <code>M-x ucs-normalize-NFKC-region</code> では英大文字が変換されません。

## ソースコード

<details><summary>Emacs-lisp (折りたたみ)</summary><div>

```emacs-lisp:
(defconst ucs-superscript-symbols-alist
  '(("0" . "⁰") ("1" . "¹") ("2" . "²") ("3" . "³") ("4" . "⁴")
    ("5" . "⁵") ("6" . "⁶") ("7" . "⁷") ("8" . "⁸") ("9" . "⁹")

    ("A" . "ᴬ") ("B" . "ᴮ") ("C" . "ꟲ") ("D" . "ᴰ") ("E" . "ᴱ") ("F" . "ꟳ")
    ("G" . "ᴳ") ("H" . "ᴴ") ("I" . "ᴵ") ("J" . "ᴶ") ("K" . "ᴷ") ("L" . "ᴸ")
    ("M" . "ᴹ") ("N" . "ᴺ") ("O" . "ᴼ") ("P" . "ᴾ") ("Q" . "ꟴ") ("R" . "ᴿ")
    ("T" . "ᵀ") ("U" . "ᵁ") ("V" . "ⱽ") ("W" . "ᵂ")

    ("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" . "ᶻ")

    ("(" . "⁽") (")" . "⁾") ("-" . "⁻") ("=" . "⁼") ("+" . "⁺")

    ("Æ" . "ᴭ") ("æ" . "𐞃") ("ð" . "ᶞ") ("ø" . "𐞢") ("Ħ" . "ꟸ")
    ("ħ" . "𐞕") ("ŋ" . "ᵑ") ("œ" . "ꟹ") ("Ǝ" . "ᴲ") ("ƫ" . "ᶵ")
    ("ǀ" . "𐞶") ("ǁ" . "𐞷") ("ǂ" . "𐞸") ("Ȣ" . "ᴽ") ("ɐ" . "ᵄ")
    ("ɑ" . "ᵅ") ("ɒ" . "ᶛ") ("ɓ" . "𐞅") ("ɔ" . "ᵓ") ("ɕ" . "ᶝ")
    ("ɖ" . "𐞋") ("ɗ" . "𐞌") ("ɘ" . "𐞎") ("ə" . "ᵊ") ("ɛ" . "ᵋ")
    ("ɜ" . "ᵌ") ("ɜ" . "ᶟ") ("ɞ" . "𐞏") ("ɟ" . "ᶡ") ("ɠ" . "𐞓")
    ("ɡ" . "ᶢ") ("ɢ" . "𐞒") ("ɣ" . "ˠ") ("ɤ" . "𐞑") ("ɥ" . "ᶣ")
    ("ɦ" . "ʱ") ("ɧ" . "𐞗") ("ɨ" . "ᶤ") ("ɩ" . "ᶥ") ("ɪ" . "ᶦ")
    ("ɫ" . "ꭞ") ("ɬ" . "𐞛") ("ɭ" . "ᶩ") ("ɮ" . "𐞞") ("ɯ" . "ᵚ")
    ("ɰ" . "ᶭ") ("ɱ" . "ᶬ") ("ɲ" . "ᶮ") ("ɳ" . "ᶯ") ("ɴ" . "ᶰ")
    ("ɵ" . "ᶱ") ("ɶ" . "𐞣") ("ɷ" . "𐞤") ("ɸ" . "ᶲ") ("ɹ" . "ʴ")
    ("ɻ" . "ʵ") ("ɽ" . "𐞨") ("ɾ" . "𐞩") ("ʀ" . "𐞪") ("ʁ" . "ʶ")
    ("ʂ" . "ᶳ") ("ʃ" . "ᶴ") ("ʄ" . "𐞘") ("ʈ" . "𐞯") ("ʉ" . "ᶶ")
    ("ʊ" . "ᶷ") ("ʋ" . "ᶹ") ("ʍ" . "ꭩ") ("ʎ" . "𐞠") ("ʏ" . "𐞲")
    ("ʐ" . "ᶼ") ("ʑ" . "ᶽ") ("ʒ" . "ᶾ") ("ʕ" . "ˤ") ("ʘ" . "𐞵")
    ("ʙ" . "𐞄") ("ʛ" . "𐞔") ("ʜ" . "𐞖") ("ʝ" . "ᶨ") ("ʟ" . "ᶫ")
    ("ʡ" . "𐞳") ("ʢ" . "𐞴") ("ʣ" . "𐞇") ("ʤ" . "𐞊") ("ʥ" . "𐞉")
    ("ʦ" . "𐞬") ("ʧ" . "𐞮") ("ʨ" . "𐞫") ("ʩ" . "𐞐") ("ʪ" . "𐞙")
    ("ʫ" . "𐞚") ("ː" . "𐞁") ("ˑ" . "𐞂") ("β" . "ᵝ") ("γ" . "ᵞ")
    ("δ" . "ᵟ") ("θ" . "ᶿ") ("φ" . "ᵠ") ("χ" . "ᵡ") ("а" . "𞀰")
    ("б" . "𞀱") ("в" . "𞀲") ("г" . "𞀳") ("д" . "𞀴") ("е" . "𞀵")
    ("ж" . "𞀶") ("з" . "𞀷") ("и" . "𞀸") ("к" . "𞀹") ("л" . "𞀺")
    ("м" . "𞀻") ("н" . "ᵸ") ("о" . "𞀼") ("п" . "𞀽") ("р" . "𞀾")
    ("с" . "𞀿") ("т" . "𞁀") ("у" . "𞁁") ("ф" . "𞁂") ("х" . "𞁃")
    ("ц" . "𞁄") ("ч" . "𞁅") ("ш" . "𞁆") ("ъ" . "ꚜ") ("ы" . "𞁇")
    ("ь" . "ꚝ") ("э" . "𞁈") ("ю" . "𞁉") ("і" . "𞁌") ("ј" . "𞁍")
    ("ҫ" . "𞁫") ("ү" . "𞁏") ("ұ" . "𞁭") ("ӏ" . "𞁐") ("ә" . "𞁋")
    ("ө" . "𞁎") ("ნ" . "ჼ") ("ᴂ" . "ᵆ") ("ᴖ" . "ᵔ") ("ᴗ" . "ᵕ")
    ("ᴜ" . "ᶸ") ("ᴝ" . "ᵙ") ("ᴥ" . "ᵜ") ("ᵻ" . "ᶧ") ("ᶅ" . "ᶪ")
    ("ᶑ" . "𐞍") ("ⱱ" . "𐞰") ("ⵡ" . "ⵯ") ("ꙑ" . "𞁬") ("ꚉ" . "𞁊")
    ("ꜧ" . "ꭜ") ("ꝯ" . "ꝰ") ("ꞎ" . "𐞝") ("ꬷ" . "ꭝ") ("ꭒ" . "ꭟ")
    ("ꭦ" . "𐞈") ("ꭧ" . "𐞭") ("𝼄" . "𐞜") ("𝼅" . "𐞟") ("𝼆" . "𐞡")
    ("𝼈" . "𐞧") ("𝼊" . "𐞹") ("𝼞" . "𐞺")
    ))

(defconst ucs-subscript-symbols-alist
  '(("0" . "₀") ("1" . "₁") ("2" . "₂") ("3" . "₃") ("4" . "₄")
    ("5" . "₅")("6" . "₆") ("7" . "₇") ("8" . "₈") ("9" . "₉")

    ("A" . "ᴀ") ("B" . "ʙ") ("C" . "ᴄ") ("D" . "ᴅ") ("E" . "ᴇ") ("F" . "ꜰ")
    ("G" . "ɢ") ("H" . "ʜ") ("I" . "ɪ") ("J" . "ᴊ") ("K" . "ᴋ") ("L" . "ʟ")
    ("M" . "ᴍ") ("N" . "ɴ") ("O" . "ᴏ") ("P" . "ᴘ") ("Q" . "ꞯ") ("R" . "ʀ")
    ("S" . "ꜱ") ("T" . "ᴛ") ("U" . "ᴜ") ("V" . "ᴠ") ("W" . "ᴡ")
    ("Y" . "ʏ") ("Z" . "ᴢ")

    ("a" . "ₐ") ("e" . "ₑ")
    ("h" . "ₕ") ("i" . "ᵢ") ("j" . "ⱼ") ("k" . "ₖ") ("l" . "ₗ")
    ("m" . "ₘ") ("n" . "ₙ") ("o" . "ₒ") ("p" . "ₚ") ("r" . "ᵣ")
    ("s" . "ₛ") ("t" . "ₜ") ("u" . "ᵤ") ("v" . "ᵥ") ("x" . "ₓ")

    ("(" . "₍") (")" . "₎") ("+" . "₊") ("-" . "₋") ("=" . "₌")

    ("ə" . "ₔ") ("β" . "ᵦ") ("γ" . "ᵧ") ("ρ" . "ᵨ") ("φ" . "ᵩ")
    ("χ" . "ᵪ") ("а" . "𞁑") ("б" . "𞁒") ("в" . "𞁓") ("г" . "𞁔")
    ("д" . "𞁕") ("е" . "𞁖") ("ж" . "𞁗") ("з" . "𞁘") ("и" . "𞁙")
    ("к" . "𞁚") ("л" . "𞁛") ("о" . "𞁜") ("п" . "𞁝") ("с" . "𞁞")
    ("у" . "𞁟") ("ф" . "𞁠") ("х" . "𞁡") ("ц" . "𞁢") ("ч" . "𞁣")
    ("ш" . "𞁤") ("ъ" . "𞁥") ("ы" . "𞁦") ("ѕ" . "𞁩") ("і" . "𞁨")
    ("џ" . "𞁪") ("ґ" . "𞁧")))

(defun replace-some-chars (beg end callback)
  (let (pos (swp (< end beg)))
    (when swp (setq pos end) (setq end beg) (setq beg pos))
    (goto-char beg)
    (while (< (point) end) (funcall callback))
    (goto-char (if swp beg end))))

(defun replace-to-some-char (alist)
  (let ((kv (assoc (buffer-substring (point) (1+ (point))) alist)))
    (if (not kv) (forward-char) (delete-char 1) (insert (cdr kv)))))

(defun replace-from-some-char (alist)
  (let ((kv (rassoc (buffer-substring (point) (1+ (point))) alist)))
    (if (not kv) (forward-char) (delete-char 1) (insert (car kv)))))

;; Superscript

(defun replace-to-superscript ()
  (interactive)
  (replace-to-some-char ucs-superscript-symbols-alist))

(defun replace-to-superscript-region (beg end)
  (interactive (list (mark) (point)))
  (replace-some-chars beg end 'replace-to-superscript))

(defun replace-from-superscript ()
  (interactive)
  (replace-from-some-char ucs-superscript-symbols-alist))

(defun replace-from-superscript-region (beg end)
  (interactive (list (mark) (point)))
  (replace-some-chars beg end 'replace-from-superscript))

;; Subscript

(defun replace-to-subscript ()
  (interactive)
  (replace-to-some-char ucs-subscript-symbols-alist))

(defun replace-to-subscript-region (beg end)
  (interactive (list (mark) (point)))
  (replace-some-chars beg end 'replace-to-subscript))

(defun replace-from-subscript ()
  (interactive)
  (replace-from-some-char ucs-subscript-symbols-alist))

(defun replace-from-subscript-region (beg end)
  (interactive (list (mark) (point)))
  (replace-some-chars beg end 'replace-from-subscript))
```

</div></details>

# JavaScript - CodePen

## 上付き文字への変換

<p class="codepen" data-height="228" data-default-tab="result" data-slug-hash="qBvZxEb" data-user="ikiuo" style="height: 228px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ikiuo/pen/qBvZxEb">
  Superscript: 上付き文字への変換</a> by Ikiuo (<a href="https://codepen.io/ikiuo">@ikiuo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 下付き文字への変換

<p class="codepen" data-height="228" data-default-tab="result" data-slug-hash="bGZpLdK" data-user="ikiuo" style="height: 228px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ikiuo/pen/bGZpLdK">
  Subscript: 下付き文字への変換</a> by Ikiuo (<a href="https://codepen.io/ikiuo">@ikiuo</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>