Leia linha por linha o conteúdo de \NewEnviron incluindo "\\"

Leia linha por linha o conteúdo de \NewEnviron incluindo "\\"

Estou tentando criar um novo ambiente e usá-lo como um array customizado (com muitas alterações no código fornecido). Então eu preciso ler o \BODYe \NewEnvironler linha por linha. Não me importo se tenho que terminar as linhas com \\ou com linha vazia ou algo assim. Mas tenho que lê-los um por um e não sei quantas linhas tem antes de usar o ambiente.

Eu tentei isso:

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

Mas usa tudo \BODYe não linha por linha. Além disso, se eu adicionar uma quebra de linha, #1of \StrLennão será mais uma string (contém quebra de linha e apresenta erros).

Finalmente consegui pegar a primeira linha do meu novo ambiente usando o código do @Bruno Le Floch deaquimas eu realmente não entendo esse código e não sei o que ler para entendê-lo e alterá-lo para receber todos os argumentos. Além disso, ainda não consigo adicionar \ no final das linhas para mostrar onde termina a linha do array... Aqui está o que tenho agora:

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

Qualquer ajuda será apreciada. O resultado que desejo é tomar como argumentos as linhas do ambiente. (Não sei quantas linhas o array terá. Portanto, não forneça um número específico de argumentos no novo ambiente).

Responder1

Isso usa o listofitemspacote poderoso para analisar o \BODY, usando \\separadores.

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

insira a descrição da imagem aqui

E isso mostra como subanalisar cada linha, palavra por palavra, usando um espaço como separador de segunda camada:

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

insira a descrição da imagem aqui

Responder2

Se você não se importa se as linhas terminam com \\(o que é mais seguro do que brincar com \endlinechar), é realmente simples com 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}

Usei uma ação fictícia para ser executada em cada linha, apenas a título de exemplo. A verificação de vazios mostra-se útil caso a última linha termine com \\. Existem outras possibilidades: pode-se simplesmente verificar se o último item da sequência obtida \BODYestá vazio. Tudo depende do que você quer fazer com o conteúdo do ambiente.

insira a descrição da imagem aqui

informação relacionada