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.

  • 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 '14 at 17:36
  • 1
    The \textmacro command puts a note in the margin using \marginpar. For more context see tex.stackexchange.com/questions/215322/…. – Jamie Vicary Dec 15 '14 at 17:50
3

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

  • 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... – Jamie Vicary Dec 15 '14 at 18:29
  • I have added these requirements to the question. – Jamie Vicary Dec 15 '14 at 18:33
  • @JamieVicary That is a bit tougher, but I'll give it some thought. – Steven B. Segletes Dec 15 '14 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. – Jamie Vicary Dec 15 '14 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. – Steven B. Segletes Dec 15 '14 at 18:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.