2

I am using the modification of a macro to save to lists using expl3 and xparse. I have managed to create a small interface type [key = val] and using the environ package I have been able to achieve my goal. The issue is that the list, like environ, does not support content of the type verbatim, apparently the only option is to write a auxiliary file (.tsc) and then use \input{file-\tmpNr.tsc} what which solves the problem. Here is where I am trapped, I can generate the temporary files and add it with \envtolist{\input{file-\tmpNr.tsc}}, but in the list the value of \tmpNr it increases every time that \usecontent[...]{...} command is used.
I just want to record the current value at the minute it is recorded and that it will not be modified in the future. The code that I have is the following:

% MWE forum new
\documentclass{article}
\usepackage{environ,etoolbox,xparse,fvextra}%
% Definitions 
\ExplSyntaxOn
% \elementin{listname} number of elements in listname
\cs_new:Npn \elementin #1
 {%
    \seq_count:c {l_savecontent_content_#1_seq}%
 }
% \clearlist{listname} clear if exists
\cs_new:Npn \clearlist #1 
 {
    \seq_clear_new:c {l_savecontent_content_#1_seq}%
 }

% \addcontent{listname}{{}} ...need double {{...}}
\NewDocumentCommand{\addcontent}{m+m}
 {
    \savecontent_add_content:nn { #1 } { #2 }
 }

% \usecontent[number]{listname}
\DeclareExpandableDocumentCommand{\usecontent}{O{1}m}
 {
    \savecontent_use_content:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \savecontent_add_content:nn #1 #2
 {
 \seq_if_exist:cF { l_savecontent_content_#1_seq }
    { \seq_new:c { l_savecontent_content_#1_seq } }
 \__savecontent_add_content:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \__savecontent_add_content:nn #1 #2
 {
    \tl_map_inline:nn { #2 }
  {
    \seq_gput_right:cn { l_savecontent_content_#1_seq } { ##1 }
  }
 }

\cs_new:Npn \savecontent_use_content:nn #1 #2
 {
    \seq_item:cn { l_savecontent_content_#2_seq } { #1 }
 }

% define keys (local)
\keys_define:nn { scontent }
 {
    save-cmd .tl_set:N   = \l_scontent_cmd_save_tl,%
    show-cmd .bool_set:N = \l_scontent_cmd_show_tl,%
    save-env .tl_set:N   = \l_scontent_env_save_tl,%
    show-env .bool_set:N = \l_scontent_env_show_tl,%
    %temp-ext .tl_set:N   = \l_scontent_temp_ext_tl,%
    %temp-nro .tl_set:N   = \l_scontent_temp_nro_tl,%
    name-tmp .tl_set:N   = \l_scontent_tmp_name_tl,%
    body-env .bool_set:N = \l_scontent_env_body_tl,%
    body-cmd .bool_set:N = \l_scontent_cmd_body_tl,%
    verb     .meta:n     = { body-env = false, body-cmd = false },%
    show-all .meta:n     = { show-env = true , show-cmd = true  },%
 }

% set local default 
\keys_set:nn { scontent }
 {
    save-cmd = content, %
    show-cmd = false,%
    save-env = content, %
    show-env = false,%
    name-tmp = \jobname,%
    body-env = true,%
    body-cmd = true,%
 }


% \Setscontent{ key = val } 
\NewDocumentCommand{\Setscontent}{ +m} 
 {
    \keys_set:nn { scontent } {#1}
 }

% \envtolist pass \BODY to list name
\newrobustcmd{\envtolist}[1]{\addcontent{ \l_scontent_env_save_tl }{{#1}}}

% Define SAVEcontent to activate \BODY from environ 
\NewEnviron{SAVEcontent}[1]{}

% counter for external tmp files
\newcounter{outNr}
\DeclareExpandableDocumentCommand{\tmpNr}{}{% 
  \arabic{outNr}
}

% \begin{scontent}[...] no space need ! 
\NewDocumentEnvironment{scontent}{ !o } 
 {%
  \group_begin:

  \IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
  \IfBooleanT { \l_scontent_env_body_tl } { \SAVEcontent{#1} } % no \verb content
  \IfBooleanF  { \l_scontent_env_body_tl } { 
            \stepcounter{outNr}
            \VerbatimEnvironment
            \VerbatimOut{\l_scontent_tmp_name_tl-\theoutNr.tsc}} % \verb content 
 } % close first part
 {
  \IfBooleanF { \l_scontent_env_body_tl } { 
            \endVerbatimOut%
            \envtolist{\input{\l_scontent_tmp_name_tl-\tmpNr.tsc}} % line whit counter ...
               }
  \IfBooleanT { \l_scontent_env_body_tl } { \endSAVEcontent\expandafter\envtolist\expandafter{\BODY} }%
  \IfBooleanT { \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} } 
  \group_end:
 } % close second part

 % \Scontent[...]{...}
\NewDocumentCommand{\Scontent}{!o +m}
 {
  \group_begin:
  \IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
  \IfBooleanT { \l_scontent_cmd_body_tl } { \addcontent{ \l_scontent_cmd_save_tl }{{#2}} } % pass direct to list
  \IfBooleanT { \l_scontent_cmd_show_tl } { \usecontent[-1]{ \l_scontent_cmd_save_tl} } %
  \group_end:
 }%      

% put starred "*" in clasical... use * and [...] cause a problem whit \VerbatimOut :(
% use key = verb for solve this 
%\cs_new:cpn {scontent*} {\scontent*}
%\cs_new_eq:cN {endscontent*} \endscontent
\ExplSyntaxOff

\begin{document}
\Setscontent{
    save-env=test-env,% list for save env
    save-cmd=test-cmd,% list for save cmd
            } 

\section{Test scontent env}
Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text

\begin{scontent}
Text is hiden....no verb inside the block, and no use [...]...use environ
\end{scontent}
Now show save using \verb+\usecontent[1]{test-env}+\par
\usecontent[1]{test-env}\par

OK...continue\par

\begin{scontent}[verb]
Second Text using \verb+\verb+ in some lines...
\end{scontent}

Now show save using \verb+\usecontent[2]{test-env}+\par
\usecontent[2]{test-env}\par
OK...continue\par

\begin{scontent}[verb]
Third Text using \verb+\verb+ in some lines
\end{scontent}
Now show using \verb+\usecontent[3]{test-env}+\par
\usecontent[3]{test-env}\par
OK...continue\par

SOME LINE OF TEXT

Now reuse \verb+\usecontent[2]{test-env}+\par
\usecontent[2]{test-env}\par
NOT OK...show  \verb+\usecontent[3]{test-env}+ :(

\section{Test Scontent comand}

\Scontent[show-cmd=true]{\unexpanded{using a command version, no verb in some lines}}

No \verb+\verb+ suported no escape for this...environ not suport this :(

\end{document}

I tried to use \expandafter and \noexpand but I could not make it work :( How can I record only the value of the counter and then not change it when I use the \usecontent command?

Saludos PS: If someone has any better idea to achieve this, we appreciate ...

1

I have solved it by myself, I do not know if the code will be completely correct, but, it works for what I want, I leave it here:

% Example OK
\documentclass{article}
\usepackage{environ,etoolbox,xparse,fvextra,xcolor}%
% Definitions 
\ExplSyntaxOn
% \elementin{listname} number of elements in listname
\cs_new:Npn \elementin #1
 {%
    \seq_count:c {l_savecontent_content_#1_seq}%
 }
% \clearlist{listname} clear if exists
\cs_new:Npn \clearlist #1 
 {
    \seq_clear_new:c {l_savecontent_content_#1_seq}%
 }

% \addcontent{listname}{{}} ...need double {{...}}
\NewDocumentCommand{\addcontent}{m+m}
 {
    \savecontent_add_content:nn { #1 } { #2 }
 }

% \usecontent[number]{listname}
\DeclareExpandableDocumentCommand{\usecontent}{O{1}m}
 {
    \savecontent_use_content:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \savecontent_add_content:nn #1 #2
 {
 \seq_if_exist:cF { l_savecontent_content_#1_seq }
    { \seq_new:c { l_savecontent_content_#1_seq } }
 \__savecontent_add_content:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \__savecontent_add_content:nn #1 #2
 {
    \tl_map_inline:nn { #2 }
  {
    \seq_gput_right:cn { l_savecontent_content_#1_seq } { ##1 }
  }
 }

\cs_new:Npn \savecontent_use_content:nn #1 #2
 {
    \seq_item:cn { l_savecontent_content_#2_seq } { #1 }
 }

% define keys (local)
\keys_define:nn { scontent }
 {
    save-cmd .tl_set:N   = \l_scontent_cmd_save_tl,%
    show-cmd .bool_set:N = \l_scontent_cmd_show_tl,%
    save-env .tl_set:N   = \l_scontent_env_save_tl,%
    show-env .bool_set:N = \l_scontent_env_show_tl,%
    name-tmp .tl_set:N   = \l_scontent_tmp_name_tl,%
    body-env .bool_set:N = \l_scontent_env_body_tl,%
    body-cmd .bool_set:N = \l_scontent_cmd_body_tl,%
    verb     .meta:n     = { body-env = false, body-cmd = false },%
    show-all .meta:n     = { show-env = true , show-cmd = true  },%
 }

% set local default 
\keys_set:nn { scontent }
 {
    save-cmd = content, %
    show-cmd = false,%
    save-env = content, %
    show-env = false,%
    name-tmp = \jobname,%
    body-env = true,%
    body-cmd = true,%
 }


% \Setscontent{ key = val } 
\NewDocumentCommand{\Setscontent}{ +m} 
 {
    \keys_set:nn { scontent } {#1}
 }

% \envtolist pass \BODY to list name
\newrobustcmd{\envtolist}[1]{\addcontent{ \l_scontent_env_save_tl }{{#1}}}

% counter for external tmp files
\newcounter{outNr}

% \filetolist for external tmp files
\tl_new:N \filetolist

% Define SAVEcontent to activate \BODY from environ 
\NewEnviron{SAVEcontent}[1]{}

% \begin{scontent}[...] no space need ! 
\NewDocumentEnvironment{scontent}{ !o } 
 {%
  \group_begin:
  \IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
  \IfBooleanT { \l_scontent_env_body_tl } { \SAVEcontent{#1} } % no verb content
  \IfBooleanF { \l_scontent_env_body_tl } % verb content 
    { 
    \stepcounter{outNr}
    \VerbatimOut{\l_scontent_tmp_name_tl-\theoutNr.tsc}
    } % write out 
 } % close first part
 {
  \IfBooleanF { \l_scontent_env_body_tl } 
    { 
    \endVerbatimOut%
     \tl_put_right:Nx \filetolist { \envtolist{\exp_not:N \input  {\exp_after:wN \l_scontent_tmp_name_tl-\theoutNr.tsc} } }% \expandafter counter
    \filetolist
    %\show\filetolist
    }
  \IfBooleanT { \l_scontent_env_body_tl } { \endSAVEcontent\expandafter\envtolist\expandafter{\BODY} }%
  \IfBooleanT { \l_scontent_env_show_tl } { \usecontent[-1]{ \l_scontent_env_save_tl} } 
  \group_end:
 } % close second part

 % \Scontent[...]{...}
\NewDocumentCommand{\Scontent}{!o +m}
 {
  \group_begin:
  \IfNoValueF {#1} { \keys_set:nn { scontent } {#1} }
  \IfBooleanT { \l_scontent_cmd_body_tl } { \addcontent{ \l_scontent_cmd_save_tl }{{#2}} } % pass direct to list
  \IfBooleanT { \l_scontent_cmd_show_tl } { \usecontent[-1]{ \l_scontent_cmd_save_tl} } %
  \group_end:
 }%      
\ExplSyntaxOff
\begin{document}
% set name of list
\Setscontent{
    save-env=test-env,% list for save env
    save-cmd=test-cmd,% list for save cmd
            } 
\section{Test scontent env OK}
The following blocks of text will be stored in memory or in external files and 
then referenced using lists, not shown directly.\par

\begin{scontent}
\textcolor{red}{First Text}....no verb inside the block, and no use [...]...use environ
\end{scontent}

% \jobname-1.tsc
\begin{scontent}[verb]
\textcolor{green}{Second Text}...save in \verb+\jobname-1.tsc+
\end{scontent}

% \jobname-2.tsc
\begin{scontent}[verb]
\textcolor{blue}{Third Text}...save in \verb+\jobname-2.tsc+
\end{scontent}

% \jobname-3.tsc
\begin{scontent}[verb]
\textcolor{gray}{Fourth Text}...save in \verb+\jobname-3.tsc+
\end{scontent}

Now we can see that the number of items saved in the list is \elementin{test-env} 
and we can show them in reverse order whit \verb+\usecontent[...]{test-env}+:\par

\usecontent[4]{test-env}\par\vspace{1cm}
\usecontent[3]{test-env}\par\vspace{1cm}
\usecontent[2]{test-env}\par\vspace{1cm}
\usecontent[1]{test-env}\par\vspace{1cm}

\section{Test scontent env other OK}

% \jobname-4.tsc 
\begin{scontent}[save-env=other, verb]
\textcolor{magenta}{Other Text}...save in list \{other\} and write in \verb+\jobname-4.tsc+
\end{scontent}
Now show whit \verb+\usecontent{other}+:\par 
\usecontent{other}

\section{Test Scontent comand OK}
\Scontent{using a command version, no verb\par in\par some\par lines}

No \verb+\verb+ suported no escape for this...environ not suport this :(. [no problem]

\usecontent{test-cmd}
\end{document}

Apparently the line

\tl_put_right:Nx \filetolist { \envtolist{\exp_not:N \input  {\exp_after:wN \l_scontent_tmp_name_tl-\theoutNr.tsc} } }% \expandafter counter
\filetolist

It's not the right one, it works, but, when using:

pdflatex --recorder -newtest.tex & cat -n newtest.fls | grep "INPUT newtest"

the output is:

 5  INPUT newtest.tex
56  INPUT newtest.aux
57  INPUT newtest.aux
67  INPUT newtest-3.tsc
68  INPUT newtest-3.tsc
69  INPUT newtest-2.tsc
70  INPUT newtest-2.tsc
71  INPUT newtest-1.tsc
72  INPUT newtest-1.tsc
74  INPUT newtest-4.tsc
75  INPUT newtest-4.tsc
80  INPUT newtest.aux

that is, \input a .tsc files twice, since in the example only called them once ... I suppose this is another question ....

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.