Inconvenientes del método csname para evitar espacios después del comando

Inconvenientes del método csname para evitar espacios después del comando

Tuve un problema similar a este:Espacio después de los comandos LaTeX

Mi primer intento fue algo como esto:

\newcommand{\satip}{SAT\textgreater IP}

Esto lleva al problema conocido de que los espacios después del comando se consumen:

\satip is a cool Protocol. %Produces: SAT>IPis a cool Protocol.
                             space missing ^^^

Busqué y encontré la pregunta mencionada. Las soluciones proporcionadas ayudaron mucho, pero no estaba completamente satisfecho con ninguna de ellas. \satip/Simplemente se ve un poco extraño en un documento de látex, me gusta \satip{}mucho más. Es solo que, si olvido poner {}detrás el comando, falta el espacio en la salida. Por lo tanto, me gustaría recibir un error si lo uso incorrectamente.

Solución posible:

\def\satip#{SAT\textgreater IP}
%\satip is a cool Protocol. %doesn't compile, error

De esta manera se aplica la llave abierta, pero las llaves pueden contener algo:

\satip{is} a cool Protocol.

Esto se compila bien, pero como no tiene ningún sentido, me gustaría que produjera un error. Mi forma actual de manejar el problema es la siguiente:

\expandafter\def\csname satip{}\endcsname \relax{SAT\textgreater IP}
\def\satip#1{\csname satip{}\endcsname #1\relax}

%\satip{is} a cool Protocol. %Use of \satip{} doesn't match its definition.
%\satip is a cool Protocol. %Use of \satip{} doesn't match its definition.
\satip{} is a cool Protocol. %works

Ahora mi pregunta:

Esta Macro necesita un segundo paso de expansión. ¿Eso podría causar algún problema? ¿Hay otros problemas? (Como no había encontrado esto en ningún lado antes).

PD: Perdón por el mal título, no se me ocurrió nada mejor. Siéntete libre de editar.

Respuesta1

Siempre puedes usar

\newcommand*\satip{SAT\textgreater IP}
\satip{} is a cool protocol

No veo el problema.


Por cierto, su última definición define la macro con nombre satip{}(llavesincluidoen el nombre de la macro) seguido de un \relaxtoken. Si coloca el #1valor entre \endcsnamey \relaxen la \satipmacro, solo puede funcionar si #1está vacío (es decir, solo si se dan llaves vacías \satip{} is...).


¿Puede ser que esto logre lo que desea?

\newcommand*\satip[1]
 {\if\relax\detokenize{#1}\relax
    SAT\textgreater IP%
  \else
    \GenericError{} % <- I don't know what this argument does
       {Wrong use of \string\satip{}.} % <- short version
       {Wrong use of \string\satip. You must use \string\satip\space followed by an empyt argument `{}'.}% <- long version
  \fi}

Respuesta2

No lo usaría {}en el nombre de la macro auxiliar, pero el método es sólido:

\newcommand{\satip}[1]{\csname satip\string+\endcsname #1\relax}
\expandafter\def\csname satip\string+\endcsname\relax{%
  SAT\textgreater IP%
}

activará un error en caso de que \satip{x}se utilice

! Use of \satip+ doesn't match its definition.
<argument> x

Sin embargo, \satip ipno lo haría. Deberías hacerdospasos:

\newcommand{\satip}{}% initialize
\protected\def\satip#{\csname satip\string+\endcsname}
\expandafter\def\csname satip\string+\endcsname#1{%
  \csname satip\string+\string+\endcsname #1\relax
}
\expandafter\def\csname satip\string+\string+\endcsname\relax{%
  SAT\textgreater IP%
}

Ahora ambos \satip xy \satip{x}provocarían errores:

! Use of \satip doesn't match its definition.
l.14 \satip x

? 
! Use of \satip++ doesn't match its definition.
<argument> x

l.16 \satip{x}

? 

Tenga en cuenta \protecteddelante de la definición de \satip, para que no se expanda en contextos de "argumentos en movimiento".

Una versión abstracta:

\documentclass{article}

\makeatletter
\newcommand\definestringcommand[2]{%
  \@ifdefinable#1{\@definestringcommand#1{#2}}%
}

\newcommand{\@definestringcommand}[2]{%
  \begingroup
  \escapechar=\m@ne % get rid of the backslash
  % require brace
  \protected\xdef#1##{\expandafter\noexpand\csname\string#1\string+\endcsname}%
  % examine the argument
  \expandafter\xdef\csname\string#1\string+\endcsname##1{%
    \expandafter\noexpand\csname\string#1\string+\string+\endcsname##1\relax
  }%
  \expandafter\gdef\csname\string#1\string+\string+\endcsname\relax{#2}%
  \endgroup
}
\makeatother

\definestringcommand{\satip}{SAT\textgreater IP}

\begin{document}

\satip is nice

\satip{x} is nice

\satip{} is nice

\end{document}

Si esto es útil, te dejo la decisión a ti.

Una implementación diferente: verifique el {, luego verifique que haya seguidores }que se coman ambos tokens en caso de éxito.

\documentclass{article}

\makeatletter
\newcommand\definestringcommand[2]{%
  \@ifdefinable#1{\@definestringcommand#1{#2}}%
}

\newcommand{\@definestringcommand}[2]{%
  \begingroup
  \escapechar=\m@ne % get rid of the backslash
  % require brace
  \protected\xdef#1##{%
    \expandafter\noexpand\csname\string#1\string+\endcsname
  }%
  \expandafter\gdef\csname\string#1\string+\endcsname{%
    #2%
    \afterassignment\@checkrightbrace\let\@forget= % the space counts
  }
  \endgroup
}
\newcommand{\@checkrightbrace}{%
  \@ifnextchar\egroup{\let\@forget= }{\@strcmderr\let\@forget= }%
}
\newcommand{\@strcmderr}{%
  \@latex@error{Non empty group}{The braces must contain nothing}%
}
\makeatother

\definestringcommand{\satip}{SAT\textgreater IP}

\begin{document}

\satip is nice

\satip{x} is nice

\satip{} is nice

\end{document}

información relacionada