
我正在嘗試創建一個新環境並將其用作自訂數組(對給定的程式碼進行了許多更改)。所以我需要閱讀\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
為空。這完全取決於您想如何處理環境內容。