4

I have an important macro \textmacro that can only be invoked in text mode. I would like a macro \mathmacro such that issuing the command

Some text $a^b\mathmacro c^d$ more text

is automatically transformed and evaluates as follows:

Some text $a^b c^d$\textmacro more text

That is, the macro position is 'moved' to just after the end of math mode, at which point \textmacro is called. Is there any internal LaTeX technology that would allow this? I would need this to work in $...$, equation and align environments.

Edit: the \textmacro command puts a note in the margin using \marginpar. There is no comparable command that operates the same way in both text mode and math mode; in particular, \marginnote does not stack comments vertically.

Edit: just to make things a bit harder/more realistic: (1) the \textmacro commands will sometimes be inside \ensuremath commands, so e.g. $a^b \ensuremath{x \mathmacro y}$ should expand to $a^b \ensuremath{x y}$\textmacro. (2) In general there will be multiple invocations of \mathmacro inside the math environment, and they must all get pushed to the end. (3) When used in text mode, \mathmacro should just behave like \textmacro. (4) In general \mathmacro will take an argument.

2
  • 1
    The first option (within $..$) is easy: \newcommand{\textmacro}{abc} \def\mathmacro#1${#1$\textmacro} The others aren't. What is this "important macro" that can only be invoked in text mode? Using \mbox initiates text mode. Shouldn't that be sufficient?
    – Werner
    Dec 15, 2014 at 17:36
  • 1
    The \textmacro command puts a note in the margin using \marginpar. For more context see tex.stackexchange.com/questions/215322/…. Dec 15, 2014 at 17:50

1 Answer 1

4

I used Werner's comment for the $...$ form, but added forms that work for equation and align.

EDITED to handle the OP's requirements:

1) arguments to \mathmacro;

2) multiple calls to \mathmacro in a single environment;

3) works when embedded within \ensuremath argument.

REVISED SOLUTION (can handle multiple \mathmacro calls)

In this approach, to allow for multiple calls, I use \mathmacro to build a semicolon separated list (disallows the ; therefore in your \marginpars, but you can manually change the separator) of the \mathmacro arguments.

Then, upon completion of the environment, I call on a routine to parse that list, and issue a \textmacro call to \marginpar for each argument in the list. Along the way, I had to handle a quirk of align which makes a double pass, originally resulting in doubled calls to \mathmacro.

