Цель:Я хотел бы иметь макрос, который заменяет различные команды в зависимости от того, находится ли он в режиме отображения математики или нет. В частности, он должен генерировать угловые скобки фиксированного размера в текстовых строках, \langle ... \rangle
, но переменного размера в отображаемой математике, \left<...\right>
.
Мотивация:Макрос должен быть универсальным, поскольку математические выражения могут часто перемещаться между отображаемыми и неотображаемыми выражениями (я пишу учебник, редактирую его, перередактирую и т. д.). Это было бы источником опечаток, если бы мне приходилось менять код выражения каждый раз при перемещении его из отображаемой математики или в нее. Приведенный выше пример с угловыми скобками является стандартной записью для усреднения в физической литературе.
Первая попытканаходится в MWE ниже. Он работает для встроенной математики, но не может правильно подставить в режиме отображения. LaTeX реагирует с "Missing \right. inserted" или "Bad math environment delimiter" в зависимости от использования или $$
и \[
, \]
соответственно. Компиляция в пакетном режиме генерирует вывод с правильным размером левой скобки, но неправильным правой. Этот результат не зависит от использования \def или \newcommand. Проверено, что он такой же для квадратных скобок [...]
.
Система:Mac OS 12.7.2., LaTeX: <Это pdfTeX, версия 3.141592653-2.6-1.40.24 (TeX Live 2022) (предварительно загруженный формат=latex) ограниченный \write18 включен. вход в расширенный режим (./mwe.tex LaTeX2e <2021-11-15> исправление уровня 1 уровня программирования L3 <2022-02-24>>
Теперь MWE:
\documentclass{article}
\def \la{\ifinner \langle \else \left< \fi }
\def \ra{\ifinner \rangle \else \right> \fi }
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 dt \ra$,
but do not in the displayed math. Obviously, the
false text is not expanded properly, but why?
\[
\la \int \Omega_n^2 dt \ra
\]
\end{document}
решение1
Я не советую использовать этот подход. Обычно он не делает «то, что нужно».
В любом случае, поскольку клиент всегда прав, вы можете использовать amsmath
\if@display
условность.
\documentclass{article}
\usepackage{amsmath}
\makeatletter
\newcommand{\la}{\if@display\left\fi\langle}
\newcommand{\ra}{\if@display\right\fi\rangle}
\makeatother
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 \, dt \ra$,
and also in displayed math
\[
\la \int \Omega_n^2 \, dt \ra
\]
\begin{align}
I=\la \int \Omega_n^2 \, dt \ra
\end{align}
\begin{gather}
I=\la \int \Omega_n^2 \, dt \ra
\end{gather}
\end{document}
решение2
\ifinner
проверяет низкоуровневый аспект состояния TeX, но по сути никогда не делает ничего полезного в tex по отношению к каким-либо элементам уровня документа.
Здесь, в\la
нем тестыИстинныйв встроенной математике иЛОЖЬв \[
но будет тестироваться как true в amsmath
средах отображения, таких как gather
или align
когда они входят в displaystyle через
$\displaystyle display math$
not
$$ display math$$
Однако тест всегдаИстинныйв \ra
так как либо выражение уже было внутренним, либо если \ifinner
было ложным в начале, \la
то выполнится \left<
, что устанавливает \ifinner
true, так как вся математика в паре слева-справа находится во внутреннем режиме. Таким образом, вы никогда не выполните сопоставление \right
.
Также \left..\right
следует избегать случаев, когда растяжение не требуется, поскольку это влияет на горизонтальное расстояние.
Предусмотрен более надежный механизм, mathtools
который также корректирует горизонтальное расстояние слева направо.
\documentclass{article}
\def\test{\relax\ifinner T\else F\fi}
\usepackage{mathtools}
\DeclarePairedDelimiter\ang\langle\rangle
\begin{document}
a $\test \ang{\int \Omega_n^2 dt} \ang[\big]{\int \Omega_n^2 dt}$
\[
\test \ang{\int \Omega_n^2 dt} \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\]
\begin{equation}
\test \ang{\int \Omega_n^2 dt} \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\end{equation}
\begin{gather}
\test \ang{\int \Omega_n^2 dt} \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\end{gather}
\end{document}
решение3
TeX переключает режим набора текста на «внутренний» при обнаружении \left
разделителя в математическом режиме.
Так что, похоже, вопрос в том, чтобы расшириться \ifinner
в нужный момент.
Вы можете использовать \expanded
для \ifinner
оценки тестов перед дальнейшим набором текста и, таким образом, переключения режима набора текста:
\documentclass{article}
\newcommand*\la{\ifinner\else\expandafter\left\fi\langle}%
\newcommand*\ra{\ifinner\else\expandafter\right\fi\rangle}%
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 dt \ra$,
and also do work in the displayed math.
\[%
\expanded{\la \unexpanded{\int \Omega_n^2 dt} \ra}
\]%
\end{document}
В некоторых ситуациях то обстоятельство, что таким образом \la
и \ra
таким образом \langle
/ \left\langle
и \rangle
/ \right\rangle
полностью расширяются, может стать проблемой.
\unexpanded
Вы также можете обернуть их в макрос :
\documentclass{article}
\newcommand\inangle[1]{%
\expanded{%
\ifinner\else\unexpanded{\left}\fi\unexpanded{\langle}%
\unexpanded{#1}%
\ifinner\else\unexpanded{\right}\fi\unexpanded{\rangle}%
}%
}%
\begin{document}
The macros work in the text line: $\inangle{\int \Omega_n^2 dt}$,
and also do work in the displayed math.
\[\inangle{\int \Omega_n^2 dt}\]
\end{document}
Предостережение:
Как уже было отмеченоДэвид Карлайл в своем ответе, эти подходы в любом случае не работают в средах LaTeX, где текст на самом деле не набирается в режиме отображения, а набирается во встроенном режиме со стилем отображения, выбранным с помощью \displaystyle
.