使用公式或引用来剪切字符串

使用公式或引用来剪切字符串

我正在尝试定义一个宏,它将接受一个字符串并绘制其结尾,例如:

\def\paintString#1{%
  \saveexploremode%
  \exploregroups%
  \textcolor{white}{\StrGobbleRight{#1}{5}}%
  \StrGobbleRight{#1}{2}[\tmp]%
  \textcolor{yellow}{\StrRight{\tmp}{3}}%
  \textcolor{white}{\StrRight{#1}{2}}%
  \restoreexploremode%
}

这与普通文本的预期效果相同(所有内容均为白色,右侧第 4-5 个字符除外,这些字符为黄色)。但是,如果参数包含公式或以下内容,则会出现问题\cite{}

\paintString{Blah \cite{reference}}
\paintString{Blah $\Sigma$}

对此,LaTeX 报告

Argument of \XC@col@rlet has an extra }.

我认为发生这种情况的原因是因为我破坏了公式(或\cite)并将其放入\textcolor{...}{内部和相应的}外部。

有没有办法强制扩展,使得这些特殊的东西被xstring宏视为单个字符?

我需要明确地添加某种扩展(因此\exploregroups),因为没有它,字符串就无法正确解析。此外,这是 Beamer 主题,调用它的地方之一是框架标题,如果未扩展,则报告\StrLength1,因此上述绘制根本不会发生。

编辑:使用起来更安全一些:

\def\paintString#1{%
  \saveexploremode%
  \exploregroups%
  {\color{white}\StrGobbleRight{#1}{5}%
  \StrGobbleRight{#1}{2}[\tmp]%
  \color{yellow}\StrRight{\tmp}{3}%
  \StrRight{#1}{2}}%
  \restoreexploremode%
}

但是,它仍然失败\cite

答案1

这是一个令人满意的解决方案:

\def\paintString#1{%
  \IfSubStr{\expandafter\detokenize\expandafter{#1}}{\detokenize{\paintString}}{%
    #1%
  }{%
    \saveexploremode%
    \exploregroups%
    {\color{white}\StrGobbleRight{#1}{5}%
    \StrGobbleRight{#1}{2}[\tmp]%
    \color{yellow}\StrRight{\tmp}{3}%
    \color{white}\StrRight{#1}{2}}%
    \restoreexploremode%
  }%
}

这正如我在之前对这个问题的评论中所建议的那样:

处理此问题的另一种方法可能是以某种方式实现\paintString{some text}已处理但\paintString{some \paintString{already painted} text}按原样返回,因此“一些”和“文本”不是特别绘制的,但“已绘制”是。这将为用户提供一种简单的方法来控制有问题的文本块。

因此,我可以自由地放置\frametitle{Some text}\frametitle重新定义为\painString用于标题)并且像以前一样正确地绘制它。

但是,\frametitle{Author \cite{reference}}仍然会失败,因此我用 来解决它\frametitle{\paintString{Author} \cite{reference}},从而绘制“作者”并保持\cite{reference}原样(即,仅将其附加到绘制的作者姓名之后)。

为了更加安全,我添加了一些额外的代码,完全抑制了绘画,甚至没有检查参数的值:

\def\paintString#1{%
  \ifnum\suppressPainting=0%
    \IfSubStr{\expandafter\detokenize\expandafter{#1}}{\detokenize{\paintString}}{%
      #1%
    }{%
      \saveexploremode%
      \exploregroups%
      {\color{white}\StrGobbleRight{#1}{5}%
      \StrGobbleRight{#1}{2}[\tmp]%
      \color{yellow}\StrRight{\tmp}{3}%
      \color{white}\StrRight{#1}{2}}%
      \restoreexploremode%
    }%
  \else%
    {\color{white}#1}%
  \fi%
}

因此,\def\suppressPainting{1}无论参数值如何,将某个位置放在框架之前都会抑制绘画。 可能有一点 TeX-ier 解决方案,但我不知道。

当然,自动解决方案(不需要用户干预,只需手动调用\paintString)会更好,但我不认为这是不可能的(正如@egreg 在上面的评论中所建议的那样),所以这可能是处理问题的最佳方法。

相关内容