![从包含数学内容列表的 token 中提取](https://linux22.com/image/289479/%E4%BB%8E%E5%8C%85%E5%90%AB%E6%95%B0%E5%AD%A6%E5%86%85%E5%AE%B9%E5%88%97%E8%A1%A8%E7%9A%84%20token%20%E4%B8%AD%E6%8F%90%E5%8F%96.png)
我有一个令牌,其中包含以下列表:
- 格式为日期
YYYY-MM-DD
, - 后面跟着一个冒号,
- 一些可能包含数学的文本。文本将由一两句话组成(即没有段落)。
我想处理这个列表并分别提取日期和内容。
遗憾的是,我目前的 MWE作品完全没问题,我无法重现我在实际使用案例中遇到的间歇性错误。只有列表中有数学内容时才会发生错误(但其他带有数学的列表元素处理得很好)。MWE 得出:
我在实际使用中发现的问题是:
对于存在花括号组(即包含逗号的文本)的情况,我得到一个空字符串作为日期
\StrBefore{\ListMember}{:}[\Date]
。$\deg(e^x)$
对于我收到的文本中存在的情况:TeX 容量超出,抱歉 [输入堆栈大小=5000]。
\保留@a ->\def \保留@a
*{\let \@xs@assign \@xs@expand@and@detokenize...
==> 发生致命错误,未生成输出 PDF 文件!
因此,我的问题是,我处理此列表的方式是否存在固有问题? 有没有更好的方法来进行列表处理和提取(但仍使用令牌寄存器)。
我将继续尝试重现正确的 MWE,但希望有人会突然顿悟,发现我做事方式中的潜在缺陷。
笔记:
- 回想起来,对于文本包含逗号的情况,我认为最好仅将括号组放在文本周围。
代码:
\documentclass{article}
\usepackage{xstring}
\usepackage{tikz}
\usepackage{xcolor}
\newtoks\MyTodoList
% Test cases:
% 1. only text
% 2. ends with math
% 3. Math, but not at the end.
% 4. Brace group required in case there is a comma in the content
% 5. Contains a comma and math.
\MyTodoList={
2014-03-10: Go to class.,
2014-03-11: Solve $\sin x + \cos x = 0.5$.,
2014-03-12: Figure out $\deg(e^x)$ again.,
{2014-03-13: Study for Math, Physics and Geometry.},
{2014-03-14: Prepare for $\pi$ day, and eat pie.},
}
\newcommand*{\Date}{}%
\newcommand*{\TodoItem}{}%
\newcommand*{\MyTodoListExpanded}{}%
\begin{document}
\edef\MyTodoListExpanded{\the\MyTodoList}%
\foreach \ListMember in \MyTodoListExpanded {%
\IfStrEq{\ListMember}{}{}{% Filter out any empty rows (case of trailing comma on last item.
\StrBefore{\ListMember}{:}[\Date]%
\StrBehind{\ListMember}{:}[\TodoItem]%
\par\textcolor{red}{\Date}: \textcolor{blue}{\TodoItem}%
}%
}
\end{document}
答案1
包默认xstring
使用\fullexpandarg
。这意味着,字符串由 处理\edef
。如果字符串包含易碎内容,这将是致命的。甚至\edef
不尊重 LaTeX 的\protect
机制。
因为宏的用例的字符串xstring
在宏中给出,例如:\StrBefore{\ListMember}
,\expandarg
是解决方案,因为它只扩展第一个标记一次。
\foreach ... {%
\expandarg
\IfStrEq{\ListMember}{...
另请参阅文档, 章节“3.1.1 命令\fullexpandarg
,\expandarg
和\noexpandarg
”