是否可以定义一个命令来影响当前句子结束之前的所有内容?
例如,我尝试使用类似以下语法定义命令:
\documentclass{minimal}
\begin{document}
\sentencecommand This is the first sentence.
This is the second sentence.
This is the final sentence.
\end{document}
其中\sentencecommand
只影响句子“这是第一句话。”,但不影响任何后续句子?
答案1
如果句子以句号结束,那么您可以定义,例如:
\def\sentencecommand #1.{{\it#1}.}
egreg 从他的角度展示了“正确的工具”(见评论),我可以从我的角度展示“正确的工具”:OpTeX 和\eoldef
。\replstring
您可以看到解决方案要复杂得多,没有类似的\def\foo#1.{}
,但我们必须定义三个宏。
\eoldef\sentencecommand#1{\def\tmp{#1}%
\replstring\tmp{.}{\use{.}}%
\replstring\tmp{?}{\use{?}}\replstring\tmp{!}{\use{!}}%
\ea\sentencecommandA\tmp\use{ }%
}
\def\sentencecommandA#1\use#2{{\it#1#2}}
\def\use#1{#1}
\sentencecommand This is the first sentence. This is the second sentence.
This is the final sentence.
\sentencecommand This is the first sentence? This is the second sentence.
This is the final sentence.
\sentencecommand This is the first sentence.
This is the second sentence.
This is the final sentence.
\sentencecommand This is the first sentence
and the text goes on.
\bye
答案2
您可以查找结束符、句号、感叹号或问号。无论哪个先出现,处理都会结束,找到的内容将以斜体显示。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\sentencecommand}{}
{
\group_begin:
\char_set_catcode:nn { "0D } { 12 }
\peek_regex_replace_once:nn
{ (.*?) ([\x{0d}\.]) } % anything followed by ^^M or .
{ \c{textit} { \1 } \c{__thevekat_replace:n} { \2 } }
}
\cs_new_protected:Nn \__thevekat_replace:n
{
\str_if_eq:nnTF { #1 } { . } { .\__thevekat_remove: } { ~ \group_end: }
}
% we need to remove a possible \endlinechar (of category 12 after the period)
\cs_new_protected:Nn \__thevekat_remove:
{
\peek_charcode_remove:NTF \__thevekat_endline: { ~ \group_end: } { \group_end: }
}
\use:x { \cs_set_eq:NN \exp_not:N \__thevekat_endline: \char_generate:nn { "0D } { 12 } }
\ExplSyntaxOff
\begin{document}
\sentencecommand This is the first sentence. This is the second sentence.
This is the final sentence.
\sentencecommand This is the first sentence.
This is the second sentence.
This is the final sentence.
\sentencecommand This is the first sentence
and the text goes on.
\end{document}
并不真地那复杂:打开一个组,并将\endlinechar
设为类别代码 12,因此我们可以使用带有 的正则表达式来查找它\x{0D}
(这假设 的标准值为\endlinechar
)。但正则表达式也可以查找第一个句号、感叹号或问号。找到的内容将以斜体排版,并处理终止符:如果是 ,则将\endlinechar
其转换为空格,然后关闭该组。否则,将字符排版并查找\endlinechar
;如果找到 ,则将其转换为空格。在任一情况下,该组都是关闭的。
但是,语法\sentencecommand{This is the first sentence.}
更易于维护且不易出错。