
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 \BODY
und \NewEnviron
zwar 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 \BODY
und nicht Zeile für Zeile. Auch wenn ich einen Zeilenumbruch einfüge, ist das #1
von \StrLen
kein 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 listofitems
Paket zum Parsen \BODY
unter 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}
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}
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 \BODY
leer ist. Es hängt alles davon ab, was Sie mit dem Inhalt der Umgebung tun möchten.