Liest zeilenweise den Inhalt von \NewEnviron, einschließlich "\\".

Liest zeilenweise den Inhalt von \NewEnviron, einschließlich "\\".

Ich versuche, eine neue Umgebung zu erstellen und sie als angepasstes Array zu verwenden (mit vielen Änderungen im angegebenen Code). Ich muss also die Umgebung lesen \BODYund \NewEnvironzwar Zeile für Zeile. Es ist mir egal, ob ich die Zeilen mit oder mit einer leeren Zeile oder was auch immer beenden muss \\. Aber ich muss sie einzeln lesen und weiß nicht, wie viele Zeilen es gibt, bevor ich die Umgebung verwende.

Ich habe Folgendes versucht:

\documentclass{article}
\usepackage{environ}
\usepackage{xstring}

\makeatletter
\long\def\findLength#1{\StrLen{#1}[\temp] The length of ``#1'' is \temp\\}
\NewEnviron{Graph}{\findLength{\BODY}}{}
\makeatother




\begin{document}

  \begin{Graph}
     test line 1 

     test line 2
  \end{Graph}

\end{document} 

Verwendet aber alles \BODYund nicht Zeile für Zeile. Auch wenn ich einen Zeilenumbruch einfüge, ist das #1von \StrLenkein String mehr (enthält Zeilenumbrüche und gibt Fehler aus).

Ich habe es endlich geschafft, die erste Zeile in meiner neuen Umgebung mit dem Code von @Bruno Le Floch zu übernehmenHieraber ich verstehe den Code nicht wirklich und weiß nicht, was ich lesen muss, um ihn zu verstehen und ihn so zu ändern, dass er alle Argumente übernimmt. Außerdem kann ich am Ende der Zeilen noch kein \ hinzufügen, um anzuzeigen, wo die Zeile des Arrays endet... Hier ist, was ich jetzt habe:

\documentclass{article}
\usepackage{environ}% defines `NewEnviron`
\usepackage{xstring}

\makeatletter
\newcommand*{\newlinecommand}[2]{%
  \newcommand*{#1}{%
    \begingroup%
    \escapechar=`\\%
    \catcode\endlinechar=\active%
    \csname\string#1\endcsname%
  }%
  \begingroup%
  \escapechar=`\\%
  \lccode`\~=\endlinechar%
  \lowercase{%
    \expandafter\endgroup
    \expandafter\def\csname\string#1\endcsname##1~%
  }{\endgroup#2\par\space}%
}
\makeatother

\makeatletter
\newlinecommand{\findLengthOfRow}{\StrLen{#1}[\temp] The length of ``#1'' is \temp}
\makeatother


\makeatletter
\long\def\findLength#1{\findLengthOfRow{#1}}
\newenvironment{Graph}{\findLength}{}
\makeatother




\begin{document}

  \begin{Graph}
     test line 1  
     test line 2    
     test line 3 
  \end{Graph}

\end{document}

Jede Hilfe ist willkommen. Das gewünschte Ergebnis ist, die Zeilen in der Umgebung als Argumente zu verwenden. (Ich weiß nicht, wie viele Zeilen das Array haben wird. Geben Sie in der neuen Umgebung also keine bestimmte Anzahl von Argumenten an.)

Antwort1

Hierbei wird das leistungsstarke listofitemsPaket zum Parsen \BODYunter Verwendung von \\Trennzeichen verwendet.

\documentclass[12pt]{article}
\usepackage{listofitems,environ}
\NewEnviron{linebyline}{%
  \setsepchar{\\}%
  \readlist*\mylines{\BODY}%
  \foreachitem\x\in\mylines{Line \xcnt: \x\par}%
  The total number of lines is \textbf{\listlen\mylines[]}.
}
\begin{document}
\begin{linebyline}
This is a test\\
of whether\\
I can identify line by line.
\end{linebyline}
\end{document}

Bildbeschreibung hier eingeben

Und hier sehen Sie, wie jede Zeile Wort für Wort weiter unterteilt wird, wobei ein Leerzeichen als Trennzeichen der zweiten Ebene verwendet wird:

\documentclass[12pt]{article}
\usepackage{listofitems,environ}
\NewEnviron{linebyline}{%
  \setsepchar{\\/ }%
  \readlist*\mylines{\BODY}%
  \foreachitem\x\in\mylines{Line \xcnt: \x{} (has \listlen\mylines[\xcnt] words,
    first/last: ``\mylines[\xcnt,1]/\mylines[\xcnt,-1]'')\par}%
  The total number of lines is \textbf{\listlen\mylines[]}.
}
\begin{document}
\begin{linebyline}
This is a test\\
of whether\\
I can identify line by line.
\end{linebyline}
\end{document}

Bildbeschreibung hier eingeben

Antwort2

Wenn es Ihnen egal ist, ob Zeilen mit beendet werden \\(was sicherer ist, als mit herumzuspielen \endlinechar), ist es mit wirklich einfach expl3.

\documentclass{article}
\usepackage{xparse,environ}

\ExplSyntaxOn
\NewEnviron{Graph}
 {
  % split the environment's contents into items at the \\ separator
  \seq_set_split:NnV \l_koleygr_graph_lines_seq { \\ } \BODY
  \begin{enumerate}
  % map over the sequence, passing each item to the internal function
  \seq_map_function:NN \l_koleygr_graph_lines_seq \koleygr_graph_doline:n
  \end{enumerate}
 }

\cs_new_protected:Nn \koleygr_graph_doline:n
 {
  \tl_if_empty:nF { #1 }
   {
    \item #1
   }
 }
\ExplSyntaxOff

\begin{document}

Something at the top
\begin{Graph}
Line 1\\
Line 2\\
Line 3
\end{Graph}
Something in between
\begin{Graph}
Line 1\\
Line 2\\
Line 3\\
\end{Graph}
Something at the bottom

\end{document}

Ich habe nur als Beispiel eine Dummy-Aktion verwendet, die auf jede Zeile angewendet wird. Die Prüfung auf Leere erweist sich als nützlich, wenn die letzte Zeile mit endet \\. Es gibt noch andere Möglichkeiten: Man kann einfach prüfen, ob das letzte Element in der aus erhaltenen Sequenz \BODYleer ist. Es hängt alles davon ab, was Sie mit dem Inhalt der Umgebung tun möchten.

Bildbeschreibung hier eingeben

verwandte Informationen