\documentclass[11pt]{article}
\usepackage{amsmath}
\newcommand\textmacro[1]{\marginpar{\textbf{\sffamily #1}}}
% FIX FOR $...$ PER WERNER'S USAGE
\def\mathmacro#1#2${#2$\textmacro{#1}}
\makeatletter
% FIX FOR EQUATION
\let\svequation\equation
\let\svendequation\endequation
\def\eqfinishmacro{\expandafter\eqfinishhelpA\eqfinishdata\relax;\relax}
\def\eqfinishhelpA#1;#2\relax{%
  \ifx\relax#1\else\textmacro{#1}\if\relax#2\relax\else\eqfinishhelpA#2\relax\fi\fi%
  \@gobble}
\def\eqfinishdata{}
\newcommand\equationmacro[1]{%
  \xdef\eqfinishdata{\eqfinishdata#1;}}
\def\equation{\let\mathmacro\equationmacro\svequation}
\def\endequation{\svendequation\eqfinishmacro\gdef\eqfinishdata{}}
% FIX FOR ALIGN
\let\svalign\align
\let\svendalign\endalign
\def\alfinishmacro{\expandafter\alfinishhelpA\alfinishdata\relax;\relax}
\def\alfinishhelpA#1;#2\relax{%
  \ifx\relax#1\else\textmacro{#1}\if\relax#2\relax\else\alfinishhelpA#2\relax\fi\fi%
  \@gobble}
\def\alfinishdata{}
\newcommand\alignmacro[1]{%
  \xdef\alfinishdata{\alfinishdata#1;}}
\def\align{\let\mathmacro\alignmacro\svalign\def\alfinishdata{}}
\def\endalign{\svendalign\alfinishmacro\gdef\alfinishdata{}}
\makeatother
\begin{document}
Some text $a^b\mathmacro{MP} c^d$ more text\par
Some more text without a macro $a^b c^d$ more text\par
An equation using mathmacro
\begin{equation}
  a^b\mathmacro{EQ XYZ} c^d
\end{equation}%
to see if it works.\par
An equation using mathmacro
\begin{equation}
  a^b\mathmacro{EQ ARG.} c^d\mathmacro{2nd eq test}
\end{equation}%
to see if it works.\par
Here we have an equation without the mathmacro
\begin{equation}
  a^b =c^d
\end{equation}
but some following text.\par
Align with the mathmacro
\begin{align}
  a^b \mathmacro{AL ARG.} &= c^d &x &= y\mathmacro{2nd test}\\
  A^B \mathmacro{3rd test} &= C^D & X &= y
\end{align}%
to also see if it works.\par
Here we us align without the mathmacro
\begin{align}
  a^b &= c^d
\end{align}
but some following text.\par
Some text $a^b\mathmacro{ABC} c^d$ more text to see if original definition active.
\end{document}

enter image description here

ORIGINAL SOLUTION (allows only one \mathmacro call per environment)

\documentclass[11pt]{article}
\usepackage{amsmath}
\newcommand{\textmacro}[1][ABC]{\marginpar{\textbf{\sffamily #1}}}
% FIX FOR $...$ PER WERNER'S USAGE
\def\mathmacro#1#2${#2$\textmacro[#1]}
% FIX FOR EQUATION
\let\svequation\equation
\let\svendequation\endequation
\def\eqfinishmacro{}
\newcommand\equationmacro[1]{\gdef\eqfinishmacro{\textmacro[#1]}}
\def\equation{\let\mathmacro\equationmacro\svequation}
\def\endequation{\svendequation\eqfinishmacro\gdef\eqfinishmacro{}}
% FIX FOR ALIGN
\let\svalign\align
\let\svendalign\endalign
\def\alfinishmacro{}
\newcommand\alignmacro[1]{\gdef\alfinishmacro{\textmacro[#1]}}
\def\align{\let\mathmacro\alignmacro\svalign}
\def\endalign{\svendalign\alfinishmacro\gdef\alfinishmacro{}}
\begin{document}
Some text $a^b\mathmacro{MP} c^d$ more text\par
Some more text without a macro $a^b c^d$ more text\par
An equation using mathmacro
\begin{equation}
  a^b\mathmacro{EQ ARG.} c^d%\mathmacro
\end{equation}
to see if it works.\par
Here we have an equation without the mathmacro
\begin{equation}
  a^b =c^d
\end{equation}
Align with the mathmacro
\begin{align}
  a^b \mathmacro{AL ARG.} &= c^d
\end{align}
to also see if it works.\par
Here we us align without the mathmacro.
\begin{align}
  a^b &= c^d
\end{align}
Some text $a^b\mathmacro{ABC} c^d$ more text to see if original definition active.
\end{document}

enter image description here

8
  • Very nice! Thanks for this nice answer. How about multiple invocations of $\mathmacro$ in the same math environment? I would need them all to be pushed to the end. Also, I need to handle \ensuremath in general... Dec 15, 2014 at 18:29
  • I have added these requirements to the question. Dec 15, 2014 at 18:33
  • @JamieVicary That is a bit tougher, but I'll give it some thought. Dec 15, 2014 at 18:35
  • Is it possible to write a macro that saves every \mathmacro call by concatenating it to a big request string? Then once we leave math mode with \end{equation}, \end{align} or $, we could simply execute that big concatenated macro. Dec 15, 2014 at 18:40
  • @JamieVicary That would be indeed be the approach. The typical way I do that expands the contents, which of course one can't do in math mode with a \marginpar. So I have to think harder. Dec 15, 2014 at 18:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .