Nachteile der csname-Methode zur Vermeidung von Leerzeichen nach dem Befehl

Nachteile der csname-Methode zur Vermeidung von Leerzeichen nach dem Befehl

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 \relaxeinfü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 ipwü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 xals 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 \protectedvor 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}

verwandte Informationen