1

In the following code the use of \tcbuselibrary{minted} breaks the compilation and if I comment the use of \redoit{} the compilation succeeds.

Why ? How do I fix this ?

Here is the message I have with an infinite loop.

...
Library (tcolorbox): 'tcblistingscore.code.tex' version '4.31'
(/usr/local/texlive/2020/texmf-dist/tex/latex/tcolorbox/tcbprocessing.code.tex
Library (tcolorbox): 'tcbprocessing.code.tex' version '4.31'
)))/Users/projetmbc/anaconda3/bin/pygmentize

No file x-storebis-x.aux. (/usr/local/texlive/2020/texmf-dist/tex/context/base/mkii/supp-pdf.mkii [Loading MPS to PDF converter (version 2006.09.02).] ) (/usr/local/texlive/2020/texmf-dist/tex/latex/epstopdf-pkg/epstopdf-base.sty (/usr/local/texlive/2020/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg)) ABD: EveryShipout initializing macros

If I type CTRL+C, I can see :

! Interruption.
\tnscalc_calcexpval:nnnn ...tnscalc_pline_temp_tl
                                                  \CodeAfter \int_add:Nn \l_...
l.150 \redoit
             {}

The code of \redoit is the following one where \lastcontent contains a table like content (\\ for new lines and & for new cells).

\newcommand\redoit{
    \expandafter\calcexpval\expanded{{\lastcontent}}
}

Here is the complete code.

\documentclass{article}

\usepackage{nicematrix} \usepackage{tikz} \usetikzlibrary{fit}

\usepackage{tcolorbox} \tcbuselibrary{theorems}

\tcbuselibrary{minted} % This breaks the compilation.

% Sources % * https://tex.stackexchange.com/a/475291/6880 % * https://tex.stackexchange.com/a/558343/6880 % * https://tex.stackexchange.com/a/558185/6880

