Как использовать @ifstar с аргументами

Как использовать @ifstar с аргументами

Я хочу использовать @ifstarдля определения команды, чья не-звездочная версия сохраняет значение в переменной, а чья звездочная версия считывает значение из переменной. Я попробовал следующее. Это не выдает ошибку, но и не выводит значение.

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

Я знаю, что могу использовать этот шаблон, но есть ли способ сделать это в одну строку?

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

решение1

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

Фокус в том, что он \sndnameчитает не аргумент, а то, что \defвнутри \sndname.

решение2

Вы злоупотребляете правилами синтаксиса LaTeX. *-версия команды обычно должна иметь те же обязательные аргументы, что и стандартная версия.

Вместо этого вы можете использовать необязательный аргумент:

\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}

введите описание изображения здесь

Однако лучшим подходом было бы использование разных команд для установки переменной и для ее использования.

решение3

Дополнение к ответу @egreg, который, как я согласен, имеет лучший синтаксис, но без xparse. Закомментированная версия — это определение команды в стиле TeX, а незакомментированная — это определение в стиле LaTeX. В определении LaTeX необязательный аргумент может принимать только значение по умолчанию, здесь установлено значение \empty, которое затем можно проверить в коде. Это должно работать, пока оно не загружено с \empty. Точки вокруг команд при использовании нужны только для проверки того, что не добавляются лишние пробелы. (На самом деле, версию LaTeX, вероятно, можно рассматривать как однострочную, но так ее удобнее читать:-)

\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}

Связанный контент