
Ich erstelle Konzertprogramme für meine Schülervorträge mithilfe der Klasse ConcProg. Die gespielten Lieder wiederholen sich häufig, deshalb möchte ich eine Kurzschrift erstellen.
Also statt diesem
\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
\end{composition}
Etwas wie das.
\newcommand{\twinkle}{{Folk Song}{}{Twinkle Twinkle Little Star}}
\newcommand{\studentname}{{Student Name}}
\begin{composition}\twinkle\studentname
\end{composition}
Allerdings scheint \newcommand mehrere Klammern nur zu mögen, wenn sie für Argumente für diesen bestimmten neuen Befehl verwendet werden. Soweit ich das beurteilen kann, ignoriert es alleinstehende Klammern {d. h. Klammern, die nichts mit Argumenten für diesen bestimmten \newcommand oder Befehlen innerhalb des \newcommands zu tun haben}. In dieser benutzerdefinierten Umgebung wird ein Fehler ausgegeben.
Es folgt ein weiteres Beispiel (das keine benutzerdefinierte Umgebung verwendet).
%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}
Gibt es also eine einfache Möglichkeit, die gleiche Ausgabe zu erzielen?
Antwort1
Nach Ihren bisherigen Angaben lässt sich das Problem nicht reproduzieren und daher ist die Suche nach der Problemquelle bis zu einem gewissen Grad mit Rätselraten verbunden.
Zunächst einige allgemeine Bemerkungen – ich hoffe, dass meine Vermutungen richtig sind und meine Bemerkungen nützlich sind:
- Beim Sammeln von Argumenten für Makros oder Umgebungen aus dem Token-Stream ist die ErweiterungnichtAusgelöst.
- Falls vorhanden, entfernt (La)TeX die äußerste Ebene geschweifter Klammern, die eingesamteArgument, wenn dieses Argument während der Erweiterung in den Ersetzungstext eingefügt wird.
Nach dem "Ausgraben" der ConcProg-Klasse auf CTAN (https://ctan.org/pkg/concprog) habe ich festgestellt, dass die Umgebung composition
vier Argumente verarbeitet:
- ⟨Autor⟩
- ⟨Geburts- (und Sterbejahr)⟩
- ⟨Titel der Komposition⟩
- ⟨optionale Beschreibung⟩
Also mit
\begin{composition}{Folk Song}{}{Twinkle Twinkle Little Star}{Student Name}
⟨whatsoever environment-body⟩
\end{composition}
- das erste Argument der
composition
-Umgebung wird sein:Folk Song
, - das zweite Argument der
composition
-Umgebung wird leer sein, - das dritte Argument der
composition
-Umgebung wird sein:Twinkle Twinkle Little Star
, - das vierte Argument der
composition
-Umgebung wird sein:Student Name
,
während mit
\begin{composition}\twinkle\studentname
\end{composition}
- das erste Argument der
composition
-Umgebung wird sein:\twinkle
, - Das zweite Argument der
composition
-Umgebung wird sein\studentname
, - das dritte Argument der
composition
-Umgebung wird sein:\end
, - Das vierte Argument der
composition
-Umgebung lautet:composition
.
Dies liegt daran, dass die Expansionnichtwird ausgelöst, wenn LaTeX Argumente für Makros oder Umgebungen sammelt.
Je nachdem, wie die Argumente eingefügt werden, wenn LaTeX die der -Umgebung zugrunde liegenden Makros ausführt/erweitert composition
, kann diese Art des Abrufens von Argumenten zu allen möglichen seltsamen/fehlerhaften/problematischen Verhaltensweisen führen.
Ich kann eine angepasste Variante der composition
-Umgebung namens anbieten mycomposition
, die sich um die Erweiterung kümmert:
Tatsächlich verarbeitet die Umgebung überhaupt keine Argumente. Stattdessen prüft sie, ob das nächste Token in ihrem Umgebungskörper erweiterbar ist oder nicht. Wenn dies der Fall ist, wird die Erweiterung durchgeführt, bis ein nicht erweiterbares Token gefunden wird. (Beachten Sie, dass geschweifte öffnende Klammern {
keine erweiterbaren Token sind. ;-)) Dann wird ein Argument erfasst. Dies wird viermal durchgeführt, um 4 Argumente zu erfassen. Dann werden diese vier Argumente intern an das der Umgebung zugrunde liegende Makro übergeben 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}