编辑

编辑

以下文件获取了 !TeX 容量超出,抱歉 [输入堆栈大小=5000]。如果我删除对 \tl_gput_right:Nn 的调用,则它会成功编译。

\documentclass{article}
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{mathtools}
\usepackage{xparse} % loads expl3
%See interface3.pdf

\ExplSyntaxOn

\NewDocumentCommand{\uqual}{mm}
 {
   \int_compare:nTF { \tl_count:n { #1 } > 1 }
     {
       Extended \ parm \ #1 \
       \bool_gset_true:N \g_tmpa_bool
       \tl_gclear:N \g_tmpa_tl
       \tl_map_inline:nn{#1}
       {
         mapping \ ##1 \
         \if_bool:N \g_tmpa_bool
           {
             first \ item \ ##1 \
             \bool_gset_false:N \g_tmpa_bool
              \tl_gset_eq:NN \g_tmpa_tl ##1
           } \else: {
             next \ item \ ##1
             \tl_gput_right:Nn \g_tmpa_tl {xx ##1}
           } \fi:
       }
       test \ tokenlist=\g_tmpa_tl \
       \expandafter
         \left ( {\forall}_{ \g_tmpa_tl} \right ) #2
     }
     {
        single \ parm \ #1 \
       \expandafter
         \left ( {\forall}_{#1} \right ) #2
     }
 }

\ExplSyntaxOff

\begin{document}

$\uqual{{X}}{P(X.Y)}$

$\uqual{{X}{Y}}{P(X,Y)}$

\end{document}

答案1

执行 时会出现错误\tl_gset_eq:NN \g_tmpa_tl ##1,因为##1通常不会以控制序列变量开头,即使如此,结果也不是您想要的。

请记住,N表示应由单个标记组成的参数;特别是,\tl_gset_eq:NN使作为第一个参数给出的标记列表变量全局等于作为第二个参数给出的标记列表变量(如果您询问,则没有强制)。

带括号的参数在函数名称中用 表示n。你真正想要的是

\tl_gset:Nn \g_tmpa_tl { ##1 }

(全局设置\g_tmpa_tl为给定的参数)。

但是,还有其他部分需要整理。例如,您在不需要的地方使用了全局设置和变量。此外,

\if_bool:N <boolean>
  <true text>
\else:
  <false text>
\fi:

不是推荐的编码;无论如何,真假文本应该不是做好准备(这可能是你使用全局分配的原因);最好这样做

\bool_if:NTF <boolean>
 {
  <true text>
 }
 {
  <false text>
 }

的问题_很容易解决;因为在expl3语法中它是宏名称的一部分,当您想要表示数学下标时,请使用\c_math_subscript_token

但是,有更简单的方法来完成您的任务(我猜是在第一个参数中列出用逗号分隔的变量):

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse} % loads expl3

\ExplSyntaxOn

\seq_new:N \l_shmuel_uqual_seq

\NewDocumentCommand{\uqual}{mm}
 {
  \seq_set_split:Nnn \l_shmuel_uqual_seq { } { #1 }
  ( \forall \c_math_subscript_token { \seq_use:Nn \l_shmuel_uqual_seq { , } } ) #2
 }

\ExplSyntaxOff

\begin{document}

$\uqual{X}{P(X.Y)}$

$\uqual{XY}{P(X,Y)}$

\end{document}

这意味着:将第一个参数“完全”拆分\tl_map_inline:nn成一个序列(与 所做的除法相同);然后用逗号分隔项来传递该序列。

在此处输入图片描述

如果要堆叠第一个参数中给出的变量,请按如下所示更改宏:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse} % loads expl3

\ExplSyntaxOn

\seq_new:N \l_shmuel_uqual_seq

\NewDocumentCommand{\uqual}{mm}
 {
  \seq_set_split:Nnn \l_shmuel_uqual_seq { } { #1 }
  ( 
  \forall \c_math_subscript_token
   {
    \substack{  \seq_use:Nn \l_shmuel_uqual_seq { \\ } } 
   }
  ) #2
 }

\ExplSyntaxOff

\begin{document}

$\uqual{X}{P(X.Y)}$

$\uqual{XY}{P(X,Y)}$

\end{document}

在此处输入图片描述

答案2

\tl_gset_eq:NN 

需要两个类型为 和 的参数N,而不是一个类型为N和一个类型为 的参数n

你想要的只是

\tl_gset:Nn \g_tmpa_tl {##1}

效果很好。

编辑

如果我只是用上面的替换替换我提到的行,代码就可以正常工作。这并不是说不需要对预期功能进行其他更改(无论它是什么),也不是说以不同的方式执行某些操作可能不明智,但它肯定不会编译失败。

那是,

\documentclass{article}
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{mathtools}
\usepackage{xparse} % loads expl3
%See interface3.pdf

\ExplSyntaxOn

\NewDocumentCommand{\uqual}{mm}
 {
   \int_compare:nTF { \tl_count:n { #1 } > 1 }
     {
       Extended \ parm \ #1 \
       \bool_gset_true:N \g_tmpa_bool
       \tl_gclear:N \g_tmpa_tl
       \tl_map_inline:nn{#1}
       {
         mapping \ ##1 \
         \if_bool:N \g_tmpa_bool
           {
             first \ item \ ##1 \
             \bool_gset_false:N \g_tmpa_bool
              \tl_gset:Nn \g_tmpa_tl {##1}
           } \else: {
             next \ item \ ##1
             \tl_gput_right:Nn \g_tmpa_tl {xx ##1}
           } \fi:
       }
       test \ tokenlist=\g_tmpa_tl \
       \expandafter
         \left ( {\forall}_{ \g_tmpa_tl} \right ) #2
     }
     {
        single \ parm \ #1 \
       \expandafter
         \left ( {\forall}_{#1} \right ) #2
     }
 }

\ExplSyntaxOff

\begin{document}

$\uqual{{X}}{P(X.Y)}$

$\uqual{{X}{Y}}{P(X,Y)}$

\end{document}

编译无错误。我不知道输出是否是您想要的,但它确实生成了 PDF。

输出

相关内容