在我的文档中,我有条件文本,这些文本带有下划线(在非显示数学模式下),以便读者更清楚地知道文本的哪些部分是条件文本。在显示数学模式下,我不会尝试为内容添加下划线,而是使用单独的标记来指示条件文本。这就是\ConditionalText
下面这个宏的目的,它是我实际用例的一个大大简化的版本。
因此,我希望能够传递文本开始处于文本模式,但可能具有显示数学模式,并且
- 有下划线跳过显示数学部分,然后
- 显示数学运算后恢复。
下面的 MWE 运行良好,但这是因为最后一个\ConditionalText
被注释了,而这是特定的问题情况。
笔记:
我之所以能不是只需应用
\ConditionalText
三次:一次在显示数学之前,然后在显示数学中,然后在显示数学之外,如下面完整的测试用例所示,设置如下\def\ShowProblemSpacingIssue{}
我觉得全文案例下面的可能并不像我预期的那样清楚,所以现在可以忽略它——只有当人们对为什么我不能
\ConditionalText
多次应用宏感兴趣时才相关。一种解决方案是在文本被抑制时手动调整间距,但这不仅容易出错,而且很难知道要调整多少空间,因为可能有多个显示数学环境,或
align
由多行方程组成的块。尽管 MWE 使用包裹
soul
,我并没有陷入这个困境,所以\tikzmark
有一种解决方案就可以了。现在我已经编写了这个问题,我觉得这可能是一个经典的 xy 问题,因为我真的在寻找一种方法来显示条件文本,该文本可能是几个单词、段落中间的几行、可能包含显示数学的整个段落、显示数学方程式的部分,甚至是整个显示数学环境。但解决这个问题需要对我的代码进行最少的更改,因此我首先研究这个问题。
参考:
- 我正在使用的解决方案标记文本部分而不影响间距标记条件文本的指标。
- 指示条件文本位置的 Changbars
代码:MWE
\documentclass{article}
\usepackage{xparse}% Not essential for this problem.
\usepackage{xcolor}
\usepackage{amsmath}% just for \text{}
\usepackage{soul}
\NewDocumentCommand{\UnderlineText}{O{red} m}{%
\setulcolor{#1}\ul{#2}%
}%
\NewDocumentCommand{\ConditionalText}{O{red} m}{%
\ifmmode%
#2% Don't underline if in math mode
\else%
\UnderlineText[#1]{#2}%
\fi%
}%
\begin{document}
\noindent\ConditionalText{Underlining in text mode works great.}
\noindent\ConditionalText{Underlining works with inline math: $e = mc^2.$}
%
\[
\ConditionalText{F = ma \quad\text{Properly skips underling in math mode}}
\]
\noindent
%\ConditionalText{%
The problem is here when there is display math mode
\[ e^{\pi i} = -1\]
in the same paragraph where I need the underlining to \emph{skip}
the display math portion.
%}%
\end{document}
代码:完整测试用例
% With the following commented, I should not need the
% \renewcommand that gets executed below.
\def\ShowProblemSpacingIssue{}%
\documentclass{article}
\usepackage{xparse}% Not essential for this problem.
\usepackage{xcolor}
\usepackage{etoolbox}
\usepackage{amsmath}% just for \text{}
\usepackage{soul}
\usepackage{parskip}
\usepackage{showframe}
\newtoggle{SupressConditionalText}
\ifdefined\ShowProblemSpacingIssue
\toggletrue{SupressConditionalText}
\else
\togglefalse{SupressConditionalText}% This requires last use of \ConditionalText to be commented
\fi
\NewDocumentCommand{\UnderlineText}{O{red} +m}{%
\setulcolor{#1}\ul{#2}%
}%
\NewDocumentCommand{\ConditionalText}{O{red} +m}{%
\ignorespaces%
\iftoggle{SupressConditionalText}{}{%
\ifmmode%
#2% Don't underline if in math mode
\else%
\UnderlineText[#1]{#2}%
\fi%
}%
\ignorespacesafterend%
}%
\begin{document}
\ConditionalText{Underlining in text mode works great.}
\ConditionalText{Underlining works with inline math: $e = mc^2.$}
%
Text before a conditional display math formula.
\[
\ConditionalText{F = ma \quad\text{Properly skips underling in math mode}}
\]
Text after a conditional display math formula.
The following works in terms of toggling the conditional text, but has a spacing issue due to the conditional text in the display math environment:
%
\ConditionalText{%
The problem is here when there is display math mode}%
\[ \ConditionalText{e^{\pi i} = -1} \]
\ConditionalText{%
in the same paragraph where I need the underling to \emph{skip}
the display math portion.
}%
\ifdefined\ShowProblemSpacingIssue
\else
% Want to be able to eliminate this \renewcommand,
% and use \ConditionalText as below.
\renewcommand{\ConditionalText}[2][red]{%{O{red} +m}{%
\iftoggle{SupressConditionalText}{}{%
#2% Don't underline if in math mode
}%
}%
\fi
\ConditionalText{%
The problem is here when there is display math mode
\[ e^{\pi i} = -1\]
in the same paragraph where I need the underling to \emph{skip}
the display math portion.
}%
Some text at end of document to see placement.
Note the additional space above this with
\verb|\def\ShowProblemSpacingIssue{}|.
\end{document}
答案1
我并不认为我的解决方案能够解决您的一般问题,但它可能会给您一些关于如何继续的想法。它使用 stringstrings 包来解析输入行以查找显示数学。然后,它首先处理显示前文本,然后处理显示数学,然后处理显示后数学文本。
问题是 stringstrings 本身并没有设置为处理数学模式特殊字符,尽管它在这方面的能力有限。我利用这种有限的能力,使用 \encodetoken 命令将 \[、\] 和 \pi 添加到 stringstrings 词汇表中。不幸的是,该包在任何给定时间只允许三个这样的分配(这就是为什么这个解决方案还不通用的原因)。此外,stringstrings 无法处理其参数中的 { 或 } 分组符号,尽管如果您使用 \LB 和 \RB 代替它们,它有一个解决方法。最后,在数学模式下,stringstrings 可能会无意中添加一些额外的胶水,这会弄乱您的间距。
有了这些免责声明,该软件包能够处理您的特定情况。请注意,我使用了红色文本而不是下划线,因为当我尝试在我的解决方案中使用它时,您的 \UnderlineText 命令会中断。
无论如何,这里是:
\documentclass{article}
\usepackage{xparse}% Not essential for this problem.
\usepackage{xcolor}
\usepackage{amsmath}% just for \text{}
\usepackage{soul}
\usepackage{stringstrings}
\NewDocumentCommand{\UnderlineText}{O{red} m}{%
\setulcolor{#1}\ul{#2}%
}%
\NewDocumentCommand{\ConditionalText}{O{red} m}{%
\ifmmode%
#2% Don't underline if in math mode
\else%
\UnderlineText[#1]{#2}%
\fi%
}%
\newcounter{letpos}
\newcounter{letpoe}
\newcommand\myCT[1]{%
% PREPARE
\encodetoken[1]{\[}%
\encodetoken[2]{\]}%
\encodetoken[3]{\pi}%
% PRE MATH MODE
\whereisword[q]{#1}{\[}%
\setcounter{letpos}{\theresult}%
\addtocounter{letpos}{-1}%
\substring[q]{#1}{1}{\theletpos}%
\textcolor{red}{\thestring}%
% MATH MODE
\addtocounter{letpos}{1}%
\whereisword[q]{#1}{\]}%
\setcounter{letpoe}{\theresult}%
\substring[e]{#1}{\theletpos}{\theletpoe}%
\retokenize[v]{\thestring}%
% POST MATHMODE
\addtocounter{letpoe}{1}%
\substring[q]{#1}{\theletpoe}{$}%
\removeleadingspaces[q]{\thestring}%
\textcolor{red}{\thestring}%
% CLEAN UP
\decodetoken[1]{\[}%
\decodetoken[2]{\]}%
\decodetoken[3]{\pi}%
}
\begin{document}
\noindent
\myCT{%
The problem is here when there is display math mode
\[ e^\LB\pi i\RB =-1\]
in the same paragraph where I need the underlining to skip
the display math portion. And here is some inline math, $x=3$, as an
extra.
}
\end{document}
输出结果如下: