mathtools

amsmath는 1990년대 이후로 거의 달라지지 않았습니다. 안정성은 미덕이지만, 그 대가로 「고치고 싶어도 고칠 수 없는 자잘한 불만」이 쌓였습니다. :=의 생김새, 내용물 높이를 따라가지 않는 절댓값 세로줄, 합 기호 아래에 긴 조건을 쓰면 식 전체가 옆으로 벌어지는 문제 같은 것들입니다. mathtools는 그 수선들을 놓아 둘 자리로 2002년에 만들어진 LaTeX 패키지이며, amsmath를 대체하지 않고 amsmath를 불러온 위에 얹습니다. 이 페이지에서는 \DeclarePairedDelimiter, \coloneqq, \mathclap, \prescript, matrix*, dcases, showonlyrefs를 실제로 측정한 치수와 함께 살펴봅니다. 모두 amsmath 혼자서는 내딛지 못한 한 걸음입니다.

amsmath와 mathtools 중 무엇을 \usepackage 할까

mathtools만 쓰면 충분합니다. mathtools가 내부에서 amsmath를 불러오므로 \usepackage{amsmath}를 따로 적을 필요가 없습니다. 게다가 amsmath로 갈 옵션은 그대로 통과합니다. \usepackage[fleqn,tbtags]{mathtools}\usepackage[fleqn,tbtags]{amsmath} 다음에 \usepackage{mathtools}를 쓴 것과 같습니다. 둘 다 적고 순서를 신경 쓰는 수고는 필요 없습니다.

latex
% one line is enough: mathtools loads amsmath itself
\usepackage{mathtools}

% options aimed at amsmath are passed straight through
\usepackage[fleqn,tbtags]{mathtools}

「amsmath 위에 쌓는다」는 이 설계는 관리자가 세 번 바뀌는 동안에도 그대로였습니다. mathtools.sty의 저작권 표시는 2002~2011년 Morten Høgholm, 2012~2019년 Lars Madsen, 2020년부터는 Lars Madsen과 LaTeX3 프로젝트로 되어 있습니다. 즉 mathtools는 한 사람의 편의 도구에서 LaTeX 본체 개발팀이 돌보는 준표준으로 올라섰습니다. 그 흔적은 분명합니다. 수식이 들어가는 문서의 프리앰블에서 첫 줄에 적히는 것은 이제 amsmath보다 mathtools인 경우가 많습니다. mathtools는 보조 패키지 mhsetup에도 의존하지만 TeX Live 같은 배포판에 함께 들어 있어 신경 쓸 일이 없습니다.

절댓값과 노름의 크기를 자동으로 맞추기 — \DeclarePairedDelimiter

