章节标题内的递归 \peek_meaning

章节标题内的递归 \peek_meaning

我正在尝试用 来做一些巫术\peek_meaning。我想要一个命令,\blubb,它对重复本身

当我写作时\blubb{Lorem Ipsum},我希望文字有颜色红色的,但\blubb\blubb{Lorem Ipsum}我希望文字有颜色蓝色的.参见此工作示例:

\documentclass{article}
\usepackage{xcolor}
\usepackage{expl3}
\usepackage{xparse}

%\usepackage{hyperref}

\ExplSyntaxOn

\DeclareRobustCommand\blubb{
    \peek_meaning:NTF \blubb { \colorTwo } { \colorOne }
}

\ExplSyntaxOff

\DeclareRobustCommand\colorOne[1]{\textcolor{red}{#1}}
\DeclareRobustCommand\colorTwo[2]{\textcolor{blue}{#2}}

\begin{document}

Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}

\section{Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}}
% ^ does not work with hyperref

\end{document}

截屏

这很好,直到我启用了该hyperref包。然后我得到:

! TeX capacity exceeded, sorry [input stack size=5000].
\blubb  ->\peek_meaning:NTF \blubb 
                                   {\colorTwo }{\colorOne }
l.23 ...b{is red} Dolor Sit \blubb\blubb{is blue}}

显然,\blubbafter\peek_meaning被扩展了,这导致了递归。我该如何防止这种情况发生?

答案1

\documentclass{article}
\usepackage{xcolor}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn

\NewDocumentCommand \blubb { }
 {
  \peek_meaning_remove:NTF \blubb { \colorTwo } { \colorOne }
 }

\ExplSyntaxOff

\NewDocumentCommand \colorOne { m } {\textcolor{red}{#1}}
\NewDocumentCommand \colorTwo { m } {\textcolor{blue}{#1}}

\begin{document}

Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}

\section{Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}}
% ^ does not work with hyperref without warnings

\end{document}

输出

但请注意控制台输出:

Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref)                removing `\blubb' on input line 139.

这是因为hyperref为 制作的书签\section不能包含\blubb宏。有关hyperref详细信息,请参阅 的文档。我们可以使用\texorpdfstring{}{}来避免此问题。

\documentclass{article}
\usepackage{xcolor}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn

\NewDocumentCommand \blubb { }
 {
  \peek_meaning_remove:NTF \blubb { \colorTwo } { \colorOne }
 }

\ExplSyntaxOff

\NewDocumentCommand \colorOne { m } {\textcolor{red}{#1}}
\NewDocumentCommand \colorTwo { m } {\textcolor{blue}{#1}}

\begin{document}

Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}

\section{Lorem Ipsum \texorpdfstring{\blubb}{}{is red} Dolor Sit \texorpdfstring{\blubb\blubb}{}{is blue}}

\end{document}

不过,避免警告的更方便的方法可能是在必要时使用hyperref的钩子来禁用\blubb。例如(也可以使用推荐的bookmark包):

\documentclass{article}
\usepackage{xparse,xcolor}
\usepackage{hyperref}
\usepackage{bookmark}

\ExplSyntaxOn

\NewDocumentCommand \blubb { }
 {
  \peek_meaning_remove:NTF \blubb { \colorTwo } { \colorOne }
 }

\ExplSyntaxOff

\NewDocumentCommand \colorOne { m } {\textcolor{red}{#1}}
\NewDocumentCommand \colorTwo { m } {\textcolor{blue}{#1}}

\makeatletter
\pdfstringdefDisableCommands{%
  \let\blubb\@firstofone
}
\makeatother

\begin{document}

Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}

\section{Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}}

\end{document}

答案2

一种不同的方法。

\documentclass{article}
\usepackage{xcolor}

\usepackage{hyperref}

\def\blubb#1{%
  \ifx\blubb#1\relax%
    \def\blubbcolor{blue}\expandafter\blubbhelp%
  \else
    \def\blubbcolor{red}\blubbhelp{#1}%
  \fi%
}
\def\blubbhelp#1{\textcolor{\blubbcolor}{#1}}

\begin{document}

Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}

Lorem Ipsum \blubb{is red}Dolor Sit \blubb\blubb{is blue}without trailing spaces.

\section{Lorem Ipsum \blubb{is red} Dolor Sit \blubb\blubb{is blue}}
% ^ does not work with hyperref

\end{document}

在此处输入图片描述

正如 cfr 正确指出的那样,\blubb在章节标题中使用 时会产生警告hyperref,用于创建书签。可以使用 来克服它\texorpdfstring,如下所示:\section{Lorem Ipsum \texorpdfstring{\blubb{is red}}{is red} Dolor Sit \texorpdfstring{\blubb\blubb{is blue}}{is blue}},例如。

相关内容