自动将某些输入(例如标点符号)置于环境/命令之外

自动将某些输入(例如标点符号)置于环境/命令之外

所以我有一个代码,修改自这是用户“ShreevatsaR”的回答,可以使用

\tooltips{...}

该代码对其中的任何字符都非常有用。

例如,对于:

\tooltips{疊音詞疊音詞疊音詞}

只有...代码会卡住标点符号

代码不是为标点符号设计的,这没问题。因为代码运行了一些字符编码转换,而标点符号不需要这些转换。

但是,问题是,目前我无法编译这样的东西:

\tooltips{疊音詞(疊、音、詞。)疊音詞}

事实上,我必须手动复制和粘贴,直到最终获得命令之外的所有标点符号,并重新初始化非标点符号部分的环境:

\tooltips{疊音詞}(\tooltips{疊}、\tooltips{音}、\tooltips{詞}。)\tooltips{疊音詞}

这有点耗时。有什么方法可以自动完成吗?

请注意,对于这个问题,答案不需要使用特定的\tooltips{...}命令。就我而言,你可以用以下命令替换任何命令类型,例如:

从:

\any{疊音詞(疊、音、詞。)疊音詞}

到:

\any{疊音詞}(\any{疊}、\any{音}、\any{詞}。)\any{疊音詞}

此外,中文字符不是必需的。它们可以是任何不在预定义排除项目列表中的内容,例如:

从:

\any{AQ(D、Y、F。)PIOP}

到:

\any{AQ}(\any{D}、\any{Y}、\any{F}。)\any{PIOP}

重点是排除任何标点符号(在本例中是 andand )

我会满意:

  • 答案要么因此排除所有可能的标点符号,无论 Tex 怎样找出这些……
  • 或者允许指定标点符号列表的答案(例如,以下示例中的,and ?and .and "and and )。-

从:

\any{AQ,D?Y.F'-PIOP}

到:

\any{AQ},\any{D}?\any{Y}.\any{F}'-\any{PIOP}

答案1

您可以从 OPmac 使用。它用后面跟有此标点符号的\replacetrings替换提到的标点符号。然后您可以定义简单的宏,参数用 分隔。&\anyA&

\replacestring当你使用纯 TeX 加 OPmac 时,定义的代码不能直接使用。

\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\bgroup \catcode`!=3 \catcode`?=3
\gdef\replacestrings#1#2{\long\def\replacestringsA##1#1{\def\tmpb{##1}\replacestringsB}%
   \long\def\replacestringsB##1#1{\ifx!##1\relax \else\addto\tmpb{#2##1}%
      \expandafter\replacestringsB\fi}%     improved version <May 2016> inspired 
   \expandafter\replacestringsA\tmpb?#1!#1% from pysyntax.tex by Petr Krajnik
   \long\def\replacestringsA##1?{\def\tmpb{##1}}\expandafter\replacestringsA\tmpb
}
\egroup


\def\any#1{\def\tmpb{#1}%
   \replacestrings {,}  {&,}%
   \replacestrings {.}  {&.}%
   \replacestrings {'-} {&{'-}}
   \replacestrings {'}  {&'}%
   \replacestrings {(}  {&(}%
   \replacestrings {)}  {&)}%
   \replacestrings {?}  {&?}%
   \expandafter\anyA\tmpb&{}%
}
\def\anyA#1#2&#3{\anyX{#1#2}#3\ifx&#3&\else\expandafter\anyB\fi}
\def\anyB{\futurelet\next\anyC}
\def\anyC{\expandafter\ifx\space\next\space\fi\anyA}


% just for testing:
\def\anyX#1{any[#1]}

\any{AQ,D?Y.F'-PIOP}
% result:  any[AQ],any[D]?any[Y].any[F]'-any[PIOP]

\bye

答案2

新的答案——保留标点符号

我知道的唯一按任意字符集拆分文本的方法是\regex_split使用解释3. 对我来说这是一个可怕的领域。

下面的代码可以产生输出:

在此处输入图片描述

从(本质上)以下几行来看:

\Any{A, (B: C. D)} 
\Any{A), E,  G  H(;;,) (B: C. D)}
\Any{abc,a:b::def:f}
\Any{A,A,,AAA}

