nicematrix,LaTeX3 矩阵命名和 for 循环

nicematrix,LaTeX3 矩阵命名和 for 循环

以下代码失败。我正在寻求一些建议。

\documentclass{beamer}

\usepackage{nicematrix}
\usepackage{tikz}

\NewDocumentCommand\drawstrike{ mmm } {  
    \begin{tikzpicture}[
        remember picture, 
        overlay
    ]
        \draw[
            very thick, 
            red, 
            opacity = 0.5
        ] 
        ([xshift=-3pt]this-#1-#2-#3.north west)
        --
        ([xshift=3pt]this-#1-#2-#3.south east);
    \end{tikzpicture}
}

\ExplSyntaxOn

\int_new:N \l_row_int
\int_new:N \l_col_int

\NewDocumentCommand\strikeme{ mmm } {
    \int_set:Nn \l_row_int { \int_div_truncate:nn {#3}{#2} }
    \int_set:Nn \l_col_int { \int_mod:nn {#3} {#2}}
    
    \int_compare:nNnTF \l_col_int = 0 {
        \int_set:Nn \l_col_int { #2 }
    } {
        \int_set:Nn \l_row_int { \l_row_int + 1}
    }

    \drawstrike{#1}{\int_use:N \l_row_int}{\int_use:N \l_col_int}
}

\seq_new:N \l_notprime_seq

\int_new:N \l_tested_int
\int_new:N \l_striked_int
\int_new:N \l_max_int

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
    $\AutoNiceMatrix[
        hvlines, 
        columns - width = auto,
        name            = this-#1   % NOT SEEN FROM THE LOOP...
    ]{
        #2-#2
    }{
        \cellval{#2}{\arabic{iRow}}{\arabic{jCol}}
    }$
   
    \int_set:Nn \l_tested_int { 1 }
    \int_set:Nn \l_max_int { #2*#2 }
    
    \int_while_do:nn {
         \l_tested_int <= #1
    } {
        \int_compare:nNnTF \l_tested_int = 1 {
            \strikeme{#1}{#2}{1}
            \seq_put_left:Nn \l_notprime_seq 1
        } {
            \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_tested_int} {
                \int_set:Nn \l_striked_int { 2*\l_tested_int }
                
                \int_while_do:nn {
                    \l_striked_int <= \l_max_int
                } {
                    \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_striked_int} {
                        \strikeme{#1}{#2}{\int_use:N \l_striked_int}
                        \seq_put_left:Nx \l_notprime_seq {\int_use:N \l_striked_int}
                    }
    
                    \int_set:Nn \l_striked_int { \l_striked_int + \l_tested_int }         
                }
            }
        }
        
        \int_incr:N \l_tested_int
    }
}

\NewDocumentCommand\cellval{ mmm }{    
    \int_eval:n{#3 + #1*(#2 - 1)}
}

\ExplSyntaxOff


\begin{document}

\foreach \i in {0,...,4}{
    \begin{frame}
        \frametitle{Étape \i}
        \begin{center}
            \eratosthenes[\i]{10}
        \end{center}
    \end{frame}
}

\end{document}

答案1

更新:

在最新版本nicematrix(6.20a 2023-06-30)中,键的值name被扩展(在 TeX 意义上)。

因此,输出符合预期......


在当前版本(v. 6.20 2023-06-04) 中,环境或命令的nicematrix键值(例如) 未展开 (并存储为L3 的 )。因此,您的所有数组都具有相同的名称:。namenicematrix\AutoNiceMatrixstrthis-\i

也许在下一版本中改变这种行为是个好主意nicematrix...

这时候解决办法就是扩展你的命令的可选参数,最好的办法大概就是在命令中\eratosthenes使用,这个命令需要 L3 级别的辅助函数:\exp_args:Nx\eratosthenes

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
  \exp_args:Nx \__projetmbc_eratosthenes:nn { #1 } { #2 }
}

\cs_new_protected:Nn \__projetmbc_eratosthenes:nn {
    $\AutoNiceMatrix[
        hvlines, 
        columns - width = auto,
.........

以下是完整代码:

\documentclass{beamer}

\usepackage{nicematrix}
\usepackage{tikz}

\NewDocumentCommand\drawstrike{ mmm } {%  
    \begin{tikzpicture}[
        remember picture, 
        overlay
    ]
        \draw[
            very thick, 
            red, 
            opacity = 0.5
        ] 
        ([xshift=-3pt]this-#1-#2-#3.north west)
        --
        ([xshift=3pt]this-#1-#2-#3.south east);
    \end{tikzpicture}%
}

\ExplSyntaxOn

\int_new:N \l_row_int
\int_new:N \l_col_int

\NewDocumentCommand\strikeme{ mmm } {
    \int_set:Nn \l_row_int { \int_div_truncate:nn {#3}{#2} }
    \int_set:Nn \l_col_int { \int_mod:nn {#3} {#2}}
    
    \int_compare:nNnTF \l_col_int = 0 {
        \int_set:Nn \l_col_int { #2 }
    } {
        \int_set:Nn \l_row_int { \l_row_int + 1}
    }

    \drawstrike{#1}{\int_use:N \l_row_int}{\int_use:N \l_col_int}
}

\seq_new:N \l_notprime_seq

\int_new:N \l_tested_int
\int_new:N \l_striked_int
\int_new:N \l_max_int

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
  \exp_args:Nx \__projetmbc_eratosthenes:nn { #1 } { #2 }
}

\cs_new_protected:Nn \__projetmbc_eratosthenes:nn {
    $\AutoNiceMatrix[
        hvlines, 
        columns - width = auto,
        name            = this-#1 
    ]{
        #2-#2
    }{
        \cellval{#2}{\arabic{iRow}}{\arabic{jCol}}
    }$
   
    \int_set:Nn \l_tested_int { 1 }
    \int_set:Nn \l_max_int { #2*#2 }
    
    \int_while_do:nn {
         \l_tested_int <= #1
    } {
        \int_compare:nNnTF \l_tested_int = 1 {
            \strikeme{#1}{#2}{1}
            \seq_put_left:Nn \l_notprime_seq 1
        } {
            \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_tested_int} {
                \int_set:Nn \l_striked_int { 2*\l_tested_int }
                
                \int_while_do:nn {
                    \l_striked_int <= \l_max_int
                } {
                    \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_striked_int} {
                        \strikeme{#1}{#2}{\int_use:N \l_striked_int}
                        \seq_put_left:Nx \l_notprime_seq {\int_use:N \l_striked_int}
                    }
    
                    \int_set:Nn \l_striked_int { \l_striked_int + \l_tested_int }         
                }
            }
        }
        
        \int_incr:N \l_tested_int
    }
}

\NewDocumentCommand\cellval{ mmm }{    
    \int_eval:n{#3 + #1*(#2 - 1)}
}

\ExplSyntaxOff


\begin{document}

\foreach \i in {0,...,4}{
    \begin{frame}
        \frametitle{Étape \i}
        \begin{center}
            \eratosthenes[\i]{10}
        \end{center}
    \end{frame}
}

\end{document}

答案2

使用 so ugly\expandafter就可以了。还有其他方法吗?

\documentclass{beamer}

\usepackage{nicematrix}
\usepackage{tikz}

\NewDocumentCommand\drawstrike{ mmm } {  
    \begin{tikzpicture}[
        remember picture, 
        overlay
    ]
        \draw[
            very thick, 
            red, 
            opacity = 0.5
        ] 
        ([xshift=-3pt]this-#1-#2-#3.north west)
        --
        ([xshift=3pt]this-#1-#2-#3.south east);
    \end{tikzpicture}
}

\ExplSyntaxOn

\int_new:N \l_row_int
\int_new:N \l_col_int

\NewDocumentCommand\strikeme{ mmm } {
    \int_set:Nn \l_row_int { \int_div_truncate:nn {#3}{#2} }
    \int_set:Nn \l_col_int { \int_mod:nn {#3} {#2}}
    
    \int_compare:nNnTF \l_col_int = 0 {
        \int_set:Nn \l_col_int { #2 }
    } {
        \int_set:Nn \l_row_int { \l_row_int + 1}
    }

    \drawstrike{#1}{\int_use:N \l_row_int}{\int_use:N \l_col_int}
}

\seq_new:N \l_notprime_seq

\int_new:N \l_tested_int
\int_new:N \l_striked_int
\int_new:N \l_max_int

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
    $\AutoNiceMatrix[
        hvlines, 
        columns - width = auto,
        name            = this-#1
    ]{
        #2-#2
    }{
        \cellval{#2}{\arabic{iRow}}{\arabic{jCol}}
    }$
   
    \int_set:Nn \l_tested_int { 1 }
    \int_set:Nn \l_max_int { #2*#2 }
    
    \int_while_do:nn {
         \l_tested_int <= #1
    } {
        \int_compare:nNnTF \l_tested_int = 1 {
            \strikeme{#1}{#2}{1}
            \seq_put_left:Nn \l_notprime_seq 1
        } {
%           \int_show:N \l_tested_int
%           \seq_show:N \l_notprime_seq

            \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_tested_int} {
                \int_set:Nn \l_striked_int { 2*\l_tested_int }
    
%               \int_show:N \l_striked_int
                
                \int_while_do:nn {
                    \l_striked_int <= \l_max_int
                } {
                    \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_striked_int} {
                        \strikeme{#1}{#2}{\int_use:N \l_striked_int}
                        \seq_put_left:Nx \l_notprime_seq {\int_use:N \l_striked_int}
                    }
    
                    \int_set:Nn \l_striked_int { \l_striked_int + \l_tested_int }         
                }
            }
        }
        
        \int_incr:N \l_tested_int
    }
}

\NewDocumentCommand\cellval{ mmm }{    
    \int_eval:n{#3 + #1*(#2 - 1)}
}

\ExplSyntaxOff


\begin{document}

\foreach \i in {0,...,4}{
    \begin{frame}
        \frametitle{Étape \i}
        \begin{center}
            \expandafter\eratosthenes\expandafter[\i]{10}
        \end{center}
    \end{frame}
}

\end{document}

相关内容