Прочитайте построчно содержимое \NewEnviron, включая "\\"

Прочитайте построчно содержимое \NewEnviron, включая "\\"

Я пытаюсь создать новую среду и использовать ее как настраиваемый массив (со многими изменениями в приведенном коде). Поэтому мне нужно прочитать из \BODYи \NewEnvironпрочитать его построчно. Мне все равно, нужно ли мне заканчивать строки с помощью \\или пустой строки или как-то еще. Но мне нужно прочитать их одну за другой, и я не знаю, сколько там строк, прежде чем использовать среду.

Я попробовал это:

\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} 

Но использует все \BODYи не построчно. Также если я добавляю перенос строки, то #1из \StrLenбольше не является строкой (содержит перенос строки и выдает ошибки).

Мне наконец-то удалось занять первую строчку в моей новой среде, используя код @Bruno Le Floch изздесьно я не очень понимаю этот код и не знаю, что читать, чтобы понять его и изменить для принятия всех аргументов. Также я пока не могу добавить \ в конце строк, чтобы показать, где заканчивается строка массива... Вот что у меня сейчас:

\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}

Любая помощь будет оценена по достоинству. Результат, который я хочу получить, — это взять в качестве аргументов строки в среде. (Я не знаю, сколько строк будет в массиве. Поэтому не указывайте конкретное количество аргументов в новой среде).

решение1

Здесь используется мощный listofitemsпакет для анализа \BODYс использованием \\разделителей.

\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}

введите описание изображения здесь

А это показывает, как можно дополнительно разобрать каждую строку, слово за словом, используя пробел в качестве разделителя второго уровня:

\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}

введите описание изображения здесь

решение2

Если вас не волнует, заканчиваются ли строки символом \\(что безопаснее, чем возиться с \endlinechar), то с . все очень просто 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}

Я использовал фиктивное действие для выполнения в каждой строке, просто в качестве примера. Показано, что проверка на пустоту полезна в случае, если последняя строка заканчивается на \\. Есть и другие возможности: можно просто проверить, является ли последний элемент в последовательности, полученной из , \BODYпустым. Все зависит от того, что вы хотите сделать с содержимым среды.

введите описание изображения здесь

Связанный контент