Cómo usar @ifstar con argumentos

Cómo usar @ifstar con argumentos

Quiero usar @ifstarpara definir un comando, cuya versión sin estrella almacena un valor en una variable y cuya versión con estrella lee el valor de la variable. Intenté lo siguiente. No produce error, pero tampoco imprime el valor.

\def\sndname#1{\@ifstar\@sndname{\def\@sndname{#1}}}
\sndname{Hello U2}
\sndname*

Sé que puedo usar este patrón, pero ¿hay alguna manera de hacerlo de una sola línea?

\def\foo{\@ifstar\@foo\@@foo}
\def\@foo#1{...}
\def\@@foo#1{...}

Respuesta1

\documentclass{article}
\makeatletter
\def\sndname{\@ifstar\@sndname{\def\@sndname}}
\makeatother
\begin{document}
Set it \sndname{Hello U2}and use it \sndname*.
\end{document}

El truco es que no \sndnamelee el argumento sino \defel interior \sndname.

Respuesta2

Estás abusando de las pautas de sintaxis de LaTeX. La versión * de un comando generalmente debería tener los mismos argumentos obligatorios que la versión estándar.

Puedes usar un argumento opcional en su lugar:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\sndname}{o}
 {
  \IfNoValueTF{#1}
    {\tl_use:N \l_cocomore_sndname_tl}
    {\tl_set:Nn \l_cocomore_sndname_tl { #1 }}
 }
\tl_new:N \l_cocomore_sndname_tl
\ExplSyntaxOff

\begin{document}

\sndname[Hello U2]
\sndname

\end{document}

ingrese la descripción de la imagen aquí

Sin embargo, un mejor enfoque sería utilizar diferentes comandos para configurar la variable y usarla.

Respuesta3

Una adición a la respuesta de @egreg, que estoy de acuerdo tiene una mejor sintaxis, pero sin xparse. La versión comentada es una definición de estilo TeX del comando y la versión sin comentar es una definición de estilo LaTeX. En la definición de LaTeX, el argumento opcional solo puede tomar un valor predeterminado, aquí establecido en \empty, que luego se puede verificar en el código. Debería funcionar siempre y cuando no esté cargado con \empty. Los puntos alrededor de los comandos cuando se usan son solo para verificar que no se agreguen espacios adicionales. (En realidad, la versión LaTeX probablemente pueda verse como una sola línea, pero es más legible así :-)

\documentclass{article}
%%%% TeX style definition
% \makeatletter
% \def\sndname{\@ifnextchar[\opt@sndname\@sndnamevar}
% \def\opt@sndname[#1]{\def\@sndnamevar{#1}}
% \makeatother

%%%% LaTeX style definition
\newcommand\sndname[1][\empty]{%
  \ifx#1\empty
    \sndnamevar
  \else
    \def\sndnamevar{#1}%
  \fi}

%%%% Load with nothing (just in case \sndname is used before loaded)
\sndname[]
%%%%
\begin{document}
Load: .\sndname[Name of snd].

Print: .\sndname.

\end{document}

información relacionada