我正在尝试用 来做一些巫术\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}}
显然,\blubb
after\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}}
,例如。