如何测试宏参数是否以显示的方程式结尾?

如何测试宏参数是否以显示的方程式结尾?

我想构建一个宏,将其参数的内容转换为粗体,无论是文本、内联方程还是显示方程。(我使用箭头表示向量,所以这不是问题。)因此,我定义了以下宏:

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

问题是,如果#1以显示的方程式结尾,则会在下一行前面添加一个水平空格,如下所示:

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

“Text2” 相对于“Text1”向右移动一个空格。如果我\makebold按以下方式定义,我可以摆脱这个空格:

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

现在的问题是合法的空格也被删除了,如下例中“Text2”前面的空格一样:

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

那么,我如何知道宏参数是否以显示的方程式结尾?我曾尝试测试 a\belowdisplayskip或 a\belowdisplayshortskip是否带有 a\lastskip关系(例如仅当最后一段没有以显示的数学运算结束时才添加 \par删除末尾的多余空间),但这仅当我\par在 之后插入 时才有效#1,并且在上述情况 2 中,我不想离开水平模式。我也尝试过设置\postdisplaypenalty为某个神奇值并测试是否插入了该值,但它也不起作用。

@campa 我知道如果以显示的方程式结尾,我可以在%其后插入一个\makebold{...},但我经常忘记这样做。这是一个您可以编译的文件:

\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}

答案1

这将处理使用给定环境集指示的显示数学\[\]。如果您希望\ignorespaces在参数以任何环境结束时这样做,这会更容易一些。该命令\declaredisplayenvs采用逗号分隔的环境名称列表,这些环境名称是您想要单独处理的环境名称。

\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}{}}}

完整示例:

\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} 

相关内容