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