我正在尝试实现一件(看似简单)的事情。我想定义一个自定义命令\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 的内部定义所取代
也许您想使用\providecommand
not\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}
对所有给定的情况都很有效。