增加参数和全局 xparse 宏的嵌套级别?

增加参数和全局 xparse 宏的嵌套级别?

这有点像一个双重问题,但对我来说却紧密相关。灵感来自https://tex.stackexchange.com/a/55769/14159我尝试制作一个改进的版本,允许为定义的符号添加附加参数。

这是我当前的代码:

\documentclass{article}
\usepackage{xparse}
\usepackage{nomencl}
\usepackage{xcolor}

% colorize to distinguish original and renewed command
\NewDocumentCommand{\defsym}{mmmmm} {%
    \NewDocumentCommand{#1}{#2}{%
        \RenewDocumentCommand{#1}{#2}{\textcolor{blue}{#4}}
        \nomenclature{$#1$}{#5}
        \textcolor{red}{#3}
    }
}

\defsym\Uk{O{k}}{U_{#1}}{U_{##1}}{Some variable}

\makenomenclature

\begin{document}
\noindent$\Uk[j]$,$\Uk,$ $\Uk[p], \Uk[q]$ and $\Uk[r]$
\printnomenclature
\end{document}

上述代码的结果


现在我面临的两个问题是

  1. 双重定义#3非常#4丑陋,是否有一些宏可以增加嵌套级别,即在每个参数中添加一个#?这样我就可以写\incnest{#3}而不是#4
  2. 定义\RenewDocumentCommand不是全局的,所以除了 之外的所有 U\Uk[q]都是红色的。xparse 中是否有与\global或等价的东西。我在 中\gdef找到了类似的\renewcommand\global\renewcommand 相当于 \global\def但它有点不合常理。

欢迎提供任何能使其正常工作的技巧或解决方法。

答案1

这个全局重定义的问题无法用来解决\RenewDocumentCommand;通过更深层次的expl3编程,可以通过设置一个开关(布尔值)来解决。

\documentclass{article}
\usepackage{xparse}
\usepackage{nomencl}
\usepackage{xcolor}

% colorize to distinguish original and renewed command
\ExplSyntaxOn
% #1 = command name
% #2 = definition
% #3 = default optional argument
% #4 = description
\NewDocumentCommand{\defsym}{mmmm}
  {
   \bool_new:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \bool_gset_false:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \buergi_defsym:nnnn { #1 } { #2 } { #3 } { #4 }
  }
\cs_new_protected:Npn \buergi_defsym:nnnn #1 #2 #3 #4
 {
  \NewDocumentCommand{#1}{O{#3}}
   {
    \bool_if:cTF  { g_buergi_sym_ \cs_to_str:N #1 _bool }
     { \textcolor{blue}{#2} }
     {
      \textcolor{red}{#2}
      \nomenclature{$#1$}{#4}
      \bool_gset_true:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
     }
   }
 }
\ExplSyntaxOff

\defsym\Uk{U_{#1}}{k}{Some variable}
\defsym\Ak{A(#1)}{k}{Another}

\makenomenclature

\begin{document}
\noindent $\Uk[j]$, $\Uk$, $\Uk[p]$, $\Uk[q]$ and $\Uk[r]$

\noindent $\Ak$, $\Ak[n]$
\printnomenclature
\end{document}

如您所见,您可以在第二个参数中给出任何表示#1可选参数的标记列表,我将其放在第三个。只是个人喜好,如果您想切换第二个和第三个参数,只需将第一个定义更改为

\NewDocumentCommand{\defsym}{mmmm}
  {
   \bool_new:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \bool_gset_false:c { g_buergi_sym_ \cs_to_str:N #1 _bool }
   \buergi_defsym:nnnn { #1 } { #3 } { #2 } { #4 }
  }

该命令\defsym首先根据第一个参数定义一个布尔开关,并将其设置为 false;然后执行核心函数,该函数完成所需的操作\NewDocumentCommand;因此,\Uk如果布尔值为真,则以蓝色表示正常工作,否则以红色表示工作。在命名法文件中注释用法和全球将布尔值设置为 true。

在此处输入图片描述

相关内容