
Estoy intentando crear un nuevo entorno y usarlo como una matriz personalizada (con muchos cambios en el código proporcionado). Entonces necesito leer el \BODY
y \NewEnviron
leerlo línea por línea. No me importa si tengo que terminar las líneas con \\
o con línea vacía o lo que sea. Pero tengo que leerlos uno por uno y no sé cuántas líneas hay antes de utilizar el entorno.
Probé esto:
\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}
Pero usa todos los \BODY
y no línea por línea. Además, si agrego un salto de línea, #1
ya \StrLen
no es una cadena (contiene saltos de línea y genera errores).
Finalmente logré tomar la primera línea en mi nuevo entorno usando el código de @Bruno Le Floch deaquípero realmente no entiendo ese código y no sé qué leer para entenderlo y cambiarlo para tomar todos los argumentos. Además, todavía no puedo agregar \ al final de las filas para mostrar dónde termina la línea de la matriz... Esto es lo que tengo ahora:
\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}
Cualquier ayuda será apreciada. El resultado que quiero es tomar como argumentos las filas del entorno. (Ahora no sé cuántas filas tendrá la matriz. Así que no proporcione una cantidad específica de argumentos en el nuevo entorno).
Respuesta1
Esto utiliza el poderoso listofitems
paquete para analizar el archivo \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}
Y esto muestra cómo subanalizar aún más cada línea, palabra por palabra, usando un espacio como separador de segundo nivel:
\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}
Respuesta2
Si no te importa si las líneas terminan en \\
(lo cual es más seguro que jugar con \endlinechar
), es realmente sencillo con 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}
Utilicé una acción ficticia para realizar en cada línea, solo a modo de ejemplo. La comprobación de vacío resulta útil en caso de que la última línea termine en \\
. Hay otras posibilidades: simplemente se puede comprobar si el último elemento de la secuencia obtenida \BODY
está vacío. Todo depende de lo que quieras hacer con los contenidos del entorno.