\newcommand для ввода переменных среды

\newcommand для ввода переменных среды

Я делаю концертные программы для своих студенческих выступлений, используя класс ConcProg. В песнях много повторений, поэтому я хотел бы создать стенографию.

Так что вместо этого

\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
    \end{composition}

Что-то вроде этого.

\newcommand{\twinkle}{{Folk Song}{}{Twinkle Twinkle Little Star}}
\newcommand{\studentname}{{Student Name}}

\begin{composition}\twinkle\studentname
    \end{composition}

Однако, \newcommand, похоже, любит только несколько наборов скобок, когда они используются для аргументов для этой конкретной новой команды. Насколько я могу судить, он игнорирует отдельные скобки {т. е. скобки, не связанные с аргументами для этой конкретной \newcommand или команд, размещенных внутри \newcommand}. В случае этой пользовательской среды он выдает ошибку.

Ниже приведен еще один пример (не использующий пользовательскую среду).

%standard input 
\newcommand{\wbalTwo}[2] {
  This is the Wikibook about LaTeX
  supported by #1 and #2}
\item \wbalTwo{John Doe}{Anthea Smith}
%trying to use new command to input args. In this instance, it seems to ignore the internal braces and treats both internally-braced items as a single text string. 
\newcommand{\wbalTwo}[2] {
  This is the Wikibook about LaTeX
  supported by #1 and #2}
\newcommand{\passargs}

Так есть ли простой способ добиться того, чтобы они имели одинаковый результат?

решение1

Из того, что вы нам рассказали до сих пор, следует, что воспроизвести проблему невозможно, и поэтому отслеживание/выявление источника проблемы в некоторой степени связано с догадками.

Сначала несколько общих замечаний — надеюсь, мои догадки верны и мои замечания окажутся полезными:

  1. Во время сбора аргументов для макросов или сред из потока токенов расширениенетсработало.
  2. В случае его наличия (La)TeX удалит самый внешний уровень фигурных скобок, которые окружаютвесьаргумент при вставке этого аргумента в текст замены во время расширения.

После «выкапывания» класса ConcProg на CTAN (https://ctan.org/pkg/concprog), я обнаружил, что среда compositionобрабатывает четыре аргумента:

  1. ⟨автор⟩
  2. ⟨годы рождения (и смерти)⟩
  3. ⟨название композиции⟩
  4. ⟨необязательное описание⟩

Таким образом с

\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
⟨whatsoever environment-body⟩
\end{composition}
  • первый аргумент -environment compositionбудет: Folk Song,
  • второй аргумент -environment compositionбудет пустым,
  • третий аргумент -окружения compositionбудет: Twinkle Twinkle Little Star,
  • четвертый аргумент -окружения compositionбудет: Student Name,

в то время как с

\begin{composition}\twinkle\studentname
\end{composition}
  • первый аргумент -environment compositionбудет: \twinkle,
  • второй аргумент -окружения compositionбудет \studentname,
  • третий аргумент -окружения compositionбудет: \end,
  • четвертым аргументом -environment compositionбудет: composition.

Это потому, что расширениенетсрабатывает, когда LaTeX собирает аргументы для макросов или сред.

В зависимости от того, как вставляются аргументы, когда LaTeX выполняет/раскрывает макросы, лежащие в основе compositionсреды, такой способ извлечения аргументов может привести к разного рода странному/ошибочному/проблемному поведению.

Я могу предложить настроенный вариант -environment composition, называемый mycomposition, который отвечает за расширение:

На самом деле среда вообще не обрабатывает никаких аргументов. Вместо этого она проверяет, является ли следующий токен в ее теле среды расширяемым или нет. Если это так, расширение будет происходить до тех пор, пока не будет найден нерасширяемый токен. (Помните, что фигурные открывающиеся скобки {не являются расширяемыми токенами. ;-)) Затем она захватит аргумент. Она делает это четыре раза для захвата 4 аргументов. Затем внутренне она передает эти четыре аргумента макросу, лежащему в основе -environment composition:

\documentclass{ConcProg}

\makeatletter
\newcommand\UD@CheckWhetherNextExpandable[2]{%
  \def\UD@reserved@a{#1}%
  \def\UD@reserved@b{#2}%
  \UD@@CheckWhetherNextExpandable
}%
\newcommand\UD@@CheckWhetherNextExpandable{%
  \futurelet\UD@reserved@c\UD@@@CheckWhetherNextExpandable
}%
\newcommand\UD@@@CheckWhetherNextExpandable{%
  \ifx\UD@reserved@c\@sptoken\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\afterassignment\UD@@CheckWhetherNextExpandable\let\UD@reserved@c= }%
  {%
    \expandafter\ifx\noexpand\UD@reserved@c\UD@reserved@c
      \expandafter\UD@reserved@b
    \else
      \expandafter\UD@reserved@a
    \fi
  }%
}%
\newcommand\UD@ExpandUntilFirstUnexpandableAndAddToUD@reserved@d[1]{%
   \ifx\relax#1\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
   {\expandafter\endgroup\UD@reserved@d}%
   {\UD@CheckWhetherNextExpandable
      {\expandafter\UD@@CheckWhetherNextExpandable}%
      {\expandafter\UD@AddNextTo\expandafter{\@gobble#1}\UD@reserved@d}%
   }%
}%
\newcommand\UD@AddNextTo[3]{%
  % \edef..\the\toks@-route prevents halving of hashes.
  \toks@\expandafter{#2{#3}}%
  \edef#2{\the\toks@}%
  \UD@ExpandUntilFirstUnexpandableAndAddToUD@reserved@d{#1}%
}%
\newcommand\UD@ExpandAndAccumulateKArgsAndPassTo[2]{%
  \begingroup
  \def\UD@reserved@d{#2}%
  \expandafter\UD@ExpandUntilFirstUnexpandableAndAddToUD@reserved@d
  \expandafter{\romannumeral\number\number#1 000}%
}%
\newenvironment{mycomposition}%
               {\UD@ExpandAndAccumulateKArgsAndPassTo{4}{\composition}}%
               {\endcomposition}%
\makeatother


\newcommand{\twinkle}{{Folk Song}{}{Twinkle Twinkle Little Star}}
\newcommand{\studentname}{{Student Name}}


\begin{document}

\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}%
environment body
\end{composition}

\begin{mycomposition} \twinkle\studentname
environment body
\end{mycomposition}

\begin{mycomposition} \twinkle {Student Name}
environment body
\end{mycomposition}

\begin{mycomposition} {Folk Song}{}{Twinkle Twinkle Little Star} \studentname
environment body
\end{mycomposition}

\begin{mycomposition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
environment body
\end{mycomposition}

\end{document}

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

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