Ich hatte ein ähnliches Problem wie dieses:Leerzeichen nach LaTeX-Befehlen
Mein erster Versuch war ungefähr so:
\newcommand{\satip}{SAT\textgreater IP}
Dies führt zu dem bekannten Problem, dass Leerzeichen nach dem Befehl aufgefressen werden:
\satip is a cool Protocol. %Produces: SAT>IPis a cool Protocol.
space missing ^^^
Ich habe herumgesucht und die erwähnte Frage gefunden. Die bereitgestellten Lösungen haben mir sehr geholfen, aber ich war mit keiner davon ganz zufrieden. \satip/
Sieht in einem Latex-Dokument einfach ein bisschen komisch aus, gefällt mir \satip{}
viel besser. Es ist nur so, dass, wenn ich vergesse, hinter den Befehl zu setzen {}
, das Leerzeichen in der Ausgabe fehlt. Deshalb möchte ich eine Fehlermeldung erhalten, wenn ich es falsch verwende.
Mögliche Lösung:
\def\satip#{SAT\textgreater IP}
%\satip is a cool Protocol. %doesn't compile, error
Auf diese Weise wird die öffnende Klammer erzwungen, die Klammern können jedoch etwas enthalten:
\satip{is} a cool Protocol.
Das lässt sich zwar gut kompilieren, aber da es keinen Sinn ergibt, möchte ich, dass es einen Fehler erzeugt. Meine derzeitige Vorgehensweise bei der Problembehandlung ist folgende:
\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
Nun meine Frage:
Dieses Makro benötigt einen zweiten Erweiterungsschritt. Könnte das Probleme verursachen? Gibt es noch andere Probleme? (Da ich das bisher nirgends gefunden habe.)
PS: Entschuldigen Sie den schlechten Titel, mir ist nichts Besseres eingefallen. Sie können ihn gerne bearbeiten.
Antwort1
Sie können immer verwenden
\newcommand*\satip{SAT\textgreater IP}
\satip{} is a cool protocol
Ich sehe das Problem nicht.
Übrigens definiert Ihre letzte Definition das Makro mit Namen satip{}
(Klammerninbegriffenim Makronamen), gefolgt von einem Token. Wenn Sie das zwischen und im Makro \relax
einfügen, kann es nur funktionieren, wenn leer ist (also nur, wenn leere Klammern angegeben sind ).#1
\endcsname
\relax
\satip
#1
\satip{} is...
Vielleicht erreichen Sie damit, was Sie wollen?
\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}
Antwort2
{}
Ich würde es nicht im Namen des Hilfsmakros verwenden , aber die Methode ist solide:
\newcommand{\satip}[1]{\csname satip\string+\endcsname #1\relax}
\expandafter\def\csname satip\string+\endcsname\relax{%
SAT\textgreater IP%
}
löst einen Fehler aus, wenn \satip{x}
verwendet wird
! Use of \satip+ doesn't match its definition.
<argument> x
Aber das \satip ip
würde ich nicht. Sie solltenzweiSchritte:
\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%
}
Nun würden sowohl \satip x
als auch Fehler auslösen:\satip{x}
! 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}
?
Beachten Sie \protected
vor der Definition von \satip
, damit es im Kontext von „beweglichen Argumenten“ nicht erweitert wird.
Eine abstrakte Version:
\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}
Ob dies sinnvoll ist, überlasse ich Ihrer Entscheidung.
Eine andere Implementierung: Suchen Sie nach dem {
, und suchen Sie dann nach einem , das }
im Erfolgsfall beide Token verbraucht.
\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}