TeX 扩展失败

TeX 扩展失败

我正在尝试实现一件(看似简单)的事情。我想定义一个自定义命令\Symbol,它接收单个参数并打印该参数。此外,我还想有另一系列命令来修改 的输出,\Symbol即和。我想要实现的是可以任意嵌套符号的样式。例如,我可以将全局符号定义为\PutSymbolSubscript\PutSymbolSuperscript\PutSymbolModifier

\newcommand{\VectorI}{\PutSymbolSubscript{\Symbol{\boldsymbol{x}}}{i}}

此外,我可以定义另一种全局样式

\newcommand{\estimate}{\hat}

然后我可以通过书写将两者结合起来\estimate{\VectorI},其呈现形式为\hat{\boldsymbol{x}}_i

我目前拥有的是

\documentclass{article}
\usepackage[utf8]{inputenc}

% the "Symbol" framework --------------------------------
\newcommand{\Symbol}[1]{%
    \ifdefined\symbolmodifier%
        \let\tmp\symbolmodifier%
        \let\symbolmodifier\undefined%
        \tmp{#1}%
    \else%
        #1%
    \fi%
    \ifdefined\symbolsubscript%
        \let\tmp\symbolsubscript
        \let\symbolsubsript\undefined
        _{\tmp}%
    \fi%
    \ifdefined\symbolsuperscript%
        \let\tmp\symbolsuperscript%
        \let\symbolsuperscript\undefined%
        ^{\tmp}%
    \fi%
}

\newcommand{\PutSymbolSubscript}[2]{{%
    \newcommand{\symbolsubscript}{#2}       % (C1)
    #1
}}

\newcommand{\PutSymbolSuperscript}[2]{{%
    \newcommand{\symbolsuperscript}{#2}     % (C2)
    #1
}}

\newcommand{\PutSymbolModifier}[2]{{%
    \let\symbolmodifier#2
    #1
}}

% some global definitions --------------------------------------------------

\newcommand{\PutSampleIdx}[2]{\PutSymbolSuperscript{#1}{(#2)}}
\newcommand{\NTrainSamples}{N}
\newcommand{\estimate}[1]{\PutSymbolModifier{#1}{\hat}}

% test it ----------------------------------------------------------------

\begin{document}

\begin{equation}
    \PutSymbolSubscript{\Symbol{A}}{i}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\Symbol{B}}{(2)}\Symbol{C}
\end{equation}

\begin{equation}
    \estimate{\Symbol{C}}\Symbol{D}
\end{equation}

\begin{equation}
    \PutSampleIdx{a}{1}
\end{equation}

%\begin{equation}
%    \PutSymbolSubscript{\Symbol{X}}{\Symbol{N}}
%\end{equation}

\end{document}

所有这些情况都按预期工作,除了最后一个(注释掉的)情况,它以 失败TeX capacity exceeded。虽然我并没有真正找出它失败的原因,但我注意到我可以通过在标有和 的行中用\newcommand相应的替换 来解决这个问题。然而,即使这样,以下操作也会失败:\edef(C1)(C2)

\PutSymbolSubscript{\PutSymbolSubscript{\Symbol{X}}{\Symbol{N}}}{\Symbol{M}}

在这里,我断言外部\PutSymbolSuperscripts超越内部,因此这应该呈现为X_M

在更复杂的文档中,我甚至会遇到inaccessible错误。然而,这些情况很难用 MWE 重现。

有人能帮助我正确实现这个小“符号框架”吗?

如果你想知道我为什么要这样做:我想全局定义符号,以便以后可以更改它们。但是,符号可能有很多变体(具有不同的索引和修饰符),全局定义所有变体很麻烦。另一方面,简单的模块化方法(例如定义\newcommand{\estimate}{\hat}和并将\newcommand{\VectorI}{x_i}其用作)显然不是我想要的。因此,我想以这种模块化的方式来做。我认为这应该是可能的,对吧?\estimate{\VectorI}\hat{x_i}

答案1

包裹semantex(免责声明:我是作者)可以做很多你想要的事情,尽管使用的是基于 keyval 的接口。它还允许任意嵌套。在下面的代码示例中,我试图复制我思考你要。

\documentclass{article}

\usepackage{amsmath,semantex}

\NewVariableClass\MyVar[
    output=\MyVar,
    define keys={
        {estimate}{ command=\hat },
    },
    define keys[1]={
        {der}{ upper={(#1)} },
        %in case ^{(2)} means derived 2 times
    },
]

\NewObject\MyVar\vA{A}
\NewObject\MyVar\vB{B}
\NewObject\MyVar\vC{C}
\NewObject\MyVar\vD{D}
\NewObject\MyVar\vX{X}
\NewObject\MyVar\vN{N}
\NewObject\MyVar\va{a}
\NewObject\MyVar\vi{i}

\NewObject\MyVar\vectorI{\boldsymbol{x}}[lower=\vi]

\begin{document}

\begin{equation}
    \vA[\vi]
\end{equation}

\begin{equation}
    \vB[der=2] \vC
\end{equation}

\begin{equation}
    \vC[estimate] \vD
\end{equation}

\begin{equation}
    \va[1]
\end{equation}

\begin{equation}
    \vX[\vN]
\end{equation}

Nesting arbitrarily:

\begin{equation}
    \vectorI[estimate,der=5,der=3]
\end{equation}

\end{document}

在此处输入图片描述


如果您确实想坚持使用当前语法,则可以执行以下操作。如果您确实希望嵌套的PutSymbolSubscript覆盖先前的 ,则可以替换upper={#2}bydata set={upper}{#2}lower={#2}by data set={lower}{#2}

\documentclass{article}

\usepackage{amsmath,semantex}

\NewVariableClass\Symbol[
    output=\Symbol,
]

\newcommand{\PutSymbolSubscript}[2]{{%
    \Symbol{#1}[lower={#2}]%
}}

\newcommand{\PutSymbolSuperscript}[2]{{%
    \Symbol{#1}[upper={#2}]%
}}

\newcommand{\PutSymbolModifier}[2]{{%
    \Symbol{#1}[command={#2}]%
}}

% some global definitions --------------------------------------------------

\newcommand{\PutSampleIdx}[2]{\PutSymbolSuperscript{#1}{(#2)}}
\newcommand{\NTrainSamples}{N}
\newcommand{\estimate}[1]{\PutSymbolModifier{#1}{\hat}}

% test it ----------------------------------------------------------------

\begin{document}

\begin{equation}
    \PutSymbolSubscript{\Symbol{A}}{i}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\Symbol{B}}{(2)}\Symbol{C}
\end{equation}

\begin{equation}
    \estimate{\Symbol{C}}\Symbol{D}
\end{equation}

\begin{equation}
    \PutSampleIdx{a}{1}
\end{equation}

\begin{equation}
    \PutSymbolSubscript{\Symbol{X}}{\Symbol{N}}
\end{equation}

\end{document}

在此处输入图片描述

答案2

您的定义\Symbol包含一个拼写错误:

\newcommand{\Symbol}[1]{%
    \ifdefined\symbolmodifier%
        \let\tmp\symbolmodifier%
        \let\symbolmodifier\undefined%
        \tmp{#1}%
    \else%
        #1%
    \fi%
    \ifdefined\symbolsubscript%
        \let\tmp\symbolsubscript
        \let\symbolsubsript\undefined
        _{\tmp}%
    \fi%
    \ifdefined\symbolsuperscript%
        \let\tmp\symbolsuperscript%
        \let\symbolsuperscript\undefined%
        ^{\tmp}%
    \fi%
}

有这样一行:\let\symbolsubsript\undefined

c仅缺少一个小字母。

它应该是:\let\symbolsubscript\undefined

因此定义应该是:

\newcommand{\Symbol}[1]{%
    \ifdefined\symbolmodifier
        \let\tmp\symbolmodifier
        \let\symbolmodifier\undefined
        \tmp{#1}%
    \else
        #1%
    \fi
    \ifdefined\symbolsubscript
        \let\tmp\symbolsubscript
        \let\symbolsubscript\undefined % <--- !!!!!
        _{\tmp}%
    \fi
    \ifdefined\symbolsuperscript
        \let\tmp\symbolsuperscript
        \let\symbolsuperscript\undefined
        ^{\tmp}%
    \fi
}

经过轻微修改,序列

\begin{equation}
    \PutSymbolSubscript{\Symbol{X}}{\Symbol{N}}
\end{equation}

不会产生以capacity exceeded-error 结尾的循环。



让我们添加另一种方法,基于交换参数而不是定义\tmp

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}

% Paraphernalia -------------------------------------------
\newcommand\exchange[2]{#2#1}%
\newcommand\firstoftwo[2]{#1}%
\newcommand\secondoftwo[2]{#2}%
\newcommand\firstofone[1]{#1}%

% the "Symbol" framework --------------------------------
\newcommand*\symbolsubscript{}%
\newcommand*\symbolsubscriptdefault{}%
\newcommand*\symbolsuperscript{}%
\newcommand*\symbolsuperscriptdefault{}%
\newcommand*\symbolmodifier{\firstofone}%
\newcommand*\symbolmodifierdefault{\firstofone}%

\newcommand{\Symbol}[1]{%
  \expandafter\exchange\expandafter{\symbolsuperscript}{%
    \expandafter\exchange\expandafter{\symbolsubscript}{%
      \ifx\symbolsubscript\symbolsubscriptdefault
        \ifx\symbolsuperscript\symbolsuperscriptdefault
          \expandafter\expandafter\expandafter\firstofone
        \else
          \global\let\symbolsuperscript\symbolsuperscriptdefault
        \fi
      \else
        \global\let\symbolsubscript\symbolsubscriptdefault
        \ifx\symbolsuperscript\symbolsuperscriptdefault\else
          \global\let\symbolsuperscript\symbolsuperscriptdefault
        \fi
      \fi
      {%
        \expandafter\exchange\expandafter{\symbolmodifier}{%
          \ifx\symbolmodifier\symbolmodifierdefault\else
            \global\let\symbolmodifier\symbolmodifierdefault
          \fi
        }%
        {#1}%
      }%
    }%
  }%
}%

\newcommand{\PutSymbolSubscript}[2]{%
  \ifx\symbolsubscript\symbolsubscriptdefault
    \xdef\symbolsubscript{\unexpanded{_{#2}}}%
  \fi
  #1%
}

\newcommand{\PutSymbolSuperscript}[2]{%
  \ifx\symbolsuperscript\symbolsuperscriptdefault
    \xdef\symbolsuperscript{\unexpanded{^{#2}}}%
  \fi
  #1%
}

\newcommand{\PutSymbolModifier}[2]{%
    \ifx\symbolmodifier\symbolmodifierdefault
       \xdef\symbolmodifier{\unexpanded{#2}}%
    \fi
    #1%
}

% some global definitions --------------------------------------------------

\newcommand{\PutSampleIdx}[2]{\PutSymbolSuperscript{#1}{(#2)}}
\newcommand{\NTrainSamples}{N}
\newcommand{\estimate}[1]{\PutSymbolModifier{#1}{\hat}}
\newcommand{\VectorI}{\PutSymbolSubscript{\Symbol{\boldsymbol{x}}}{i}}

% test it ----------------------------------------------------------------

\begin{document}

\begin{equation}
    \PutSymbolSubscript{\Symbol{A}}{i}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\Symbol{B}}{(2)}\Symbol{C}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\estimate{\Symbol{C}}}{2}\Symbol{D}
\end{equation}

\begin{equation}
    \PutSampleIdx{\Symbol{a}}{1}
\end{equation}

\begin{equation}
    \PutSymbolSubscript{\Symbol{X}}{\Symbol{N}}
\end{equation}

\begin{equation}
    \PutSymbolSubscript{\PutSymbolSubscript{\Symbol{X}}{M}}{\Symbol{N}}
\end{equation}

\begin{equation}
    \PutSymbolSubscript{\PutSymbolSuperscript{\PutSymbolSubscript{\Symbol{X}}{V}}{\Symbol{M}}}{a}
\end{equation}

\begin{equation}
    \PutSymbolSubscript{\Symbol{X}}{a}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\Symbol{X}}{M}
\end{equation}


\[\hat{\boldsymbol{x}}_i\]

\[\estimate{\VectorI}\]

\end{document}

在此处输入图片描述

答案3

很难猜测这里的意图,所以我只评论一下

\PutSymbolSubscript{\PutSymbolSubscript{\Symbol{X}}{\Symbol{N}}}{\Symbol{M}}

在这里,我断言外部\PutSymbolSuperscripts超越内部,因此这应该呈现为X_M

外部调用根本没用。

你有

\newcommand{\PutSymbolSuperscript}[2]{{%
    \newcommand{\symbolsuperscript}{#2}     % (C2)
    #1
}}

因此引用的调用是,经过一次扩展

{%
    \newcommand{\symbolsuperscript}{\Symbol{M}}     % (C2)
    \PutSymbolSubscript{\Symbol{X}}
}

因此这从开始一个组{并定义\symbolsuperscript为 M,但下一个扩展产生

{%
    \newcommand{\symbolsuperscript}{\Symbol{M}}     % (C2)
    {%
       \newcommand{\symbolsuperscript}{\Symbol{N}}     % (C2)
        \Symbol{X}
    }
}

因此,第一个定义对 M 从未使用过,它被对 N 的内部定义所取代

也许您想使用\providecommandnot\newcommand以便内部调用仅定义您的修饰符(如果它们尚未定义),但老实说,很难猜测这里预期的行为。

答案4

总结了很多提示,我最终得出

\documentclass{article}
\usepackage[utf8]{inputenc}

% the "Symbol" framework --------------------------------
\newcommand{\Symbol}[1]{%
    \ifdefined\symbolmodifier%
        \let\tmp\symbolmodifier%
        \let\symbolmodifier\undefined%
        \tmp{#1}%
    \else%
        #1%
    \fi%
    \ifdefined\symbolsubscript%
        \let\tmp\symbolsubscript
        \let\symbolsubscript\undefined
        _{\tmp}%
    \fi%
    \ifdefined\symbolsuperscript%
        \let\tmp\symbolsuperscript%
        \let\symbolsuperscript\undefined%
        ^{\tmp}%
    \fi%
}

\newcommand{\PutSymbolSubscript}[2]{%
    \providecommand{\symbolsubscript}{#2}
    #1
}

\newcommand{\PutSymbolSuperscript}[2]{%
    \providecommand{\symbolsuperscript}{#2}
    #1
}

\newcommand{\PutSymbolModifier}[2]{%
    \let\symbolmodifier#2
    #1
}

% some global definitions --------------------------------------------------

\newcommand{\PutSampleIdx}[2]{\PutSymbolSuperscript{#1}{(#2)}}
\newcommand{\NTrainSamples}{N}
\newcommand{\estimate}[1]{\PutSymbolModifier{#1}{\hat}}

% test it ----------------------------------------------------------------

\begin{document}

\begin{equation}
    \PutSymbolSubscript{\Symbol{A}}{i}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\Symbol{B}}{(2)}\Symbol{C}
\end{equation}

\begin{equation}
    \PutSymbolSuperscript{\estimate{\Symbol{C}}}{2}\Symbol{D}
\end{equation}

\begin{equation}
    \PutSampleIdx{\Symbol{a}}{1}
\end{equation}

\begin{equation}
    \PutSymbolSubscript{\PutSymbolSubscript{\Symbol{X}}{M}}{\Symbol{N}}
\end{equation}

\end{document}

对所有给定的情况都很有效。

相关内容