프리앰블에 \DeclarePairedDelimiter\abs{\lvert}{\rvert} 한 줄을 적으면 크기를 세 단계로 바꿀 수 있는 나만의 \abs가 생깁니다. 누구나 먼저 떠올리는 \newcommand{\abs}[1]{\lvert#1\rvert}는 가로 간격만큼은 제대로 잡아 주지만, \abs{\frac{a}{b}}처럼 키가 큰 내용을 넣으면 세로줄이 늘어나지 않아 자기를 넘어서는 분수 옆에 덩그러니 남습니다. \DeclarePairedDelimiter가 맡는 지점이 바로 여기입니다. 명령 이름을 중괄호로 감싼 \DeclarePairedDelimiter{\abs}{\lvert}{\rvert}도 똑같이 컴파일됩니다.

latex
% in the preamble; braces around the command name are optional
\DeclarePairedDelimiter\abs{\lvert}{\rvert}
\DeclarePairedDelimiter\norm{\lVert}{\rVert}

% three ways to call it
\[
  \abs{x} = \abs{-x}
  \qquad
  \abs*{\frac{a}{b}} = \frac{\abs{a}}{\abs{b}}
  \qquad
  \norm[\big]{v}
\]

차이는 인상이 아니라 치수로 확인됩니다. TeX Live 2024에서 \sbox0{$\abs{\frac ab}$}의 높이를 재면 7.5pt, 별표를 붙인 \abs*{\frac ab}8.50006pt가 나왔습니다. 별표는 내용을 \left … \right로 감싸므로 분수 높이만큼 세로줄이 늘어난 것입니다. [\big], [\Big], [\bigg], [\Bigg]를 넘기는 세 번째 형태는 단계를 손으로 고르는 방식인데, 이 예에서 [\big] 역시 8.50006pt로 자동이 고른 단계와 같은 곳에 떨어졌습니다. 별표는 늘리기, 대괄호는 이 단계로 고정 이라고 기억하면 헷갈리지 않습니다. \Set{x}{x>0}처럼 구분자 안쪽에 또 구분이 필요한 표기에는 \DeclarePairedDelimiterX를 씁니다.

형태크기쓰는 곳
\abs{x}고정(측정값 7.5pt)내용이 낮은 변수나 숫자일 때
\abs*{x}자동(측정값 8.50006pt)분수, 근호, 합처럼 키가 큰 내용
\abs[\big]{x}단계를 손으로 지정나란한 식들의 높이를 맞추고 싶을 때
\DeclarePairedDelimiterX위와 같되 인수를 여러 개\Set{x}{x>0} 처럼 내부 구분이 있는 표기

:=가 이상해 보이는 이유와 \coloneqq가 실제로 바꾸는 것

고칠 곳은 둘, 콜론의 높이콜론과 등호 사이의 간격 입니다. 흔히 「:는 관계 기호가 아니라서 간격이 어긋난다」고 설명하지만, 이는 사실이 아닙니다. LaTeX에서 :의 math code를 출력해 보면 12346, 16진수로 "303A 이고 앞자리 3이 class 3, 곧 관계 기호 를 뜻합니다. 그래서 $a\mathrel{:=}b$로 감싸도 아무것도 달라지지 않습니다. 실측도 같습니다. $a:=b$$a\mathrel{:=}b$는 둘 다 정확히 25.68855pt 였습니다.

그렇다면 \coloneqq는 무엇을 할까요. 정의를 열어 보면 \vcentcolon\mathrel{\mkern-1.2mu}= 입니다. 첫째, 보통의 : 대신 수식 축 높이에 가운데를 맞춘 콜론 \vcentcolon을 씁니다(실측: $:$의 높이 4.30554pt에 비해 $\vcentcolon$은 4.65277pt로 0.34723pt 올라가 있습니다). 둘째, -1.2mu의 음수 간격으로 콜론을 등호 쪽으로 당깁니다. 관계 기호가 둘 나란히 놓이면 TeX이 그 사이에도 관계 기호 간격을 넣어 :=가 별개의 기호처럼 보이기 때문입니다. 그 결과 $a\coloneqq b$25.02191pt, 날것의 :=보다 0.66664pt 좁고, 이는 10pt 크기에서의 1.2mu와 정확히 일치합니다.

latex
\[
  f(x) \coloneqq x^2 + 1, \qquad y \eqqcolon g(x), \qquad
  A \Coloneqq B
\]

함정이 하나 있습니다. mathtools는 \coloneq의 의미 자체를 바꿨습니다. 지금 기본값에서 \coloneq\coloneqq와 같은 「:=」를 내지만, 예전 정의에서는 콜론과 가로줄 「:−」 였습니다. \eqcolon도 마찬가지로 지금은 \eqqcolon과 같은 「=:」입니다. 옛 글자꼴이 필요한 문서를 위해 \usepackage[legacycolonsymbols]{mathtools}가 마련되어 있습니다. 거꾸로 \coloneqq\eqqcolon은 폐기된 적이 없고 어느 설정에서도 같은 것을 냅니다. 헷갈리면 q가 둘인 쪽을 쓰면 안전합니다. 같은 계열로 \dblcolon(::), \Coloneqq(::=), \Eqqcolon, \colonapprox, \colonsim, 그리고 새로 들어온 \approxcolon, \simcolon이 있습니다.

합 기호 아래 긴 조건이 식을 옆으로 벌린다 — \mathclap\smashoperator

조건을 폭이 0인 상자 에 넣으면 해결됩니다. \sum_{1 \le i \le j \le n} a_{ij}를 재면 전체 48.21771pt 인데, 조건을 \mathclap{…}으로 감싼 \sum_{\mathclap{1 \le i \le j \le n}} a_{ij}28.43983pt19.78pt 나 줄어듭니다. 조건의 글자는 사라지지 않고 합 기호 아래에 그대로 보입니다. 다만 그 폭이 식 전체의 폭에 더 이상 계산되지 않을 뿐입니다. \mathclap은 양옆으로, \mathllap은 왼쪽으로, \mathrlap은 오른쪽으로 넘치게 합니다. 본문에서 쓰는 \clap도 같은 발상입니다.

latex
% the wide condition stretches the whole formula
\[ \sum_{1 \le i \le j \le n} a_{ij} \]

% zero-width box: same look, width of the operator only
\[ \sum_{\mathclap{1 \le i \le j \le n}} a_{ij} \]

% same result, but this one can flatten a single side
\[ \smashoperator{\sum_{1 \le i \le j \le n}} a_{ij} \]
\[ \smashoperator[r]{\sum_{1 \le i \le j \le n}} a_{ij} \]

mathtools에는 \smashoperator라는 도구가 하나 더 있습니다. \smashoperator{\sum_{1 \le i \le j \le n}}의 측정값은 28.43983pt\mathclap의 결과와 똑같았습니다. 차이는 융통성입니다. \smashoperator는 연산자와 첨자를 함께 받아 [l], [r], [lr](기본값)로 어느 쪽을 눌러 없앨지 고를 수 있습니다. 합 기호가 줄머리에 붙어 있어 왼쪽으로 넘치면 곤란할 때 [r]이 답입니다. 실측 38.32878pt 로 양쪽 누르기와 원래 값의 중간이었습니다. \mathclap은 식 안의 한 점을 겨냥하는 도구, \smashoperator는 줄머리의 연산자를 통째로 돌보는 도구로 나누어 씁니다.

기호 왼쪽에 첨자 놓기 — \prescript\adjustlimits

\prescript{위}{아래}{본체} 세 인수로 기호의 왼쪽 위와 왼쪽 아래 에 첨자가 붙습니다. 동위원소 표기가 가장 알기 쉬운 예로, \prescript{238}{92}{\mathbf{U}}는 질량수 238을 왼쪽 위에, 원자번호 92를 왼쪽 아래에 두어 우라늄 238을 조판합니다. 손으로 {}^{238}_{92}\mathbf{U}라고 쓸 수도 있지만, 그것은 빈 그룹에 첨자를 매다는 방식이라 위치와 크기가 안정적이지 않습니다. 왼쪽 아래가 필요 없으면 두 번째 인수를 빈 {}로 둡니다. 첨자의 서체는 \mathtoolssetprescript-sub-format, prescript-sup-format으로 바꿀 수 있습니다.

latex
\[
  \prescript{238}{92}{\mathbf{U}}, \qquad
  \prescript{n}{}{C}_{k}
\]

% limits of two nested operators lined up
\[ \adjustlimits \sum_{i} \sum_{j} a_{ij} \]

이 절에 도구를 하나 더 놓습니다. 수수하지만 제 몫을 합니다. \adjustlimits중첩된 두 연산자의 아래 극한을 나란히 맞춥니다. \sum_i \sum_j처럼 크기가 다른 첨자가 이어지면 두 번째 극한이 살짝 떠 보일 수 있는데, \adjustlimits가 그 단차를 흡수합니다. 실측으로 \sum_i\sum_j가 30.55557pt, \adjustlimits\sum_i\sum_j가 32.2222pt로 차이는 1.66663pt, 정확히 3mu만큼의 조정입니다. \lim_{n\to\infty}\sup_{x}처럼 폭이 다른 연산자가 이어지는 자리에서도 효과가 있습니다.

행렬의 열 정렬하기 — pmatrix*[r] [l] [c]

amsmath의 pmatrix는 열을 언제나 가운데 정렬합니다. 음수가 섞이는 순간 이것이 골칫거리가 됩니다. -12가 위아래로 놓이면 숫자가 마이너스 기호 폭만큼 어긋나 보입니다. mathtools는 각 환경의 별표판——matrix*, pmatrix*, bmatrix*, Bmatrix*, vmatrix*, Vmatrix*, smallmatrix*——을 마련하고, array와 같은 열 지정을 선택 인수 로 받습니다. \begin{pmatrix*}[r]라고 쓰면 오른쪽 정렬이 되어 마이너스 기호가 왼쪽으로 깔끔하게 튀어나옵니다. 기본값이 c이므로 별표만 붙여서는 겉모습이 달라지지 않습니다. 작은 행렬의 기본 정렬은 \mathtoolssetsmallmatrix-align으로 정합니다.

latex
\[
  \begin{pmatrix*}[r]
    -1 &  3 \\
     2 & -4
  \end{pmatrix*}
  \qquad
  \begin{pmatrix}
    -1 &  3 \\
     2 & -4
  \end{pmatrix}
\]

경우 나누기와 너무 긴 한 줄 — dcases, rcases, multlined

amsmath의 cases는 내용을 본문 스타일(text style) 로 조판하므로 분수를 넣으면 \frac{1}{2}가 작게 눌립니다. mathtools의 dcases 는 쓰는 법은 그대로 두고 본문을 별행 크기로 조판합니다. d는 displaystyle의 d입니다. 중괄호를 오른쪽 에 두고 싶을 때, 즉 여러 조건에서 하나의 결론을 이끌어 내는 형태라면 rcases 를 쓰고 \end{rcases} 바로 뒤에 \Rightarrow 등을 이어 붙입니다. 둘을 합친 drcases, 마지막 열을 문장으로 조판하는 dcases*rcases*도 있습니다. 나만의 경우 나누기 환경이 필요하면 \newcases로 만들 수 있습니다.

latex
\[
  f(x) =
  \begin{dcases}
    \frac{1}{2} & x > 0 \\
    0           & x \le 0
  \end{dcases}
  \qquad
  \begin{rcases}
    a \\ b
  \end{rcases} \Rightarrow c
\]

% [t] aligns on the first row; the second optional argument fixes the width
\[
  \begin{multlined}[t][0.6\textwidth]
    a + b + c + d \\ {} + e + f
  \end{multlined}
\]

multlined 는 amsmath의 multline 환경을 상자 하나에 가둔 판 입니다. multline은 별행 전체를 차지하므로 align 안이나 = 오른쪽에서는 쓸 수 없습니다. multlined는 환경이라 식의 어디에나 끼워 넣을 수 있고, 긴 우변만 내부에서 접을 수 있습니다. 선택 인수는 둘로, 첫째는 바깥과의 세로 정렬 위치(t/b, 기본은 가운데), 둘째는 폭입니다. 폭을 밝히지 않으면 필요한 만큼만 차지합니다. 정렬된 두 줄 사이에 화살표를 끼우고 싶으면 \ArrowBetweenLines를, 정렬 전체의 행간을 넉넉하게 하고 싶으면 spreadlines 환경을 씁니다.

참조한 식에만 번호 붙이기 — showonlyrefs

\mathtoolsset{showonlyrefs}라고 쓰면 본문에서 참조한 식에만 번호가 붙고 나머지 번호는 사라집니다. 초고에서는 식 번호가 늘었다 줄었다 하기 마련이고, 아무도 참조하지 않는 식에 번호가 붙어 있으면 심사자는 「(7)은 어디에 쓰이나」를 찾아 나서게 됩니다. TeX Live 2024에서 식이 둘 있는 align을 조판하고 한쪽만 \eqref로 참조했더니, 참조한 식은 (1)이 되고 참조하지 않은 식은 번호가 아예 없었습니다. 조건은 하나, 참조에 \ref가 아니라 \eqref를 쓰는 것입니다. \tag{}로 직접 붙인 번호까지 사라지면 곤란할 때는 showmanualtags를 더합니다.

latex
\mathtoolsset{
  showonlyrefs,        % number only what \eqref points at
  showmanualtags,      % but keep \tag{} numbers visible
  centercolon          % a bare : is set at axis height
}

그 명령은 amsmath의 것인가 mathtools의 것인가

mathtools만 불러 쓰면 경계가 보이지 않지만, 남의 문서를 손볼 때나 amsmath만 허용하는 투고 규정을 만났을 때 이 경계가 중요해집니다. 구분은 .sty를 열면 드러납니다. 늘어나는 화살표 \xrightarrow, \xleftarrowamsmath(정의는 amsmath.sty)이고, mathtools가 더하는 것은 나머지 계열——겹선 \xRightarrow, \xLeftarrow, \xLeftrightarrow, 양방향 \xleftrightarrow, 갈고리 달린 \xhookrightarrow, \xhookleftarrow, 사상 \xmapsto, 더 긴 \xlongrightarrow, 그리고 harpoon——입니다. 모두 [아래]{위}라는 같은 형식으로 씁니다. \intertext는 amsmath, 좁힌 \shortintertext는 mathtools입니다. \overset, \underset, \substack은 amsmath이고, 각진 \overbracket, \underbracket은 mathtools입니다.

명령・환경출처역할
\xrightarrowamsmath라벨 너비만큼 늘어나는 화살표. [아래]{위}
\xleftrightarrowmathtools늘어나는 화살표 계열을 크게 늘림. \xRightarrow, \xmapsto
\overbracketmathtools\overbrace\underbrace의 각진 판. 첫 선택 인수는 선 두께, 둘째는 높이(기본 0.7ex)
\intertextamsmath정렬을 유지한 채 줄 사이에 문장을 끼움
\shortintertextmathtools같은 일을 위아래 여백을 좁혀서 함
\substackamsmath첨자를 여러 줄로 쌓음. 가로로 좁히는 \mathclap과 짝
\MoveEqLeftmathtoolsalign의 첫 줄을 왼쪽으로 내보내 이후 줄과 맞춤
\splitfracmathtools분자나 분모가 너무 길 때 그 자리만 두 줄로 접음