Условные макросы

Условные макросы

Цель:Я хотел бы иметь макрос, который заменяет различные команды в зависимости от того, находится ли он в режиме отображения математики или нет. В частности, он должен генерировать угловые скобки фиксированного размера в текстовых строках, \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< , что устанавливает \ifinnertrue, так как вся математика в паре слева-справа находится во внутреннем режиме. Таким образом, вы никогда не выполните сопоставление \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.

Связанный контент