\newcommand\decoframe[3]{ \begin{tikzpicture}[remember picture, overlay] \node[draw = #1, rounded corners, line width=1pt, fit = (#2.north west) (#2.north east) (#3.south west) (#3.south east)] {}; \end{tikzpicture} }

\newcommand\decobox[2]{ \tcboxmath[colframe = #1, left = 0mm, right = 0mm, top = 0mm, bottom = 0mm, boxsep = 1mm, boxrule = 1pt]{#2} }

\ExplSyntaxOn % Global variables used. \seq_new:N \l__tnscalc_colors_seq \tl_new:N \l__tnscalc_actual_color_temp_tl

\seq_new:N \l__tnscalc_calcexpval_seq
\seq_new:N \l__tnscalc_subseq_seq
\tl_new:N \l__tnscalc_xline_temp_tl
\tl_new:N \l__tnscalc_pline_temp_tl

\int_new:N \l__tnscalc_nbline_int
\int_new:N \l__tnscalc_numcol_int
\int_new:N \l__tnscalc_numcol_deco_int
\int_new:N \l__tnscalc_numcol_decotwo_int

% #1 : line separator % #2 : cell separator % #3 : content \NewDocumentCommand{\calcexpval}{O{red,blue,orange,gray} +m} { \gdef\lastcontent{#2} \tnscalc_calcexpval:nnnn{#1}{\}{&}{#2} }

% The internal version of the general purpose macro \cs_new_protected:Nn \tnscalc_calcexpval:nnnn { % #1 (option) : colors % #2 : line separator % #3 : cell separator % #4 : content

% Colors. \seq_set_split:Nnn \l__tnscalc_colors_seq { , } { #1 }

% Split into lines \seq_set_split:Nnn \l__tnscalc_calcexpval_seq { #2 } { #4 } \int_set:Nn \l__tnscalc_nbline_int { \seq_count:N \l__tnscalc_calcexpval_seq }

% Split each line into cells. \seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_xline_temp_tl \seq_set_split:NnV \l__tnscalc_x_seq { #3 } \l__tnscalc_xline_temp_tl

    \seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_pline_temp_tl
    \seq_set_split:NnV \l__tnscalc_p_seq { #3 } \l__tnscalc_pline_temp_tl

% Number of columns (offensive programming) \int_set:Nn \l__tnscalc_numcol_int { \seq_count:N \l__tnscalc_x_seq } \int_set:Nn \l__tnscalc_numcol_deco_int { 2 }

% The table of values
[ \setlength\arraycolsep{.75em} \begin{NiceArray}{r*{\l__tnscalc_numcol_int}{|c}} x\sb{k} & \l__tnscalc_xline_temp_tl \ \hline p\sb{k} & \l__tnscalc_pline_temp_tl \CodeAfter
\int_add:Nn \l__tnscalc_numcol_int {2} \bool_while_do:nn { \int_compare_p:nNn { \l__tnscalc_numcol_deco_int } < { \l__tnscalc_numcol_int } }{ \seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl \seq_put_right:NV \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl} \decoframe{\l__tnscalc_actual_color_temp_tl}{1-\int_use:N \l__tnscalc_numcol_deco_int}{2-\int_use:N \l__tnscalc_numcol_deco_int}

            \int_add:Nn \l__tnscalc_numcol_deco_int {2}
        }
    \end{NiceArray}
    \]

% Explain the calculus of the expected value. \int_incr:N \l__tnscalc_numcol_deco_int

    $E(X) = \sum\limits\sb{k=1}^{\int_use:N \l__tnscalc_numcol_int} p\sb{k} \cdot x\sb{k}$

    \par

    $E(X) = 
    \seq_map_indexed_inline:Nn \l__tnscalc_x_seq {
        \seq_pop_left:NN \l__tnscalc_p_seq \l__tnscalc_pval_tl
        \int_if_odd:nTF
            { \l__tnscalc_numcol_deco_int }
            { 
                \seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
                \seq_put_right:NV \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl}

                \decobox{\l__tnscalc_actual_color_temp_tl}{##2 \cdot \l__tnscalc_pval_tl}
            }
            { ##2 \cdot \l__tnscalc_pval_tl }

        \int_compare:nNnT { ##1 } &lt; { \seq_count:N \l__tnscalc_x_seq } { + }
        \int_incr:N \l__tnscalc_numcol_deco_int
    }
    $
} 

\ExplSyntaxOff

\newcommand\redoit{ \expandafter\calcexpval\expanded{{\lastcontent}} }

\setlength\parindent{0pt}

\begin{document}

Let's try...

\calcexpval{ 0 & 1 & 2 & 3 & 4 & 5 & 6 \ 0.2000 & 0.1 & 0.2 & 0.05 & 0.15 & 0.1 & 0.2 }

\bigskip \hrule \bigskip

\redoit{}

\end{document}

cgnieder
  • 66,645
projetmbc
  • 13,315
  • I have noticed that this is the use of \redoit and \tcbuselibrary{minted} that makes the compilation going into an infinite loop – projetmbc Aug 28 '20 at 20:16
  • I wrote it. Here is its code : \newcommand\redoit{\expandafter\calcexpval\expanded{{\lastcontent}}} . – projetmbc Aug 28 '20 at 20:22
  • So the problem now is not that of the minted library, but that of your macro. I can't help you here, I only use LaTeX to create geometry exercise polycops with TikZ and I don't master macro creation at all. Change the title of your question related to this error and add the macro tag so that the pros of TeX, LaTeX and LaTeX3 will be interested in your problem. Have a nice evening. – AndréC Aug 28 '20 at 20:28
  • 2
    Well, using \expanded when the argument contains tokens such as \\ is *very* risky. In the sense that it will definitely break. – egreg Aug 28 '20 at 21:08
  • @egreg Is there a way to save my argument safely such as to reuse it at another place ? Or do I have to use another approach ? Concretly I want to define my table of values and prints it in a place, and then explains my calculus in another place with the possibility to print or not another time the table decorated as it is the case in the code of the OP. – projetmbc Aug 28 '20 at 21:12
  • @egreg \expandafter\calcexpval\expandafter{\lastcontent} works. Why expanded breaks things ? – projetmbc Aug 29 '20 at 21:29
  • @projetmbc For the same reason as \edef\test{\bfseries} fails. Well, \\ may work in \expanded, but there are many other commands which don't. – egreg Aug 29 '20 at 21:41

2 Answers2

1

Since you're using expl3, avoid \gdef and \expandafter.

\documentclass{article}

\usepackage{nicematrix} \usepackage{tikz} \usetikzlibrary{fit}

\usepackage{tcolorbox} \tcbuselibrary{theorems}

\tcbuselibrary{minted} % This breaks the compilation.

% Sources % * https://tex.stackexchange.com/a/475291/6880 % * https://tex.stackexchange.com/a/558343/6880 % * https://tex.stackexchange.com/a/558185/6880

\newcommand\decoframe[3]{% \begin{tikzpicture}[remember picture, overlay] \node[draw = #1, rounded corners, line width=1pt, fit = (#2.north west) (#2.north east) (#3.south west) (#3.south east)] {}; \end{tikzpicture}% }

\newcommand\decobox[2]{% \tcboxmath[colframe = #1, left = 0mm, right = 0mm, top = 0mm, bottom = 0mm, boxsep = 1mm, boxrule = 1pt]{#2}% }

\ExplSyntaxOn % Global variables used. \seq_new:N \l__tnscalc_colors_seq \tl_new:N \l__tnscalc_actual_color_temp_tl \tl_new:N \g_tnscalc_content_tl

\seq_new:N \l__tnscalc_calcexpval_seq \seq_new:N \l__tnscalc_subseq_seq \tl_new:N \l__tnscalc_xline_temp_tl \tl_new:N \l__tnscalc_pline_temp_tl

\int_new:N \l__tnscalc_nbline_int \int_new:N \l__tnscalc_numcol_int \int_new:N \l__tnscalc_numcol_deco_int \int_new:N \l__tnscalc_numcol_decotwo_int

% #1 : line separator % #2 : cell separator % #3 : content \NewDocumentCommand{\calcexpval}{O{red,blue,orange,gray} +m} { \tnscalc_calcexpval:nn { #1 } { #2 } }

\cs_new_protected:Nn \tnscalc_calcexpval:nn { \tl_gset:Nn \g_tnscalc_content_tl {#2} __tnscalc_calcexpval:nnnn{#1}{\}{&}{#2} }

\cs_generate_variant:Nn \tnscalc_calcexpval:nn { nV }

% The internal version of the general purpose macro \cs_new_protected:Nn __tnscalc_calcexpval:nnnn { % #1 (option) : colors % #2 : line separator % #3 : cell separator % #4 : content

% Colors.
\seq_set_split:Nnn \l__tnscalc_colors_seq { , } { #1 }

% Split into lines
\seq_set_split:Nnn \l__tnscalc_calcexpval_seq { #2 } { #4 }
\int_set:Nn \l__tnscalc_nbline_int { \seq_count:N \l__tnscalc_calcexpval_seq }

% Split each line into cells.
\seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_xline_temp_tl
\seq_set_split:NnV \l__tnscalc_x_seq { #3 } \l__tnscalc_xline_temp_tl

\seq_pop_left:NN \l__tnscalc_calcexpval_seq \l__tnscalc_pline_temp_tl
\seq_set_split:NnV \l__tnscalc_p_seq { #3 } \l__tnscalc_pline_temp_tl

% Number of columns (offensive programming)
\int_set:Nn \l__tnscalc_numcol_int { \seq_count:N \l__tnscalc_x_seq }
\int_set:Nn \l__tnscalc_numcol_deco_int { 2 }

% The table of values                 
\[
\setlength\arraycolsep{.75em}
\begin{NiceArray}{r*{\l__tnscalc_numcol_int}{|c}}
    x\sb{k} &amp; \l__tnscalc_xline_temp_tl \\
    \hline
    p\sb{k} &amp; \l__tnscalc_pline_temp_tl
    \CodeAfter  
    \int_add:Nn \l__tnscalc_numcol_int {2}
    \bool_while_do:nn 
      {
        \int_compare_p:nNn { \l__tnscalc_numcol_deco_int } &lt; { \l__tnscalc_numcol_int }
      }
      {
        \seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
        \seq_put_right:NV \l__tnscalc_colors_seq {\l__tnscalc_actual_color_temp_tl}
        \decoframe{\l__tnscalc_actual_color_temp_tl}
            {1-\int_use:N \l__tnscalc_numcol_deco_int}
            {2-\int_use:N \l__tnscalc_numcol_deco_int}

        \int_add:Nn \l__tnscalc_numcol_deco_int {2}
      }
\end{NiceArray}
\]

% Explain the calculus of the expected value.
\int_incr:N \l__tnscalc_numcol_deco_int
$E(X) = \sum\limits\sb{k=1}^{\int_use:N \l__tnscalc_numcol_int} p\sb{k} \cdot x\sb{k}$
\par
$E(X) = 
\seq_map_indexed_inline:Nn \l__tnscalc_x_seq
  {
    \seq_pop_left:NN \l__tnscalc_p_seq \l__tnscalc_pval_tl
    \int_if_odd:nTF { \l__tnscalc_numcol_deco_int }
      { 
        \seq_pop_left:NN \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl
        \seq_put_right:NV \l__tnscalc_colors_seq \l__tnscalc_actual_color_temp_tl

        \decobox{\l__tnscalc_actual_color_temp_tl}{##2 \cdot \l__tnscalc_pval_tl}
      }
      { ##2 \cdot \l__tnscalc_pval_tl }

    \int_compare:nNnT { ##1 } &lt; { \seq_count:N \l__tnscalc_x_seq } { + }
    \int_incr:N \l__tnscalc_numcol_deco_int
  }
$

}

\NewDocumentCommand{\redoit}{O{red,blue,orange,gray}} { \tnscalc_calcexpval:nV {#1} \g_tnscalc_content_tl }

\ExplSyntaxOff

\setlength\parindent{0pt}

\begin{document}

Let's try...

\calcexpval{ 0 & 1 & 2 & 3 & 4 & 5 & 6 \ 0.2000 & 0.1 & 0.2 & 0.05 & 0.15 & 0.1 & 0.2 }

\bigskip \hrule \bigskip

\redoit

\bigskip \hrule \bigskip

\redoit[gray,orange,red,blue]

\end{document}

enter image description here

egreg
  • 1,121,712
0

Just use \expandafter\calcexpval\expandafter{\lastcontent} seems to work.

projetmbc
  • 13,315