2

Hello everyone once again, after having resolved my doubt regarding the use of \label and \ref. Reading the comments, I have noticed that in many occasions do not need to use the referencing system, only the values associated with these.

My idea is not to use auxiliary files (need many files en some cases, append mode in .aux file no exist in TeX), save in memory list short answers to exercises , so when copying and pasting from one file to another not need to make major modifications (changue only a ref to list).

This is the file (which works)

% !file: test.tex
% arara: pdflatex
\documentclass{article}%
\usepackage{amsmath}
\usepackage{multicol}
\usepackage{enumitem}
\usepackage{tcolorbox}
\tcbuselibrary{many}
\usepackage{pgffor}

% Set key for multicols in enumitem
\SetEnumitemKey{columns}{before=\begin{multicols}{#1},after=\end{multicols}}%

% Some definition
\newtheorem{theorem}{Theorem}
\newtheorem{exercise}[theorem]{Exercise}

% from https://tex.stackexchange.com/a/215571/7832
\ExplSyntaxOn
\NewDocumentCommand{\storedata}{mm}
  {
   \bcp_store_data:nn { #1 } { #2 }
  }

\NewDocumentCommand{\appenddata}{mm}
 {
  \bcp_append_data:nn { #1 } { #2 }
 }

\DeclareExpandableDocumentCommand{\getdata}{O{1}m}
 {
  \bcp_get_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bcp_store_data:nn #1 #2
 {
  % create the sequence if it doesn't exist or clear it if it exists
  \seq_if_exist:cTF { l_bcp_data_#1_seq }
   { \seq_new:c { l_bcp_data_#1_seq } }
   { \seq_clear:c { l_bcp_data_#1_seq } }
  % append the items
  \__bcp_append_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bcp_append_data:nn #1 #2
 {
  % create the sequence if it doesn't exist, do nothing if it exists
  \seq_if_exist:cF { l_bcp_data_#1_seq }
   { \seq_new:c { l_bcp_data_#1_seq } }
  % append the items
  \__bcp_append_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \__bcp_append_data:nn #1 #2
 {
  % append items one at a time
  \tl_map_inline:nn { #2 }
   {
    \seq_put_right:cn { l_bcp_data_#1_seq } { ##1 }
   }
 }

\cs_new:Npn \bcp_get_data:nn #1 #2
 {
  % retrieve the requested item
  \seq_item:cn { l_bcp_data_#2_seq } { #1 }
 }
\ExplSyntaxOff

\begin{document}
\section{Exercices}

\begin{exercise}
Factoring next expression:
\end{exercise}

\begin{enumerate}
\item $a^{2}-b^{2}$
\item $x^{2}-2x+1$ 
\item $3x+3y+3z$
\item $3x+3y-6z$
\end{enumerate}
% save in list exe:1
\appenddata{exe:1}{{$\left(a-b\right)\left(a+b\right)$}}
\appenddata{exe:1}{{$\left(x-1\right)^{2}$}}
\appenddata{exe:1}{{$3x+3y+3z$}}
\appenddata{exe:1}{{$3\left(x+y-2z\right)$}}

\begin{exercise}
Solve:
\end{exercise}
\begin{enumerate}
\item $2x+3=5$
\item $5x-2=7$
\item $4-3x=5$
\end{enumerate}

% save in list exe:2
\appenddata{exe:2}{{$1$}}
\appenddata{exe:2}{{$\dfrac{9}{5}$}}
\appenddata{exe:2}{{$-\dfrac{1}{3}$}}

\section{Answer}
% #1 : pass to tcolorbox
% #2 : name
% #3 : list
% #4 : maxvalue
% #5 : columns
\DeclareTotalTColorBox{\answer}{O{} m m m O{4}}
{ colback=white,size=small,top=0mm,bottom=1.5mm, left=0mm,width=\columnwidth,title filled,%
  fontupper=\small,fonttitle=\small\sffamily,%
    adjusted title={#2},center title,#1}
  {% 
  \begin{enumerate}[columns=#5,leftmargin=15pt,labelsep=3pt,font=\footnotesize,nosep,widest=25,]%
  \small
  \setlength{\columnsep}{0pt} 
   \foreach \x in {1,...,#4} {
    \item \getdata[\x]{#3}%
    }
  \end{enumerate}
  }%
\answer{Exercise 1}{exe:1}{4}
\answer{Exercise 2}{exe:2}{3}[3]
\end{document}

Now comes my problem, the macro I take from Storing an array of strings in a command only works in local mode, if write it inside an environment it only exists in this and not outside it, that is, I will not be able to access it outside the environment. For example:

% save list in enumerate 
\begin{enumerate}
\item $a^{2}-b^{2}$ \appenddata{exe:1}{{$\left(a-b\right)\left(a+b\right)$}}
\item $x^{2}-2x+1$ \appenddata{exe:1}{{$\left(x-1\right)^{2}$}}
\item $3x+3y+3z$ \appenddata{exe:1}{{$3x+3y+3z$}}
\item $3x+3y-6z$ \appenddata{exe:1}{{$3\left(x+y-2z\right)$}}
\end{enumerate}

And my idea is that it works within enumerate environments, and then access values outside of them. I have tried with this:

% !file: test.tex
% arara: pdflatex
\documentclass{article}%
\usepackage{amsmath}
\usepackage{multicol}
\usepackage{enumitem}
\usepackage{tcolorbox}
\tcbuselibrary{many}
\usepackage{pgffor}

% Set key for multicols in enumitem
\SetEnumitemKey{columns}{before=\begin{multicols}{#1},after=\end{multicols}}%

% Some definition
\newtheorem{theorem}{Theorem}
\newtheorem{exercise}[theorem]{Exercise}

% from https://tex.stackexchange.com/a/215571/7832
\ExplSyntaxOn
\NewDocumentCommand{\storedata}{mm}
  {
   \bcp_store_data:nn { #1 } { #2 }
  }

\NewDocumentCommand{\appenddata}{mm}
 {
  \bcp_append_data:nn { #1 } { #2 }
 }

\DeclareExpandableDocumentCommand{\getdata}{O{1}m}
 {
  \bcp_get_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bcp_store_data:nn #1 #2
 {
  % create the sequence if it doesn't exist or clear it if it exists
  \seq_if_exist:cTF { l_bcp_data_#1_seq }
   { \seq_new:c { l_bcp_data_#1_seq } }
   { \seq_clear:c { l_bcp_data_#1_seq } }
  % append the items
  \__bcp_append_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bcp_append_data:nn #1 #2
 {
  % create the sequence if it doesn't exist, do nothing if it exists
  \seq_if_exist:cF { l_bcp_data_#1_seq }
   { \seq_new:c { l_bcp_data_#1_seq } }
  % append the items
  \__bcp_append_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \__bcp_append_data:nn #1 #2
 {
  % append items one at a time
  \tl_map_inline:nn { #2 }
   {
    \seq_put_right:cn { l_bcp_data_#1_seq } { ##1 }
   }
 }

\cs_new:Npn \bcp_get_data:nn #1 #2
 {
  % retrieve the requested item
  \seq_item:cn { l_bcp_data_#2_seq } { #1 }
 }
\ExplSyntaxOff

% Create a environment to encapsulate answer
\NewDocumentEnvironment{myenumerate}{m}{%
% Command to save answer
\NewDocumentCommand\sol{m}{%
    \appenddata{#1}{{##1}}% 
    }% close \sol
}%
{}% close myenumerate
\begin{document}
\section{Exercices}

\begin{exercise}
Factoring next expression:
\end{exercise}

\begin{myenumerate}{exe:1}
\begin{enumerate}
\item $a^{2}-b^{2}$ \sol{$\left(a-b\right)\left(a+b\right)$}
\item $x^{2}-2x+1$  \sol{$\left(x-1\right)^{2}$}
\item $3x+3y+3z$    \sol{$3x+3y+3z$}
\item $3x+3y-6z$    \sol{$3\left(x+y-2z\right)$}
\end{enumerate}
\end{myenumerate}

\begin{exercise}
Solve:
\end{exercise}

\begin{myenumerate}{exe:2}
\begin{enumerate}
\item $2x+3=5$ \sol{$1$}
\item $5x-2=7$ \sol{$\dfrac{9}{5}$}
\item $4-3x=5$ \sol{$-\dfrac{1}{3}$}
\end{enumerate}
\end{myenumerate}

\section{Answer}
% #1 : pass to tcolorbox
% #2 : name
% #3 : list
% #4 : maxvalue default: lenght of list
% #5 : columns
\DeclareTotalTColorBox{\answer}{O{} m m m O{4}}
{ colback=white,size=small,top=0mm,bottom=1.5mm, left=0mm,width=\columnwidth,title filled,%
  fontupper=\small,fonttitle=\small\sffamily,%
    adjusted title={#2},center title,#1}
  {% 
  \begin{enumerate}[columns=#5,leftmargin=15pt,labelsep=3pt,font=\footnotesize,nosep,widest=25,]%
  \small
  \setlength{\columnsep}{0pt} 
   \foreach \x in {1,...,#4} {
    \item \getdata[\x]{#3}%
    }
  \end{enumerate}
  }%
\answer{Exercise 1}{exe:1}{4}
\answer{Exercise 2}{exe:2}{3}[3]
\end{document}

Also try to add a key to enumitem to avoid writing a new environment

\SetEnumitemKey{reflist}{before=\storedata{#1}{}}%

But none of the options I tried worked out, so, here comes the big question: How do I modify \appendata|\storedata to make them work globally? \appendata would be like \label and \getdata would be as \ref, of course only with values and whitout .aux file (or two run).

  • 1
    Out of the blue: Have you tried \seq_gput_right:Nn instead of \seq_put_right:Nn etc, i.e. store it globally? – user31729 Apr 14 '17 at 18:27
  • I have read the documentation, but it is very above my level :( – Pablo González L Apr 14 '17 at 21:14
  • The expl3 macros like \seq_gput_right or \prop_gput etc. store data in a global level, i.e. the data is still available outside of the group, i.e. the g prefix to put stands for global. – user31729 Apr 14 '17 at 22:21
2

In order to store the data globally, \seq_gput_right:Nn (and its variants) must be applied, otherwise the local saving gets lost ultimately after the group formed by the enumerate environment ends.

\seq_put_right:Nn however works only inside a group.

\documentclass{article}%
\usepackage{amsmath}
\usepackage{multicol}
\usepackage{enumitem}
\usepackage{tcolorbox}
\tcbuselibrary{many}
\usepackage{pgffor}

% Set key for multicols in enumitem
\SetEnumitemKey{columns}{before=\begin{multicols}{#1},after=\end{multicols}}%

% Some definition
\newtheorem{theorem}{Theorem}
\newtheorem{exercise}[theorem]{Exercise}

% from https://tex.stackexchange.com/a/215571/7832
\ExplSyntaxOn

% Reporter macro, is expandable
\cs_new:Npn \reportnumberofseqitems #1{%
 \seq_count:c {l_bcp_data_#1_seq}%
}


\NewDocumentCommand{\storedata}{mm}
  {
   \bcp_store_data:nn { #1 } { #2 }
  }

\NewDocumentCommand{\appenddata}{mm}
 {
  \bcp_append_data:nn { #1 } { #2 }
 }

\DeclareExpandableDocumentCommand{\getdata}{O{1}m}
 {
  \bcp_get_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bcp_store_data:nn #1 #2
 {
  % create the sequence if it doesn't exist or clear it if it exists
  \seq_if_exist:cTF { l_bcp_data_#1_seq }
   { \seq_new:c { l_bcp_data_#1_seq } }
   { \seq_gclear:c { l_bcp_data_#1_seq } }
  % append the items
  \__bcp_append_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \bcp_append_data:nn #1 #2
 {
  % create the sequence if it doesn't exist, do nothing if it exists
  \seq_if_exist:cF { l_bcp_data_#1_seq }
   { \seq_new:c { l_bcp_data_#1_seq } }
  % append the items
  \__bcp_append_data:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \__bcp_append_data:nn #1 #2
 {
  % append items one at a time
  \tl_map_inline:nn { #2 }
   {
    \seq_gput_right:cn { l_bcp_data_#1_seq } { ##1 }
   }
 }

\cs_new:Npn \bcp_get_data:nn #1 #2
 {
  % retrieve the requested item
  \seq_item:cn { l_bcp_data_#2_seq } { #1 }
 }
\ExplSyntaxOff

% Create a environment to encapsulate answer
\NewDocumentEnvironment{myenumerate}{m}{%
% Command to save answer
\NewDocumentCommand\sol{m}{%
    \appenddata{#1}{{##1}}% 
    }% close \sol
}%
{}% close myenumerate
\begin{document}
\section{Exercices}

\begin{exercise}
Factoring next expression:
\end{exercise}

\begin{myenumerate}{exe:1}
\begin{enumerate}
\item $a^{2}-b^{2}$ \sol{$\left(a-b\right)\left(a+b\right)$}
\item $x^{2}-2x+1$  \sol{$\left(x-1\right)^{2}$}
\item $3x+3y+3z$    \sol{$3x+3y+3z$}
\item $3x+3y-6z$    \sol{$3\left(x+y-2z\right)$}
\end{enumerate}
\end{myenumerate}

\begin{exercise}
Solve:
\end{exercise}

\begin{myenumerate}{exe:2}
\begin{enumerate}
\item $2x+3=5$ \sol{$1$}
\item $5x-2=7$ \sol{$\dfrac{9}{5}$}
\item $4-3x=5$ \sol{$-\dfrac{1}{3}$}
\end{enumerate}
\end{myenumerate}

There are \reportnumberofseqitems{exe:1} items in exe:1 and     \reportnumberofseqitems{exe:2} items in exe:2

\section{Answer}
% #1 : pass to tcolorbox
% #2 : name
% #3 : list
% #4 : maxvalue default: lenght of list
% #5 : columns
\DeclareTotalTColorBox{\answer}{O{} m m m O{4}}
{ colback=white,size=small,top=0mm,bottom=1.5mm, left=0mm,width=\columnwidth,title filled,%
  fontupper=\small,fonttitle=\small\sffamily,%
    adjusted title={#2},center title,#1}
  {% 
  \begin{enumerate}[columns=#5,leftmargin=15pt,labelsep=3pt,font=\footnotesize,nosep,widest=25,]%
  \small
  \setlength{\columnsep}{0pt} 
   \foreach \x in {1,...,#4} {
    \item \getdata[\x]{#3}%
    }
  \end{enumerate}
  }%
\answer{Exercise 1}{exe:1}{4}
\answer{Exercise 2}{exe:2}{3}[3]
\end{document}

enter image description here

  • Thanks a lot, it's just what I was looking for, a couple of cosnsults on the sidelines, how can I get the number of items on the list? (I would like to remove the mandatory #4 from the foreach in \answer) and what is the maximum number of lists and the number of elements in this that they can have in a file? (If it is a large number that does not have memory problems, I will adapt this solution to another question)...Total thanks – Pablo González L Apr 14 '17 at 21:13
  • 1
    @PabloGonzálezL: You can achieve the number of elements in the lists with the \seq_count:N macro, which is expandable. (similarly \clist_count:N, \prop_count:N ). Basically, the number of (global) lists is only limited by the number of registers for macro names, so unless you don't plan to have more then 30000 lists it should be alright. The amount of storage is only limited by memory. – user31729 Apr 14 '17 at 22:19
  • Thanks for the clarification, can you give me an example of how to use the list counter ?, in the forum I found tex.stackexchange.com/a/246924/7832 but in my case the lists are changing names and I can not use the same trick :(. – Pablo González L Apr 14 '17 at 22:49
  • @PabloGonzálezL: With changing names you mean that you use something like \seq_new:c {#1} ? – user31729 Apr 14 '17 at 22:53
  • OK, I understand, I'm a little lost with expl3 ... I'll try to make it work – Pablo González L Apr 14 '17 at 22:59

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.