Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

AMSMath, lineno, and starred environments

248 views
Skip to first unread message

Ted Pavlic

unread,
Aug 7, 2007, 5:23:07 PM8/7/07
to
The incompatibility between lineno and amsmath is discussed in this
thread:

http://groups.google.com/group/comp.text.tex/browse_frm/thread/e8110ccea60224aa/b543fbd4ba29bbfd

Every math environment needs to be wrapped in a "linenomath"
environment to fix the problem. This is a little tedious, so the
environments can be redefined to automatically do this. That message
suggests doing something like:

\AtBeginDocument{%
\let\oldequation\equation%
\let\endoldequation\endequation%
\renewenvironment{equation}
{\linenomath\oldequation}{\endoldequation\endlinenomath}}

This is easy to implement for other environments, like align. But what
about the starred environments? Is there a CLEAN and ROBUST way to do
something LIKE:

\let\oldalignstar\align*
\let\endoldalignstar\endalign*
\renewenvironment{align*}
{\linenomath\oldalignstar}{\endoldalignstar\endlinenomath}

? I know this won't work.

Basically, what happens when a starred environment is created? How do
I get to the macros that are built?

--Ted

Ulrich Diez

unread,
Aug 7, 2007, 5:37:21 PM8/7/07
to
Ted Pavlic wrote:

[...]


> This is easy to implement for other environments, like align. But what
> about the starred environments? Is there a CLEAN and ROBUST way to do
> something LIKE:
>
> \let\oldalignstar\align*
> \let\endoldalignstar\endalign*
> \renewenvironment{align*}
> {\linenomath\oldalignstar}{\endoldalignstar\endlinenomath}

If you start the environment "foo" via \begin{foo}, the \begin-macro
will beneath other stuff open up a new grouping level and call
the macro \foo in terms of \csname..\endcsname.

That is:
By expanding \csname foo\endcsname, the token \foo is formed.
After that, the token \foo gets expanded...

For starred environments the star usually also goes into the
\csname...\endcsname-construct and is part of the name of the
token/macro which is formed by the expansion of the
\csname..\endcsname-construct.

Thus you can try:

\expandafter\let\expandafter\oldalignstar\csname align*\endcsname
\expandafter\let\expandafter\endoldalignstar\csname endalign*\endcsname


\renewenvironment{align*}
{\linenomath\oldalignstar}{\endoldalignstar\endlinenomath}


Ulrich

Ted Pavlic

unread,
Aug 7, 2007, 5:49:07 PM8/7/07
to
> \expandafter\let\expandafter\oldalignstar\csname align*\endcsname
> \expandafter\let\expandafter\endoldalignstar\csname endalign*\endcsname
> \renewenvironment{align*}
> {\linenomath\oldalignstar}{\endoldalignstar\endlinenomath}

