逐行讀取 \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為空。這完全取決於您想如何處理環境內容。

在此輸入影像描述

相關內容