\bletter
Si lo define, \DeclareRobustCommand\bletter[1]{\textbf{#1}}
funciona bien incluso dentro de los comandos de sección. Pero si desea usarlo en un comando \edef
o \xdef
, \bletter
se romperá (excepto si lo define \let\protect\noexpand
). Eso significa:
\xdef\boldyletter{\bletter{y}}
arrojará un mensaje de error.
¿Existe algún comando para definir comandos siempre irrompibles?
Respuesta1
Puedes usar
\NewDocumentCommand\bletter{m}{\textbf{#1}}
lo que hace una definición de e-tex \protected
que no se expande en un edef.
Pero nunca debe usarlo \xdef
en entradas de látex desconocidas; use \protected@xdef
entonces los comandos robustos de LaTeX estarán protegidos.
Respuesta2
Simplemente use \protected\def
primitivos para la declaración de su \bletter
macro:
\protected\def\bletter#1{\textbf{#1}}
Las \protected
macros no se expanden durante \edef
, \xdef
, \write
, \message
etc.
Respuesta3
Lamento responder mi propia pregunta, pero no tengo idea de cómo compartir mi solución con la comunidad.
\def\RJDeclareRobustCommand#1% #1 name of new command, #2 same instructions as \newcommand
{%
\gdef#1%
{%
\begingroup%
\let\relax\aftergroup% this has to be redefined before processing \csname @\string#1\endcsname
\ifx\aftergroup\relax% this is false in expandations
\expandafter\aftergroup\csname RJ@\expandafter\@gobble\string#1\endcsname%
\else% \expandafter\aftergroup\expandafter\noexpand\csname\expandafter\@gobble\string#1@RJ\endcsname%
\fi%
\endgroup%
}%
\expandafter\gdef\csname\expandafter\@gobble\string#1@RJ\endcsname%
{%
\begingroup%
\let\relax\aftergroup% this has to be redefined before processing \csname @\string#1\endcsname
\ifx\aftergroup\relax% this is false in expandations
\expandafter\aftergroup\csname RJ@\expandafter\@gobble\string#1\endcsname%
\else%
\expandafter\aftergroup\expandafter\aftergroup\expandafter\aftergroup%
\expandafter\noexpand\csname\expandafter\@gobble\string#1@RJ\endcsname%
\fi%
\endgroup%
}%
% read the instructions (see \new@command)
\expandafter\new@command\csname RJ@\expandafter\@gobble\string#1\endcsname%
}%
%
\RJDeclareRobustCommand\bletter[1]{\textbf{#1}}
será robusto.
\xdef\boldyletter{\bletter{y}}
Funciona bien incluso en el comando \xdef\boldxyletter{x\boldyletter}}
.
Respuesta4
Muchas gracias por las respuestas tan útiles. También fueron un desafío para mí, que acepté con gusto.
Para utilizar un nuevo comando en el encabezado de un capítulo, es necesario, entre otras cosas, agregar y redefinir el comando en \pdfstringdef. Esto no se tuvo en cuenta en mi código anterior. Al agregar este requisito, también pude optimizar el código.
A continuación se muestra un ejemplo de prueba con el nuevo código. Los nuevos comandos, no sus argumentos, se ignorarán en los marcadores.
\documentclass[a4paper,12pt]{report}
\RequirePackage[pdftex,colorlinks,linkcolor=blue,%
urlcolor=blue,bookmarksnumbered]{hyperref}
%
\makeatletter
%
\let\RJ@aftergroup\aftergroup%
\let\RJ@begingroup\begingroup%
\let\RJ@endgroup\endgroup%
\let\RJ@let\let%
%
\@ifundefined{pdfstringdefPreHook}{}%
{%
\gdef\Addpdfstringdef#1%
{%
\global\@temptokena\expandafter%
{\pdfstringdefPreHook#1}%
\xdef\pdfstringdefPreHook{\the\@temptokena}%
}%
%
\Addpdfstringdef%
{%
\let\RJ@aftergroup\@empty%
\let\RJ@begingroup\@empty%
\let\RJ@endgroup\@empty%
\let\RJ@let\@empty%%
}%
}%
%
\def\RJ@DRCentry#1%
{%
\RJ@begingroup%
\RJ@let\relax\RJ@aftergroup%
\ifx\RJ@aftergroup\relax%
\expandafter\RJ@aftergroup\csname RJ@\expandafter\@gobble\string#1\endcsname%
\else%
\expandafter\noexpand\csname RJ\expandafter\@gobble\string#1JR\endcsname%
\fi%
\RJ@endgroup%
}%
%
\def\RJ@DeclareRobustCommand#1% #1 name of new command, #2 same instructions as \newcommand
{%
\gdef#1%
{%
\ifx\RJ@aftergroup\@empty%
\else%
\expandafter\RJ@DRCentry\expandafter#1%
\fi%
}%
%
\expandafter\gdef\csname RJ\expandafter\@gobble\string#1JR\endcsname%
{%
\ifx\RJ@aftergroup\relax%
\gdef\next{\RJ@DRCentry{#1}}%
\RJ@aftergroup\next%
\else%
\expandafter\noexpand\csname RJ\expandafter\@gobble\string#1JR\endcsname%
\fi%
}%
%
\@ifundefined{pdfstringdefPreHook}{}%
{%
\expandafter\Addpdfstringdef\expandafter%
{\expandafter\let\csname RJ\expandafter\@gobble\string#1JR\endcsname\@empty}%
}%
\expandafter\new@command\csname RJ@\expandafter\@gobble\string#1\endcsname%
}%
%
\RJ@DeclareRobustCommand\iletter[1]{\textit{\huge #1}}%
%
\xdef\yiletter{\iletter{y}}%
\xdef\xyiletter{\iletter{x}\yiletter}%
\xdef\xyziletter{\xyiletter\iletter{z}}%
\xdef\jiletter{\iletter{j\iletter{i}}}%
\begin{document}
\tableofcontents
\newpage
test \iletter{j\iletter{i}}, \jiletter{} test \iletter{a}, \yiletter, \xyiletter, \xyziletter{} test
\section{italic \iletter{y}, \xyziletter}
The following chapter heading is for comparison purposes only .
\section{italic \textit{\huge y}, \textit{\huge xyz}}
more text
\end{document}