我开发了一个包,我想在其中定义一个命令\power
,但该名称已被SIunits
包中的命令(我的包使用)占用。我最初命名了我的命令\powr
,但决定尝试重命名该\power
命令SIunits
并在自己的包中使用\power
。问题是我显然遗漏了某些东西或做错了某些事情,因为我无法获得预期的结果。
(请注意,我目前不想使用siunitx
over SIunits
,尽管将来我会迁移到它。)
这是一个 MWE,它不包含我自己的包使用的所有包。我的主要问题是\square
重命名后它不起作用\power
,我根本不明白为什么。\sisquare
也不起作用,但我不使用它。我错过了什么?
\documentclass{article}
\usepackage{letltxmacro}
\usepackage{SIunits}
\newcommand*{\m}{\ensuremath{\mathrm{m}}
\LetLtxMacro{\sipower}{\power}
\renewcommand{\power}[1]{\ensuremath{#1 \; \mathrm{J/s}}}
\LetLtxMacro{\sisquare}{\square}
\renewcommand*{\square}[1]{\mathrm{#1}^{2}}
\renewcommand*{\squared}{\ensuremath{^{\mathrm{2}}}}
\renewcommand*{\cubic}[1]{\sipower{#1}{3}}
\renewcommand*{\cubed}{\ensuremath{^{\mathrm{3}}}}
\renewcommand*{\fourth}[1]{\sipower{#1}{4}}
\renewcommand*{\reciprocal}[1]{\sipower{#1}{\SIminus1}}
\renewcommand*{\rp}{\ensuremath{^{\mathrm{\SIminus1}}}}
\renewcommand*{\rpsquare}[1]{\sipower{#1}{\SIminus2}}
\renewcommand*{\rpsquared}{\ensuremath{^{\mathrm{\SIminus2}}}}
\renewcommand*{\rpcubic}[1]{\sipower{#1}{\SIminus3}}
\renewcommand*{\rpcubed}{\ensuremath{^{\mathrm{\SIminus3}}}}
\renewcommand*{\rpfourth}[1]{\sipower{#1}{\SIminus4}}
\begin{document}
\sipower{\m}{2} \par
\power{3} \par
$\sisquare\m$ \par
\square\m \par
\m\squared \par
\cubic\m \par
\m\cubed \par
\fourth\m \par
\reciprocal\m \par
\m\rp \par
\rpsquare\m \par
\m\rpsquared \par
\rpcubic\m \par
\m\rpcubed \par
\rpfourth\m
\end{document}
答案1
SIunits 包使用\AtBeginDocument
钩子来(重新)定义,\square
因为该宏名也被该amssymb
包用于(图形)正方形。
因此它提供了两个处理这种冲突的包选项:
amssymb
覆盖\square
而不备份amssymb
原始\square
宏。squaren
提供宏名称\squaren
并且\square
不做任何改动。
由于用户可能会在此重新定义问题amssymb
之后加载SIunits
,因此将其推迟到\begin{document}
(之后您将无法加载任何包):
%%%%%% siunits.sty, lines 75ff.
%%%%%% \typeout messages removed
%%%%%% Comments provided by me \%/
\AtBeginDocument{%
\ifredefsquare % option "amssymb": \square is overwritten
\providecommand{\square}[1]{\power{#1}{2}}
\renewcommand{\square}[1]{\power{#1}{2}}
\else
\ifdefsquaren % option "squaren": \squaren is defined
\providecommand{\squaren}[1]{\power{#1}{2}}
\renewcommand{\squaren}[1]{\power{#1}{2}}
\else % neither "amssymb" nor "squaren"
\@ifundefined{square}{% % if \square is undefined, define it (no amssymb)
\newcommand*{\square}[1]{\power{#1}{2}}
}{% % if \square is defined, yell at user:
\PackageWarningNoLine{SIunits}{% % "Use either amssymb or squaren option"
The command `square' was already defined.\MessageBreak
Possibly due to the amssymb package}
} %\ifundefined{square}
\fi %\ifsefsquaren
\fi %\ifredefsquare
} %\AtBeginDocument
解决问题的方法是让自己陷入其中\AtBeginDocument
并重新定义\square
。
我还进行了修补,\sisquare
因为它在内部定义,\power
您也可以重新定义(类似的原因,您需要用重新定义所有其他宏\sipower
)。
代码
\documentclass{article}
\usepackage{letltxmacro}
\usepackage{SIunits}
\newcommand*{\m}{\ensuremath{\mathrm{m}}}
\renewcommand*{\squared}{\ensuremath{^{\mathrm{2}}}}
\renewcommand*{\cubed}{\ensuremath{^{\mathrm{3}}}}
\renewcommand*{\cubic}[1]{\sipower{#1}{3}}
\renewcommand*{\fourth}[1]{\sipower{#1}{4}}
\renewcommand*{\reciprocal}[1]{\sipower{#1}{\SIminus1}}
\renewcommand*{\rpsquare}[1]{\sipower{#1}{\SIminus2}}
\renewcommand*{\rpcubic}[1]{\sipower{#1}{\SIminus3}}
\renewcommand*{\rpfourth}[1]{\sipower{#1}{\SIminus4}}
\renewcommand*{\rp}{\ensuremath{^{\mathrm{\SIminus1}}}}
\renewcommand*{\rpsquared}{\ensuremath{^{\mathrm{\SIminus2}}}}
\renewcommand*{\rpcubed}{\ensuremath{^{\mathrm{\SIminus3}}}}
\LetLtxMacro{\sipower}{\power}%
\renewcommand*{\power}[1]{\ensuremath{#1 \; \mathrm{J/s}}}%
\AtBeginDocument{%
\LetLtxMacro{\sisquare}{\square}%
\renewcommand*{\square}[1]{\mathrm{#1}^{2}}%
\renewcommand*{\sisquare}[1]{\sipower{#1}{2}}% to correct the output of the original square, now sisquare, command
}
\begin{document}
\sipower{\m}{5} \par
$\sisquare\m$ \par
\power{120} \par
$\square\m$ \par\bigskip
\m\squared \par
\cubic\m \par
\m\cubed \par
\fourth\m \par
\reciprocal\m \par
\m\rp \par
\rpsquare\m \par
\m\rpsquared \par
\rpcubic\m \par
\m\rpcubed \par
\rpfourth\m
\end{document}