逐行读取 \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为空。这完全取决于您想对环境的内容做什么。

在此处输入图片描述

相关内容