Sorgen Sie dafür, dass xparse bei optionalen Argumenten kein Zeilenendezeichen verschlingt.

Sorgen Sie dafür, dass xparse bei optionalen Argumenten kein Zeilenendezeichen verschlingt.

Bei der Verwendung xparsezum Definieren einer neuen Umgebung mit einem optionalen Argument O{}wird das erste Zeilenendezeichen weggelassen, wie im folgenden Beispieldokument zu sehen ist:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Npn \__my_end_of_line: { X }

\NewDocumentEnvironment{mycode}{ !O{} }{
    \char_set_catcode_active:N \^^M
    \char_set_active_eq:nN {`\^^M} \__my_end_of_line:
}{}
\ExplSyntaxOff

\begin{document}
\begin{mycode}
abc
\end{mycode}
\end{document}

welche Ausgänge

abcX

wo ich erwarten würde

XabcX

Es gibt bereitsdiese Fragewas ähnlich ist, aber keine aktiven Zeichen verwendet. Auch die Kommentare in dieser Frage helfen hier nicht weiter. Weder funktioniert es, dem Argumentspezifizierer mit das Präfix zu geben, !noch funktioniert es in einer neueren xparseVersion (meine Version ist xparse 2019-05-28).

Gibt es eine Möglichkeit, dieses Problem zu umgehen?


BEARBEITEN:Mein Anwendungsfall ist eine spezielle, wörtliche Umgebung mit einigen optionalen Einstellungen am Anfang. Das Problem besteht darin, dass ich weiterlesen muss, bis ich das Ende der ersten Zeile finde bzw. die erste Zeile, in der ^^Malles verworfen werden muss, was in dieser Zeile steht (normalerweise ist sie leer). Dies funktioniert einwandfrei, wenn ein optionales Argument vorhanden ist, aber ohne ein optionales Argument wird die erste tatsächliche Codezeile als die zu verwerfende Zeile betrachtet, was unerwünscht ist.

Antwort1

Wie gewünscht, mein schnelles Modell als Antwort. Sie sollten zuerst die Kategoriecodes ändern, bevor Sie nach dem Vorhandensein des optionalen Arguments suchen, es dann für das Erfassen des Arguments zurückschalten und die Catcodes für die tatsächliche Umgebung zurücksetzen.

Das folgende Beispiel greift recht einfach auf das optionale Argument zu, wie es in LaTeX2e gemacht wird, aber es ist schlechter als ein O{}Argument von xparse, da es keinen Klammerausgleich gibt. Sie können das umgehen, indem Sie ein verwenden \NewDocumentCommand \__mycode_parse_arg:w { !O{} } { ... }, aber \NewDocumentCommandes sollte nicht für Makros auf Codeebene verwendet werden (daher der Name).

Ich habe das optionale Argument so eingerichtet, dass es die Definition von ändert \__mycode_end_of_line:, nur um zu zeigen, dass es funktioniert.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Npn \__mycode_end_of_line: { X }
\cs_new_protected:Npn \__mycode_real_begin:
  {
    \__mycode_catcode_setup:
    \char_set_active_eq:nN { `\^^M } \__mycode_end_of_line:
  }
\cs_new_protected:Npn \__mycode_parse_arg:w [ #1 ]
  {
    % do whatever with the optional argument
    \cs_set_protected:Npn \__mycode_end_of_line: { #1 }
    \__mycode_real_begin:
  }
\cs_new_protected:Npn \__mycode_catcode_setup:
  {
    \char_set_catcode_active:N \^^M
  }
\NewDocumentEnvironment { mycode } {}
  {
    \group_begin:
    \__mycode_catcode_setup:
    \peek_meaning:NTF [
      {
        \group_end:
        \__mycode_parse_arg:w
      }
      {
        \group_end:
        \__mycode_real_begin:
      }
  }
  {}
\ExplSyntaxOff

\begin{document}
\begin{mycode}
abc
\end{mycode}

\begin{mycode}[Y]
abc
\end{mycode}
\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen