使用 TeXlive 2016 和 LuaLaTeX,但我认为这是通用的。它涉及普通文本,没有数学模式、浮点数、列表或类似的东西。
问题:不同的用户提供纯文本块,其中 LaTeX 标记非常少。特别是,他们知道 表示\\
换行符, 或\par
空白行表示新段落。
用户文本插入到处理文本的宏中。问题:有些用户将 放在\\
文本末尾。它不应该在那里。如果文本以 结尾\\
(即使以 结尾\par
),也可以。但如果以 结尾,\\
则会插入一个额外的空白行。
目前,这需要有人(并不总是我)检查提交的文本,并手动删除\\
出现在末尾的文本。我的问题是:有没有办法\\
在进一步处理文本块之前自动从文本块末尾删除文本?在 LaTex 中就是这样。
梅威瑟:
% !TeX program = LuaLaTeX
% !TeX encoding = UTF-8
\documentclass{article}
\def\printTHIS{Well, not really all that dark.\\} % incorrect user input
\begin{document}
It was a dark and stormy night.\par
\printTHIS\par
And not really all that stormy, either.\par
\end{document}
我已经搜索并找到了一个vskip=\lastskip
在这种情况下不起作用的参考。注意:段落之间的跳过设置为 0pt。
答案1
我不确定这是否适合您,但一种可能性是将用户文本传递给“清理”宏,该宏会\\
在文本末尾删除(如果存在)。您可以使用“辅助”宏来执行此操作,该宏会查找\\
并将其丢弃。例如,
\newcommand\printTHIS[1]{\CheckEndings#1\\@}
\def\CheckEndings#1\\#2@{#1}
因此,\printTHIS
将用户文本传递给\CheckEndings
,以及\\@
。该宏需要两个由和\CheckEndings
分隔的参数。如果用户文本不以 结尾,则对于宏而言 是用户的文本并且为空,而如果文本以 结尾,则为。无论哪种方式,都会丢弃并只打印(已清理的)文本。\\
@
\\
\CheckEndings
#1
#2
\\
#2
\\
\CheckEndings
#2
以下是完整的 MWE:
\documentclass{article}
\makeatletter
\newcommand\printTHIS[1]{\CheckEndings#1\\@}
\def\CheckEndings#1\\#2@{#1}
\makeatother
\begin{document}
It was a dark and stormy night.\par
\printTHIS{Well, not really all that dark.\\}\par % incorrect user input
\printTHIS{Well, not really dark at all.}\par % correct user input
And not really all that stormy, either.\par
\end{document}
编辑
正如评论中指出的那样,这种方法对于\\
嵌入的字符串无效。这是另一种方法,\SplitList
使用解析更好地处理这种情况的包:
\documentclass{article}
\usepackage{xparse}
\DeclareDocumentCommand\RemoveSlashes{>{\SplitList{\\}}m}
{\ProcessList{#1}\PrintPieces}
\newcommand\PrintPieces[1]{#1 }
\begin{document}
It was a dark and stormy night.\par
\RemoveSlashes{Well, not really all that dark.\\}\par % incorrect user input
\RemoveSlashes{Well, not really dark at all.}\par % correct user input
\RemoveSlashes{Well, not really dark at all,\\ but not that light either}\par % correct user input
\RemoveSlashes{Well, not dark,\\ and not light either.\\}\par % correct user input
And not really all that stormy, either.\par
\end{document}
输出为:
这种方法可能存在的一个缺点是它忽略了所有嵌入\\
的 。如果您想打印嵌入的\\
(当然最后一个除外),那么您可以使用上述想法的以下变体来实现:
\DeclareDocumentCommand\RemoveSlashes{>{\SplitList{\\}}m}
{\let\piecesSep\relax% insert before each "piece" (nothing at start)
\ProcessList{#1}\PrintPieces}
\newcommand\PrintPieces[1]{\ifx#1\empty\else\piecesSep #1\fi
\def\piecesSep{\\}\fi% insert \\ after first piece
}
这会将嵌入的字符串视为\\\\
,\\
这可能不是想要的,但是你(或者至少是我)可以保护用户免受他们自己的愚蠢行为侵害的程度是有限的:)