在以下 MWE 中
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage[pdftex,unicode,final]{hyperref}
\input{glyphtounicode}
\pdfgentounicode=1
\makeatletter
\newcommand*{\boilerplate}{\@ifstar\@@boilerplate\@boilerplate}
\newcommand*{\@boilerplate}{Boilerplate for running text}
\newcommand*{\@@boilerplate}{Boilerplate for headings in capalized form}
\makeatother
\begin{document}
\section{\boilerplate*}
\end{document}
星号用于获取样板的替代变体。MWE 失败,
Token not allowed in a PDF string (Unicode):
(hyperref) removing `\@ifnextchar' on input line 19.
显然,问题在于宏扩展的顺序。我已经尝试过,\expandafter
但没有找到解决方案。
评论:如果可能的话,我想保留星号版本以选择样板的变体。这种设计已经达成一致,并在无数地方使用。换句话说,将宏定义更改为类似于\boilerplateNormal
和的内容\boilerplateVariant
不是一个选择,因为这会破坏与使用 sty 文件的其他作者的兼容性。
答案1
\boilerplate
根据当前的定义,该命令很脆弱。
\protect\boilerplate
在移动参数中使用when,或者
\DeclareRobustCommand{\boilerplate}{\@ifstar\@@boilerplate\@boilerplate}
代替\newcommand
。
或者,添加\usepackage{xparse}
并修改定义到
\NewDocumentCommand{\boilerplate}{s}{%
\IfBooleanTF{#1}{%
Boilerplate for headings in capitalized form% \boilerplate*
}{%
Boilerplate for running text% \boilerplate (with no *)
}%
}
不过,不要指望\boilerplate
(带或不带) 的扩展能出现在书签中。如果宏采用常规参数,则*
可以做到这一点。\boilerplate
假设在移动参数中使用 *-variant,则可以使用\pdfstringdefDisableCommand
:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{xparse}
\usepackage[unicode,final]{hyperref}
\input{glyphtounicode}
\pdfgentounicode=1
\NewDocumentCommand{\boilerplate}{s}{%
\IfBooleanTF{#1}{%
Boilerplate for headings in capitalized form% \boilerplate*
}{%
Boilerplate for running text% \boilerplate (with no *)
}%
}
\pdfstringdefDisableCommands{\def\boilerplate*{Boilerplate for bookmark}}
\begin{document}
\section{\boilerplate*}
\boilerplate
\end{document}