I'm trying to rewrite some of the codes I have by following the correct expl3
rules. With the following code I define the scontents
environment that encapsulates the filecontentsdefmacro
environment of the filecontentsdef
package using xparse/expl3
. Everything works OK, I get to record the content of scontents
in a sequence and then I can access it, the theme is the way I get it. The original package has the \filecontentsexec
macro to run the content recorded by the filecontentsdefmacro
environment, but, I haven't been able to make this work for me and have had to copy almost directly the definition directly from the package and write it in terms of expl3
. Like this:
% Expand \l_scontents_macro_tmp_tl and pass to seq
\cs_new_protected:Nn \_scontents_macro_to_seq:
{
\tl_put_right:Nx \l_tmpa_tl
{
\tex_newlinechar:D = 13
\tex_everyeof:D = { \exp_not:N }
\exp_not:N \scantokens \exp_after:wN { \tl_use:c { l_scontents_macro_tmp_tl } }
\tex_newlinechar:D = 10 \scan_stop:
}
\tl_put_right:Nx \l_tmpb_tl
{
\exp_not:N \_scontents_append_contents:nn
{
\exp_not:V \l_scontents_name_seq_tl
}
{ \exp_not:V \l_tmpa_tl }
}
\l_tmpb_tl % add to seq
}
The problem is that I use (and abuse) the :D
argument that as far as I've read, it shouldn't be occupied, my idea was to be able to use something shorter, similar to this:
% Expand \l_scontents_macro_tmp_tl and pass to seq
\cs_new_protected:Nn \_scontents_macro_to_seq:
{
\_scontents_append_contents:nn { \l_scontents_name_seq_tl }
{
\filecontentsexec \exp_after:wN { \tl_use:c { l_scontents_macro_tmp_tl } }
}
}
This is the complete example file:
\documentclass{article}
\usepackage{filecontentsdef}[2019/04/20]
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:c { l_scontents_macro_tmp_tl }
\keys_define:nn { scontents }
{
save-env .tl_set:N = \l_scontents_name_seq_tl,
save-env .initial:n = contents,
show-env .bool_set:N = \l_scontents_show_env_tl,
show-env .initial:n = false
}
% Adapted from https://tex.stackexchange.com/a/215571/7832
\cs_new_protected:Npn \_scontents_append_contents:nn #1 #2
{
\seq_if_exist:cF { g_scontents_seq_name_#1_seq }
{
\seq_new:c { g_scontents_seq_name_#1_seq }
}
\seq_gput_right:cn { g_scontents_seq_name_#1_seq } { #2 }
}
\cs_new_protected:Npn \_scontents_getfrom_seq:nn #1 #2
{
\seq_item:cn { g_scontents_seq_name_#2_seq } { #1 }
}
\ProvideExpandableDocumentCommand{\getstored}{ O{1} m }
{
\_scontents_getfrom_seq:nn { #1 } { #2 }
}
% Define environment ( wrap \filecontentsdefmacro )
% Adapted from https://tex.stackexchange.com/a/487746/7832
\ProvideDocumentEnvironment{ scontents }{}
{
\char_set_catcode_active:N \^^M
\scontents_start_environment:w
}
{
\scontents_stop_environment:
\scontents_atend_environment:
}
% Delaying [key=val] for environment
\cs_new_protected:Npn \scontents_environment_keys:w [#1]
{
\keys_set:nn { scontents } { #1 }
}
% Star environment
\group_begin:
\char_set_catcode_active:N \^^M
\cs_new_protected:Npn \scontents_start_environment:w #1 ^^M
{
\tl_if_blank:nF { #1 } { \scontents_environment_keys:w #1 }
\group_begin: % open a group for environment
\use:c { filecontentsdefmacro } { \l_scontents_macro_tmp_tl } ^^M
}
\group_end:
% Stop environment
\cs_new_protected:Nn \scontents_stop_environment:
{
\endfilecontentsdefmacro
\group_end: % close a group for environment
}
% Expand \l_scontents_macro_tmp_tl and pass to seq
\cs_new_protected:Nn \_scontents_macro_to_seq:
{
\tl_put_right:Nx \l_tmpa_tl
{
\tex_newlinechar:D = 13
\tex_everyeof:D = { \exp_not:N }
\exp_not:N \scantokens \exp_after:wN { \tl_use:c { l_scontents_macro_tmp_tl } }
\tex_newlinechar:D = 10 \scan_stop:
}
\tl_put_right:Nx \l_tmpb_tl
{
\exp_not:N \_scontents_append_contents:nn
{
\exp_not:V \l_scontents_name_seq_tl
}
{ \exp_not:V \l_tmpa_tl }
}
\l_tmpb_tl % add to seq
}
% Execution of the code after finishing the scontent environment
\cs_new_protected:Nn \scontents_atend_environment:
{
\_scontents_macro_to_seq:
\bool_if:NT \l_scontents_show_env_tl
{
\_scontents_getfrom_seq:nn { -1 }{ \l_scontents_name_seq_tl }
}
\cs_undefine:N \l_scontents_macro_tmp_tl
}
\ExplSyntaxOff
\setlength{\parindent}{0pt} % just for the example
\begin{document}
\section*{Test environment}
Test \verb+\begin{scontents}+ no \verb+[key=val]+\par
\begin{scontents}
Using \verb+scontents+ env no \verb+[key=val]+, save in
\verb+contents+ with index 1. \footnote{AND footnotes !!}
\begin{verbatim}
(A) verbatim environment
\end{verbatim}
\end{scontents}
Test \verb+\begin{scontents}[save-env=other]+\par
\begin{scontents}[save-env=other]
Using \verb+scontents+ env with \verb+[save-env=other]+, save in
\verb+other+ with index 1.
\begin{verbatim*}
(B) verbatim environment
\end{verbatim*}
\end{scontents}
\section*{Show stored contents}
\getstored[1]{other}
\getstored[1]{contents}
\end{document}
I have tried to write the code following the "rules" (and what I have learned in the forum), if something is badly written (related to expansion
or cs
), please correct me accordingly.
Greetings.