TeXの記憶(104)— 数式の上下の空きをその都度調節する

AMS-LaTeXを使っているときに数式行の上下を調節するマクロです。

LaTeXで数式の上下の空きを調整するには一般的には、

abovedisplayskip
belowdisplayskip
abovedisplayshortskip
belowdisplayshortskip

の値で設定されます。書籍の組版などの場合、値を無難な値にしておけば全体的にはいいのですが、どうしても個別に調節する必要が出てきます。

調整する必要というのは、多くの場合個別の行間そのものを直したいというよりも全体として1ページ減らしたい(または増やしたい)という理由なので、周辺の数式を片っ端から調整しなければなりません。

以下のマクロはできるだけ安易に数式行の上下の空きを調整できるように作ってみたものです。

名前も安易で、上の空きが\XXa、下の空きが\XXbです。安易に作ったまま何年も使い続けてしまいました。

\XXa=4mm\[
数式
\]

のようにすると数式の上の空きが4mm増えることになります。垂直スペースの絶対値ではありません。

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
\[
S=\int Ld\tau = -mc^2\int d\tau
\]
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
\XXa=5mm\XXb=5mm\[
S=\int Ld\tau = -mc^2\int d\tau
\]
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
\XXa=-3mm\XXb=-2mm\[
S=\int Ld\tau = -mc^2\int d\tau
\]
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

1129

amsmath.styの中の数式行に関係する部分を上書きしているだけなので、amsmath.styのバージョンが大幅に変わったら何か問題があるかもしれません。

\usepackage{amsmath}
…
% オフセットのための量
\newdimen\XXa
\newdimen\XXb
\XXa=\z@
\XXb=\z@

% 元の値を保存
\newdimen\XX@abovedisplayskip
\newdimen\XX@belowdisplayskip
\newdimen\XX@abovedisplayshortskip
\newdimen\XX@belowdisplayshortskip
\XX@abovedisplayskip=\abovedisplayskip
\XX@belowdisplayskip=\belowdisplayskip
\XX@abovedisplayshortskip=\abovedisplayshortskip
\XX@belowdisplayshortskip=\belowdisplayshortskip

% アキの量を加える
\newcommand{\XXams@change@env}{%
  \advance\abovedisplayskip\XXa
  \abovedisplayshortskip=\abovedisplayskip
  \advance\belowdisplayskip\XXb
  \belowdisplayshortskip=\belowdisplayskip}

% 元の値に戻す (globalを使うとsmallなどにも影響を与えてしまうので使わない)
\newcommand{\XXams@restore@env}{%
  \abovedisplayskip=\XX@abovedisplayskip
  \abovedisplayshortskip=\XX@abovedisplayshortskip
  \belowdisplayskip=\XX@belowdisplayskip
  \belowdisplayshortskip=\XX@belowdisplayshortskip
%  \if@fleqn\global\XXindent=\orig@mathmargin\fi
  \global\XXa=\z@
  \global\XXb=\z@}

% \[ \], equation(*)で使われる
\def\mathdisplay#1{%
  \ifmmode \@badmath
  \else
    \XXams@change@env           % 追加
    $$\def\@currenvir{#1}%
    \let\dspbrk@context\z@
    \let\tag\tag@in@display \let\label\label@in@display \SK@equationtrue
    \global\let\df@label\@empty \global\let\df@tag\@empty
    \global\tag@false
    \let\mathdisplay@push\mathdisplay@@push
    \let\mathdisplay@pop\mathdisplay@@pop
    \if@fleqn
      \edef\restore@hfuzz{\hfuzz\the\hfuzz\relax}%
      \hfuzz\maxdimen
      \setbox\z@\hbox to\displaywidth\bgroup
        \let\split@warning\relax \restore@hfuzz
        \everymath\@emptytoks \m@th $\displaystyle %%%$
    \fi
  \fi
}
\def\endmathdisplay#1{%
  \ifmmode \else \@badmath \fi
  \endmathdisplay@a
  $$%
  \global\let\df@label\@empty \global\let\df@tag\@empty
  \global\tag@false \global\let\alt@tag\@empty
  \global\@eqnswfalse
  \XXams@restore@env            % 追加
}

% align(*), alignat(*), xalignat(*), xxalignat, flalign(*)で使われる
\def\start@align#1#2#3{%
    \let\xatlevel@#1% always \z@, \@ne, or \tw@
    \maxfields@#3\relax
    \ifnum\maxfields@>\m@ne
        \checkat@true
        \ifnum\xatlevel@=\tw@
            \xxat@true
        \fi
        \multiply\maxfields@\tw@
    \else
        \checkat@false
    \fi
    \ifingather@
        \iffalse{\fi\ifnum0=`}\fi
        \DN@{\vcenter\bgroup\savealignstate@\align@#2}%
    \else
        \ifmmode
          \if@display
             \DN@{\align@recover}%
          \else
            \nomath@env
            \DN@{\@namedef{end\@currenvir}{}\@gobble}%
          \fi
        \else
            \XXams@change@env   % 追加
            $$%
            \let\split\insplit@
            \DN@{\align@#2}%
        \fi
    \fi
    \collect@body\next@
}

% 後半は,\endalignとして使われる
\renewenvironment{align}{%
  \start@align\@ne\st@rredfalse\m@ne
}{%
  \math@cr \black@\totwidth@
  \egroup
  \ifingather@
    \restorealignstate@
    \egroup
    \nonumber
    \ifnum0=`{\fi\iffalse}\fi
  \else
    $$%
  \fi
  \XXams@restore@env            % 追加
  \ignorespacesafterend
}

% gather(*)で使われる
\def\start@gather#1{%
    \RIfM@
        \nomath@env
        \DN@{\@namedef{end\@currenvir}{}\@gobble}%
    \else
        \XXams@change@env       % 追加
        $$%
        #1%
        \ifst@rred \else \global\@eqnswtrue \fi
        \let\next@\gather@
    \fi
    \collect@body\next@
}

% 後半は\endgatherとして,gather*で使われる
\renewenvironment{gather}{%
  \start@gather\st@rredfalse
}{%
  \math@cr \black@\totwidth@ \egroup
  $$
  \XXams@restore@env            % 追加
  \ignorespacesafterend
}

% multline(*)で使われる
\def\start@multline#1{%
    \RIfM@
        \nomath@env
        \DN@{\@namedef{end\@currenvir}{}\@gobble}%
    \else
        \XXams@change@env       % 追加
        $$%
        #1%
        \ifst@rred
            \nonumber
        \else
            \global\@eqnswtrue
        \fi
        \let\next@\multline@
    \fi
    \collect@body\next@
}

% 後半は,\endmultlineとして,multline*で使われる
\renewenvironment{multline}{%
  \start@multline\st@rredfalse
}{%
  \iftagsleft@ \@xp\lendmultline@ \else \@xp\rendmultline@ \fi
  \XXams@restore@env            % 追加
  \ignorespacesafterend
}

コメント