\documentclass[a4paper]{report}
\usepackage{amsmath,mathtools}
\makeatletter
\newcount\mw@shortcnt
\mw@shortcnt=0
\newcommand{\short}[1]{%
\global\advance\mw@shortcnt by +1%
\expandafter\def\csname temp\the\mw@shortcnt\endcsname{#1}
}
\newcount\mw@unshortcnt
\mw@unshortcnt=0
\newcommand{\unshort}{%
\global\advance\mw@unshortcnt by +1%
\csname temp\the\mw@unshortcnt\endcsname
}
\newcommand{\undershort}[1]{\underset{\unshort}{#1}}
\newcommand{\overshort}[1]{\overset{\unshort}{#1}}
\newcommand{\abbr}[2]{\expandafter\gdef\csname#1\endcsname{#2}}
\newcommand{\setshortcnt}[1]{\mw@shortcnt=#1}
\newcommand{\setunshortcnt}[1]{\mw@unshortcnt=#1}
\newcommand{\showshort}{\the\mw@shortcnt}
\newcommand{\showunshort}{\the\mw@unshortcnt}
\newcommand{\showboth}{\showshort\showunshort}
\makeatother
\newcommand{\ang}[1]{\left\langle #1\right\rangle}
\begin{document}
\showboth \\
\short{\mathclap{\substack{\text{posso portarmi da un membro all'altro la proiezione e $p_1$ idempotente.} \\ |}}}
\short{\mathclap{\substack{| \\ \text{commutano per ipotesi e $p_2$ porto a destra nel primo}}}}
\showboth \\
\begin{align*}
\showboth \\
\setunshortcnt{0}
\ang{x-p_1(p_2(x)\!),p_1(p_2(y)\!)}={}\text{\textit{\showboth}}&\text{\textit{\showboth}}\ang{x,p_1(p_2(y)\!)}-\ang{p_1p_2(x),p_1p_2(y)}\undershort{=}{} \\
{}={}&\ang{p_1(x),p_2(y)}-\ang{p_1(p_2(x)\!),p_2(y)}\undershort{=}\ang{p_2(p_1(x)\!),y}-\ang{p_1(x),p_2(y)}=0.
\end{align*}
\end{document}
Команда \short
определена для случая, когда у меня есть \underset
или \overset
с \mathclap
, \substack
и \text
объединена в аргументе under или over, как в примере, чтобы сохранить сложности этого аргумента вне уравнения и сделать код уравнения более читаемым. Команда \unshort
(и ее сокращение в сочетании с \underset
and \overset
) является близнецом для \short
размещения аргумента на месте. Они полагаются каждый на счетчик, причем счетчики называются \mw@shortcnt
и \mw@unshortcnt
, определяя макросы со стандартным началом, за которым следует значение счетчика (ранее увеличенное глобально, чтобы избежать конфликта в последовательностях \short
s), чтобы расшириться до аргумента, который должен быть позже восстановлен, и восстанавливая аргумент, помещенный в \short
when , когда \mw@shortcnt
был при определенном значении ( \mw@unshortcnt
, ранее глобально увеличенном на 1). Пример компилируется в:
Оба счетчика начинаются с 0, как установлено. Затем shortcnt
становится 2 из-за двух \short
s. И это все в порядке. Затем я открываю align*
и unshortcnt
волшебным образом становится 2! Я вручную устанавливаю его обратно на 0, и следующие 20 показывают, что команда выполняется, но &
каким-то образом отменяет это! Что здесь происходит? Что эта align*
среда делает с моими счетчиками и почему? В конце концов, она имеет префикс mw@
, я имею в виду имя счетчика, так как можно amsmath
что-то знать о ней, чтобы вмешаться?
Обновлять:
Похоже, что unshortcnt
для решения проблемы достаточно установить права вручную в первый раз... почему первый раз &
срабатывает счетчик, а второй — нет?
Редактировать: Идея в следующем. Если я напишу код выше, например:
`\overset{\mathclap{\substack{\text{posso portarmi da un membro all'altro la proiezione e $p_1$ idempotente.} \\ |}{=}
Это почти нечитаемо. Поэтому я хотел сохранить этот грязный нечитаемый аргумент где-то за пределами уравнения, сделав его более читаемым. Я начал делать что-то вроде:
\def\temp{\mathclap{\substack{\text{posso portarmi da un membro all'altro la proiezione e $p_1$ idempotente.} \\ |}
Чтобы затем вызвать \temp
макрос внутри уравнения. Поскольку это было сокращение и несокращение аргументов, казалось логичным иметь макрос, который бы заботился об определении макроса и вызове, а также создавал имя. Здесь появились \short
и \unshort
. Поскольку наиболее частое использование this было в \underset
, я объединил \unshort
его с ним, получив \undershort
. Таким образом, единственной целью этих макросов было сделать код уравнения более читаемым.
решение1
Среды выравнивания amsmath
проходят по материалу дважды. В проходе измерения условие \ifmeasuring@
устанавливается в значение true, в противном случае — false.
Я внес некоторые поправки в код. Например, у вас есть два неправильных %
после +1
; также ваши настройки счетчиков были иногда локальными, иногда глобальными, что неправильно. Есть \@namedef
и \@nameuse
для избежания \expandafter\def\csname...\endcsname
и \csname...\endcsname
.
Наконец, я использовал \romannumeral
в \@namedef
, потому что лучше избегать управляющих последовательностей, заканчивающихся цифрами. СмотритеКак реализовать (низкоуровневые) массивы в TeXи в частности ответ Бруно Ле Флоха.
\documentclass[a4paper]{report}
\usepackage{amsmath,mathtools}
\makeatletter
\newcount\mw@shortcnt
\newcommand{\short}[1]{%
\ifmeasuring@\else
\global\advance\mw@shortcnt\@ne
\@namedef{mickgtemp\romannumeral\mw@shortcnt}{#1}
\fi
}
\newcount\mw@unshortcnt
\newcommand{\unshort}{%
\ifmeasuring@\else
\global\advance\mw@unshortcnt\@ne
\@nameuse{mickgtemp\romannumeral\mw@unshortcnt}%
\fi
}
\newcommand{\undershort}[1]{\underset{\unshort}{#1}}
\newcommand{\overshort}[1]{\overset{\unshort}{#1}}
\newcommand{\abbr}[2]{\global\@namedef{#1}{#2}}
\newcommand{\setshortcnt}[1]{\global\mw@shortcnt=#1\relax}
\newcommand{\setunshortcnt}[1]{\global\mw@unshortcnt=#1\relax}
\newcommand{\showshort}{\the\mw@shortcnt}
\newcommand{\showunshort}{\the\mw@unshortcnt}
\newcommand{\showboth}{\showshort\showunshort}
\makeatother
\newcommand{\ang}[1]{\left\langle #1\right\rangle}
\begin{document}
\showboth \\
\short{\mathclap{\substack{\text{posso portarmi da un membro all'altro la proiezione e $p_1$ idempotente.} \\ |}}}
\short{\mathclap{\substack{| \\ \text{commutano per ipotesi e $p_2$ porto a destra nel primo}}}}
\showboth \\
\begin{align*}
\showboth \\
\setunshortcnt{0}
\ang{x-p_1(p_2(x)\!),p_1(p_2(y)\!)}={}\text{\textit{\showboth}}&\text{\textit{\showboth}}\ang{x,p_1(p_2(y)\!)}-\ang{p_1p_2(x),p_1p_2(y)}\undershort{=}{} \\
{}={}&\ang{p_1(x),p_2(y)}-\ang{p_1(p_2(x)\!),p_2(y)}\undershort{=}\ang{p_2(p_1(x)\!),y}-\ang{p_1(x),p_2(y)}=0.
\end{align*}
\end{document}
Само собой разумеется, что типографика ужасная.