完整代码如下:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\seq_new:N \l_word_seq % define a new seqence
\NewDocumentCommand\IterateOverPunctutation{ m m }{
  % apply "function" #2 to the "words" in #1 between the punctuation  characters
   \regex_split:nnN{ ([\(\)\.,;\:\s]+) }{ #1 }\l_word_seq% split word to sequence
    \cs_set:Nn \l_map_two:n {
       \regex_match:nnTF{ ^[\(\)\.,;\:\s]*$ }{##1}
            {##1}% matches a punctuation character or empty string
            {#2{##1}}% apply #2 to ##1
    }
    \seq_map_function:NN\l_word_seq\l_map_two:n% apply \l_map_two to sequence
}
\ExplSyntaxOff
\begin{document}

% make a wrapper for \Any to apply \IterateOverPunctutation
\newcommand\realAny[1]{``\textbf{#1}''\space}% a dummy \Any command
\newcommand\Any[1]{\IterateOverPunctutation{#1}\realAny}

\Any{A, (B: C. D)}

\Any{A), E,  G  H(;;,) (B: C. D)}

\Any{abc,a:b::def:f}

\Any{A,A,,AAA}

\end{document}

我发现解释3为了避免令人害怕,让我稍微解释一下代码的工作原理。

  • 理论上, *正则表达式([\(\)\.,;\:\s]+)匹配一个或多个“标点符号”(.,;:)周围的空格。表示[...]匹配其中任何一个,表示+它们应该出现一次或多次。我们必须“转义”字符(.:),因为它们在正则表达式中还有其他含义,并且\s是任何“空格”字符。最后,(...)使其成为“匹配组”,这意味着稍后会记住它。请参阅l3regex文档以了解更多详细信息。
  • \regex_split:nnN将“单词”拆分为由#1正则表达式中的内容分隔的序列。这里的关键是正则表达式中的匹配组(即标点符号)也会被放入序列中!这意味着我们可以遍历该序列,使用\seq_map_function:NN并使用\regex_match:nnTF来打印标点符号或应用于\Any序列中的“单词”。
  • 定义\cs_set:Nn一个新的宏,应用于序列的每个元素,其中包括标点符号,因为正则表达式中的捕获组(与\cs_new:Nn此不同,如果命令已准备好定义,则不会抱怨
  • 如果“句子”以标点符号结尾,则 中将有一个“空”序列\l_word_seq。为了满足此要求,\regex_match查找^[\(\)\.,;\:\s]*$,它匹配 0 次或多次“标点符号”,但前提是它是 的全部##1。也就是说,它接受空字符串或完整的标点符号句子。

原始答案

我将回答评论中给出的问题版本,即\something对逗号分隔列表的每个元素应用命令。使用\docsvlist来自电子工具箱包裹。

由于没有 MWe,并且\something下面的 MWe没有\something定义\textbf

\documentclass{article}
\usepackage{etoolbox}
\begin{document}

\renewcommand*\do[1]{\textbf{#1}}
\docsvlist{A,B,C,D}
\end{document}

空格分隔的列表稍微难一点,可能不值得付出努力。考虑到原始问题中使用了逗号,我认为这没问题。当然,如果\something用 OP 的命令替换,可能会出错\tooltips,但在几乎所有情况下,这都是没问题的。

答案3

这似乎有效;首先我们按空格分割输入,然后处理每个项目。

它需要定义\tooltipsA为执行以下任务的宏真实的与工具提示一起使用,而\tooltip仅用于处理标点符号的输入。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\tooltipsA}{m}
 {
  \fbox{#1} % this should be the real action of your \tooltip command
 }

\NewDocumentCommand{\tooltip}{m}
 {
  \seq_set_split:Nnn \l_tmpa_seq { ~ } { #1 }
  \seq_clear:N \l_tmpb_seq
  \seq_map_function:NN \l_tmpa_seq \vincent_process:n
  \seq_use:Nn \l_tmpb_seq { ~ }
 }

\cs_new_protected:Nn \vincent_process:n
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  \regex_replace_all:nnN
   { ( [^\(\)]+? ) ( [,.]+? ) } % <==== Here define your punctuations
   { \c{tooltipsA}\cB\{ \1 \cE\} \2 }
   \l_tmpa_tl
  \regex_match:nVF { \c{tooltipsA} } \l_tmpa_tl
   {
    \regex_replace_once:nnN
     { ( \(? ) ( [^\(\)]* ) }
     { \1 \c{tooltipsA}\cB\{ \2 \cE\} }
     \l_tmpa_tl
   }
  \seq_put_right:NV \l_tmpb_seq \l_tmpa_tl
 }
\cs_generate_variant:Nn \regex_match:nnF { nV }

\ExplSyntaxOff

\begin{document}

\tooltip{a,b,c.}

\tooltip{abc (d,ef,g.) hij (uuu vvv)}

\end{document}

这里我给出了 的伪定义\tooltipsA,只是为了显示结果符合预期。

在此处输入图片描述

答案4

listofitems包可以快速完成该工作。

\documentclass{article}
\usepackage{listofitems,amsmath}
\newcommand\any[1]{\fbox{#1}}
%%%
\let\svany\any
\renewcommand\any[1]{%
  \setsepchar{,||?||.||'||-||(||)|| }
  \readlist\mylist{#1}%
  \foreachitem\i\in\mylist{%
    \expandafter\ifx\expandafter\relax\i\else\svany{\i}\fi%
    \ifnum\icnt<\mylistlen\relax\mylistsep[\icnt]\fi%
  }%
}
%%%
\begin{document}
\any{AQ,D?Y.F'-PIOP}

\any{a,b,c.}

\any{abc (d,ef,g.) hij (uuu vvv)}
\end{document}

在此处输入图片描述

相关内容