I also thought of this a few minutes after I posted (after reviewing
"source2e.pdf" to find exactly what you've said above). It seems to
work!

Thanks, much --
Ted

P.S.

It's too bad things like this are not documented with lineno/amsmath.
With as much as both are used simultaneously (for example, in Elsevier
journal preprints), you would think this would be easier to find.

Ted Pavlic

unread,
Aug 7, 2007, 7:02:48 PM8/7/07
to
> It's too bad things like this are not documented with lineno/amsmath.
> With as much as both are used simultaneously (for example, in Elsevier
> journal preprints), you would think this would be easier to find.

I've gone through and created fixes for the equation and equation*
environments as well as all of the AMSMath environments. I've
documented them here:

http://phaseportrait.blogspot.com/2007/08/lineno-and-amsmath-compatibility.html

I suppose I could just copy and paste them here as well:

%=====
% To deal with amsmath, must redefine math environments later
\AtBeginDocument{%


%
\let\oldequation\equation%
\let\endoldequation\endequation%

\renewenvironment{equation}%
{\linenomath\oldequation}{\endoldequation\endlinenomath}%
%
\expandafter\let\expandafter\oldequationstar\csname equation*\endcsname
%
\expandafter\let\expandafter\endoldequationstar\csname endequation*
\endcsname%
\renewenvironment{equation*}%
{\linenomath\oldequationstar}{\endoldequationstar\endlinenomath}%
%
\let\oldalign\align%
\let\endoldalign\endalign%
\renewenvironment{align}%
{\linenomath\oldalign}{\endoldalign\endlinenomath}%
%
\expandafter\let\expandafter\oldalignstar\csname align*\endcsname%


\expandafter\let\expandafter\endoldalignstar\csname endalign*\endcsname

%
\renewenvironment{align*}%
{\linenomath\oldalignstar}{\endoldalignstar\endlinenomath}%
%
\let\oldflalign\flalign%
\let\endoldflalign\endflalign%
\renewenvironment{flalign}%
{\linenomath\oldflalign}{\endoldflalign\endlinenomath}%
%
\expandafter\let\expandafter\oldflalignstar\csname flalign*\endcsname%
\expandafter\let\expandafter\endoldflalignstar\csname endflalign*
\endcsname%
\renewenvironment{flalign*}%
{\linenomath\oldflalignstar}{\endoldflalignstar\endlinenomath}%
%
\let\oldalignat\alignat%
\let\endoldalignat\endalignat%
\renewenvironment{alignat}%
{\linenomath\oldalignat}{\endoldalignat\endlinenomath}%
%
\expandafter\let\expandafter\oldalignatstar\csname alignat*\endcsname%
\expandafter\let\expandafter\endoldalignatstar\csname endalignat*
\endcsname%
\renewenvironment{alignat*}%
{\linenomath\oldalignatstar}{\endoldalignatstar\endlinenomath}%
%
\let\oldgather\gather%
\let\endoldgather\endgather%
\renewenvironment{gather}%
{\linenomath\oldgather}{\endoldgather\endlinenomath}%
%
\expandafter\let\expandafter\oldgatherstar\csname gather*\endcsname%
\expandafter\let\expandafter\endoldgatherstar\csname endgather*
\endcsname%
\renewenvironment{gather*}%
{\linenomath\oldgatherstar}{\endoldgatherstar\endlinenomath}%
%
\let\oldmultline\multline%
\let\endoldmultline\endmultline%
\renewenvironment{multline}%
{\linenomath\oldmultline}{\endoldmultline\endlinenomath}%
%
\expandafter\let\expandafter\oldmultlinestar\csname multline*\endcsname
%
\expandafter\let\expandafter\endoldmultlinestar\csname endmultline*
\endcsname%
\renewenvironment{multline*}%
{\linenomath\oldmultlinestar}{\endoldmultlinestar\endlinenomath}%
%
}
%=====

Of course, the template for each of these is just:

%=====
\let\oldBLAH\BLAH%
\let\endoldBLAH\endBLAH%
\renewenvironment{BLAH}%
{\linenomath\oldBLAH}{\endoldBLAH\endlinenomath}%
\expandafter\let\expandafter\oldBLAHstar\csname BLAH*\endcsname%
\expandafter\let\expandafter\endoldBLAHstar\csname endBLAH*\endcsname%
\renewenvironment{BLAH*}%
{\linenomath\oldBLAHstar}{\endoldBLAHstar\endlinenomath}%
%=====

Hence, this could be made a little smaller by building a macro that is
passed BLAH and uses that template. I didn't want to deal with
building and debugging that, so I just copied and pasted and made sure
the results worked. As far as I can tell, the above long list works.

--Ted

Ulrich Diez

unread,
Aug 7, 2007, 10:13:14 PM8/7/07
to
Ted Pavlic wrote:


> Of course, the template for each of these is just:
>
> %=====
> \let\oldBLAH\BLAH%
> \let\endoldBLAH\endBLAH%
> \renewenvironment{BLAH}%
> {\linenomath\oldBLAH}{\endoldBLAH\endlinenomath}%
> \expandafter\let\expandafter\oldBLAHstar\csname BLAH*\endcsname%
> \expandafter\let\expandafter\endoldBLAHstar\csname endBLAH*\endcsname%
> \renewenvironment{BLAH*}%
> {\linenomath\oldBLAHstar}{\endoldBLAHstar\endlinenomath}%
> %=====

\makeatletter
\newcommand*\patchenvironment[1]{%
\expandafter\@patchenvironment
\csname #1\expandafter\endcsname
\csname old#1\expandafter\endcsname
\csname end#1\expandafter\endcsname
\csname oldend#1\endcsname
{#1}%
}%
\newcommand*\@patchenvironment[5]{%
\let#2=#1%
\let#4=#3%
\renewenvironment{#5}%
{\linenomath#2}{#4\endlinenomath}%
}%
\makeatother

OR

\newcommand*\patchenvironment[1]{%
\expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname
\expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname
\renewenvironment{#1}%
{\linenomath\csname old#1\endcsname}%
{\csname oldend#1\endcsname\endlinenomath}%
}%


OR

\makeatletter
\newcommand*\patchenvironment[1]{%
\expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname
\expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname
\expandafter\@patchenvironment
\expandafter{%
\expandafter\linenomath
\csname old#1\expandafter\endcsname
\expandafter}%
\expandafter{%
\csname oldend#1\endcsname\endlinenomath}%
{\renewenvironment{#1}}%
}%
\newcommand*\@patchenvironment[3]{%
#3{#1}{#2}%
}%
\makeatother

OR whatever.

Ulrich

Ted Pavlic

unread,
Aug 8, 2007, 3:55:54 PM8/8/07
to
> \newcommand*\patchenvironment[1]{%
> \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname
> \expandafter\let\csname oldend#1\expandafter\endcsname\csname end#1\endcsname
> \renewenvironment{#1}%
> {\linenomath\csname old#1\endcsname}%
> {\csname oldend#1\endcsname\endlinenomath}%
>
> }%

Excellent! Thanks! I used this:

%=====
\newcommand*\patchAmsMathEnvironmentForLineno[1]{%


\expandafter\let\csname old#1\expandafter\endcsname\csname
#1\endcsname
\expandafter\let\csname oldend#1\expandafter\endcsname\csname
end#1\endcsname
\renewenvironment{#1}%
{\linenomath\csname old#1\endcsname}%
{\csname oldend#1\endcsname\endlinenomath}}%

\newcommand*\patchBothAmsMathEnvironmentsForLineno[1]{%
\patchAmsMathEnvironmentForLineno{#1}%
\patchAmsMathEnvironmentForLineno{#1*}}%
\patchBothAmsMathEnvironmentsForLineno{equation}%
\patchBothAmsMathEnvironmentsForLineno{align}%
\patchBothAmsMathEnvironmentsForLineno{flalign}%
\patchBothAmsMathEnvironmentsForLineno{alignat}%
\patchBothAmsMathEnvironmentsForLineno{gather}%
\patchBothAmsMathEnvironmentsForLineno{multline}%
%=====

I loaded all of that into an "AtBeginDocument". That works well, and
is much more compact.

Thanks, again --
Ted

0 new messages