LaTeX で矢印の長さを調整する際に、\rightarrow
、\longrightarrow
、\longlongrightarrow
…… というように long を付け足していくのではなく、数値で調整できると便利なので作りました。
\documentclass{article}
\usepackage{expl3}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{newtxtext}
\usepackage{newtxmath}
\usepackage{silence}
\WarningsOff[latexfont]
\ExplSyntaxOn
\cs_new_eq:NN \Repeat \prg_replicate:nn
\cs_new_eq:NN \If \bool_if:nTF
\cs_new_eq:NN \Compare \int_compare_p:nNn
\ExplSyntaxOff
\newcommand{\mathstyle}[1]{\mathchoice{#1}{#1}{{\scriptsize #1}}{\tiny #1}}
\newcommand{\makearrowr}[3][0]{\mathrel{\Repeat{#1}{#2\joinrel}#3}}
\newcommand{\makearrowl}[3][0]{\mathrel{#2\Repeat{#1}{\joinrel#3}}}
\newcommand{\makearrowb}[4][0]{\mathrel{#2\joinrel\Repeat{#1}{#3\joinrel}#4}}
\newcommand{\makearrowx}[5][0]{\mathrel{\If{\Compare{#1}={0}}{#2}{#3\joinrel\Repeat{(#1) - 1}{#4\joinrel}#5}}}
\renewcommand{\to}[1][0]{\makearrowr[#1]{\relbar}{\rightarrow}}
\newcommand{\ot}[1][0]{\makearrowl[#1]{\leftarrow}{\relbar}}
\newcommand{\To}[1][0]{\makearrowr[#1]{\Relbar}{\Rightarrow}}
\newcommand{\oT}[1][0]{\makearrowl[#1]{\Leftarrow}{\Relbar}}
\newcommand{\tot}[1][0]{\makearrowx[#1]{\leftrightarrow}{\leftarrow}{\relbar}{\rightarrow}}
\newcommand{\ToT}[1][0]{\makearrowx[#1]{\Leftrightarrow}{\Leftarrow}{\Relbar}{\Rightarrow}}
% mapping
\newcommand{\mto}[1][0]{\makearrowx[#1]{\mapsto}{\vdash}{\relbar}{\rightarrow}}
\newcommand{\otm}[1][0]{\makearrowx[#1]{\mathstyle{\reflectbox{\(\mapsto\)}}}{\leftarrow}{\relbar}{\dashv}}
\newcommand{\Mto}[1][0]{\makearrowb[#1]{\mathrel{\mathstyle{\raisebox{0.23ex}{\scalebox{1}[0.6]{\(\mid\)}}\mkern-1mu}}}{\Relbar}{\Rightarrow}}
\newcommand{\otM}[1][0]{\makearrowb[#1]{\Leftarrow}{\Relbar}{\mkern-1mu\mathrel{\mathstyle{\raisebox{0.23ex}{\scalebox{1}[0.6]{\(\mid\)}}}}}}
% partial
\newcommand{\pto}[1][0]{\makearrowr[#1]{\relbar}{\rightharpoonup}}
\newcommand{\otp}[1][0]{\makearrowl[#1]{\leftharpoonup}{\relbar}}
% injective
\newcommand{\ito}[1][0]{\makearrowb[#1]{\lhook}{\relbar}{\rightarrow}}
\newcommand{\oti}[1][0]{\makearrowb[#1]{\leftarrow}{\relbar}{\rhook}}
% surjective
\newcommand{\sto}[1][0]{\makearrowr[#1]{\relbar}{\rightarrow\kern-1.8ex\rightarrow}}
\newcommand{\ots}[1][0]{\makearrowl[#1]{\leftarrow\kern-1.8ex\leftarrow}{\relbar}}
\begin{document}
\[a \to[0] b \to[1] c \to[2] d \to[3] e \to[4] f\]
\[a \ot[0] b \ot[1] c \ot[2] d \ot[3] e \ot[4] f\]
\[a \To[0] b \To[1] c \To[2] d \To[3] e \To[4] f\]
\[a \oT[0] b \oT[1] c \oT[2] d \oT[3] e \oT[4] f\]
\[a \tot[0] b \tot[1] c \tot[2] d \tot[3] e \tot[4] f\]
\[a \ToT[0] b \ToT[1] c \ToT[2] d \ToT[3] e \ToT[4] f\]
\[a \mto[0] b \mto[1] c \mto[2] d \mto[3] e \mto[4] f\]
\[a \otm[0] b \otm[1] c \otm[2] d \otm[3] e \otm[4] f\]
\[a \Mto[0] b \Mto[1] c \Mto[2] d \Mto[3] e \Mto[4] f\]
\[a \otM[0] b \otM[1] c \otM[2] d \otM[3] e \otM[4] f\]
\[a \pto[0] b \pto[1] c \pto[2] d \pto[3] e \pto[4] f\]
\[a \otp[0] b \otp[1] c \otp[2] d \otp[3] e \otp[4] f\]
\[a \ito[0] b \ito[1] c \ito[2] d \ito[3] e \ito[4] f\]
\[a \oti[0] b \oti[1] c \oti[2] d \oti[3] e \oti[4] f\]
\[a \sto[0] b \sto[1] c \sto[2] d \sto[3] e \sto[4] f\]
\[a \ots[0] b \ots[1] c \ots[2] d \ots[3] e \ots[4] f\]
\[x \to[((1 + 2) * 3 - 4) / 5 + 6] y\]
\[x \to[7] y\]
\end{document}
基本的には expl3 パッケージを利用して \Repeat
マクロを定義して繰り返しをおこなっているだけです。\Repeat
の引数に数式をそのまま入れられるのがちょっとしたポイントです。
なお、長さの調整は棒(\relbar
か \Relbar
)を継ぎ接ぎする方法を取っています。なお、\joinrel
は二項関係の記号どうしの間のスペースを良い感じに詰めてくれるマクロです。
実装の詳細についてですが、\Mto
/ \otM
の実装は見た目を美しくするために若干複雑になっています(\mid
をそのまま使っても良かったのですが、ちょっと大きすぎるなと思ったので……)。また、\sto
/ \ots
の実装には素直に \twoheadrightarrow
/ \twoheadleftarrow
を使えば良いと思うかもしれませんが、これらの矢印はなぜか線が細く \relbar
とうまく結合しないので、矢印を重ね打ちしました。
expl3 についての文献はまだあまり充実していませんが、LaTeX におけるプログラミングを圧倒的に楽にしてくれると思いました。