# How to test if a macro parameter ends with a displayed equation?

I would like to build a macro converting the contents of its parameter to bold, whether be it text, inline equations or displayed equations. (I use an arrow for vectors, so this is not a problem.) I have therefore defined the following macro:

\def\makebold#1{{\bfseries\mathversion{bold}#1}}


The problem is that, if #1ends with a displayed equation, a horizontal space is added in front of the next line, as in the following:

\par\noindent Text1:
\makebold{one has $x=y.$}
Text2.


"Text2" is shifted by one space to the right with respect to "Text1". I can get rid of this space if I define \makebold in this way:

\def\makebold#1{{\bfseries\mathversion{bold}#1}\ignorespaces}


The problem now is that legitimate spaces are removed too, as in the following example, in front of "Text2":

Text1: \makebold{one has $x=y$.} Text2.


So, how can I know if the macro parameter ends with a displayed equation? I have tried to test for a \belowdisplayskip or a \belowdisplayshortskip with a \lastskip (as in Add \par only if last paragraph did not end with displayed math and Remove excess space at end), but this works only if I insert \par after #1, and in case 2 above, I don't want to leave the horizontal mode. I have also tried to set \postdisplaypenalty to some magic value and to test if this value is inserted, but it doesn't work either.

@campa I know that I can insert a % after \makebold{...} if it ends with a displayed equation, but I often forget to do it. Here is a file you can compile:

\documentclass{article}
\usepackage{amsmath}
\def\makeboldfirst#1{{\bfseries\mathversion{bold}#1}}
\def\makeboldsecond#1{{\bfseries\mathversion{bold}#1}\ignorespaces}
\begin{document}

\par\noindent Text1:
\makeboldfirst{one has $x=y.$}
Text2. % Unwanted space before "text2".

Text1: \makeboldfirst{one has $x=y$.} Text2. % OK.

\par\noindent Text1:
\makeboldsecond{one has $x=y.$}
Text2. % OK

Text1: \makeboldsecond{one has $x=y$.} Text2. % Space disappears before "Text2".

Environment display math test: \makeboldsecond{\begin{align*}x=y\end{align*}} Text

\end{document}

• Thanks for the update. Side comment: pinging a user with @name works only in comments, not in questions or answers. – campa Feb 8 '18 at 13:33

This handles display math indicated with  and with a given set of environments. If you want to \ignorespaces whenever the argument ends in any environment it would be a little easier. The command \declaredisplayenvs takes a comma separated list of environment names that you want to handle separately.

\makeatletter
\long\def\ifendswithdisplay#1{\ifendswithdisplay@#1\@nil\]\@nil\@nilb}
\long\def\ifendswithdisplay@#1\]\@nil#2\@nilb{%
\ifx&#2&%
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
}

\long\def\ifendswithdisplayenv#1{\ifendswithdisplayenv@#1\@nil\end{}\@nil\@nilb}
\long\def\ifendswithdisplayenv@#1\end#2{%
\@ifnextchar\@nil{%
\ifendswithdisplayenv@@{#2}
}{%
\ifendswithdisplayenv@
}%
}

\long\def\ifendswithdisplayenv@@#1#2\@nilb{%
\@ifundefined{displayenv?#1}{%
\@secondoftwo
}{%
\@firstoftwo
}%
}

\def\declaredisplayenvs#1{\declaredisplayenvs@#1,\@nil}
\def\declaredisplayenvs@#1,{%
\expandafter\let\csname displayenv?#1\endcsname\empty
\@ifnextchar\@nil{\@gobble}{\declaredisplayenvs@}
}
\makeatother

% Specify here a comma separated list of the environments you want handled
\declaredisplayenvs{align*,align}

\long\def\makebold#1{{\bfseries\mathversion{bold}#1}\ifendswithdisplay{#1}{\ignorespaces}{\ifendswithdisplayenv{#1}{\ignorespaces}{}}}


A full example:

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\def\ifendswithdisplay#1{\ifendswithdisplay@#1\@nil\]\@nil\@nilb}
\def\ifendswithdisplay@#1\]\@nil#2\@nilb{%
\ifx&#2&%
\expandafter\@secondoftwo
\else
\expandafter\@firstoftwo
\fi
}

\def\ifendswithdisplayenv#1{\ifendswithdisplayenv@#1\@nil\end{}\@nil\@nilb}
\def\ifendswithdisplayenv@#1\end#2{%
\@ifnextchar\@nil{%
\ifendswithdisplayenv@@{#2}
}{%
\ifendswithdisplayenv@
}%
}

\def\ifendswithdisplayenv@@#1#2\@nilb{%
\@ifundefined{displayenv?#1}{%
\@secondoftwo
}{%
\@firstoftwo
}%
}

\def\declaredisplayenvs#1{\declaredisplayenvs@#1,\@nil}
\def\declaredisplayenvs@#1,{%
\expandafter\let\csname displayenv?#1\endcsname\empty
\@ifnextchar\@nil{\@gobble}{\declaredisplayenvs@}
}
\makeatother

\declaredisplayenvs{align*,align}

\def\makebold#1{{\bfseries\mathversion{bold}#1}\ifendswithdisplay{#1}{\ignorespaces}{\ifendswithdisplayenv{#1}{\ignorespaces}{}}}

\parindent=0pt
\begin{document}
Text1:
\makebold{one has $x=y.$}
Text2. % Unwanted space before "text2".

Text1: \makebold{one has $x=y$.} Text2. % OK.

Text1:
\makebold{one has $x=y.$}
Text2. % OK

Text1: \makebold{one has $x=y$.} Text2. % Space disappears before "Text2".

Text1: \makebold{one has \begin{align*}x=y.\end{align*}}
Text2.

Text1: \makebold{one has \begin{align*}x=y.\end{align*}} Text2.

Text1: \makebold{one has \begin{align}x=y.\end{align}}
Text2.

Text1: \makebold{one has \begin{align}x=y.\end{align}} Text2.
\end{document}

• Interesting try, but this will work only for $...$. I would like to have a solution also for environments such as equation, equation*, align, etc. Generalizing \ifendswithdisplay for all these cases does not seem practical. – Michel Fioc Feb 8 '18 at 14:10
• Updated to handle a set of environments. I also edited your example include an environment case, since you gave no indication before that you wanted that case too. – Hood Chatham Feb 8 '18 at 15:13
• I have tested it and it works very well. I have waited a little in case another simpler solution would arise (involving for instance some e-TeX primitive such as \lastnodetype). I prefixed all the \def with \long since the parameter may contain some \par. You may want to edit your answer to take into account this case. – Michel Fioc Feb 9 '18 at 13:58
• There might be some simpler way using lualatex, but I don't think e-tex can provide any help here. This is only ~30 lines of code, which I guess is a lot to express such a simple check, but it could be a lot worse. – Hood Chatham Feb 9 '18 at 14:37
• Edited to add \longs as you suggested. – Hood Chatham Feb 9 '18 at 14:39