在证明定理时,我有时会定义任意常数,然后引用它们。这些常数并不重要,而且在证明之后也不需要记住。这就是为什么我通常采用一种符号,即每次需要定义新常数时,C_i
索引都会增加。i
我想知道我是否可以自动执行此操作。特别是因为当我重新整理校样时,我必须返回并确保索引在我的手稿中是有序的。
我的理想设置是定义两个命令\resetconstants
并\const
执行如下操作
\resetconstants{D}
This is my first constant \const{name1} and my second constant \const{name2}
but I can also reference my first constant \const{name1}
\resetconstants{E}
New constants are here \const{name1}
\resetconstants{D}
Resetting constants means that previous ones are completely
forgotten so that \const{name1} is a brand new constant.
输出将是
This is my first constant D_1 and my second constant D_2
but I can also reference my first constant D_1.
New constants are here E_1.
Resetting constants means that previous ones are completely
forgotten so that D_1 is a new constant.
我该如何实现这个?我知道如何定义计数器,但不知道如何定义键值查找表。有没有一个包可以更容易地实现这个?
答案1
这是一个裸乳胶方法。排版由其\rc@useconst
第一个参数是字母,第二个参数是与当前常量关联的数字来控制。如果您想更改常量的显示方式,只需更改此宏的定义即可。
\documentclass{article}
\makeatletter
\newcount\rc@count
\rc@count=1\relax
% initialize list of constants
\let\rc@clearconstantlist\empty
% This command takes the name of a constant and undefines it.
\newcommand\rc@clearconstant[1]{\global\expandafter\let\csname rc@const@#1\endcsname\undefined}
% Iterate over the lists of
\newcommand\resetconstants[1]{%
\def\rc@constname{#1}% Set the new base name of the constants to the argument
\global\rc@count=1\relax % Reset the constant counter to 1
\bgroup
\let\\\rc@clearconstant % map over the list of constants that have been defined, clearing each of them.
\rc@clearconstantlist
\global\let\rc@clearconstantlist\empty % Globally empty the list of constants.
\egroup
}
\newcommand\const[1]{%
\@ifundefined{rc@const@#1}{%
% Globally store the expansion of the current constant in a macro
\expandafter\xdef\csname rc@const@#1\endcsname{%
\noexpand\rc@useconst{\rc@constname}{\the\rc@count}%
}%
% Add this macro to the list of things that need to be cleared.
\g@addto@macro\rc@clearconstantlist{\\{#1}}%
\global\advance\rc@count1\relax
}{}%
% Display the output
\csname rc@const@#1\endcsname
}
% Redefine this command to change the way that the constants are typeset.
% #1 -- the letter, i.e., D or E
% #2 -- the number of the constant, i.e., 1, 2
\newcommand\rc@useconst[2]{{#1}\textsubscript{#2}}
\makeatother
\begin{document}
\resetconstants{D}
This is my first constant \const{name1} and my second constant \const{name2}
but I can also reference my first constant \const{name1}
\resetconstants{E}
New constants are here \const{name1}
\resetconstants{D}
Resetting constants means that previous ones are completely
forgotten so that \const{name1} is a brand new constant.
\end{document}
我使用的是标准 tex 列表迭代技术,即将列表存储为\mylist
具有主体的宏\\{first-entry}\\{second-entry}...\\{last-entry}
。因此,空列表只是一个具有空扩展文本的零参数宏。要初始化空列表或清空我已经拥有的列表,我只需说\let\mylist\empty
。要向列表添加元素,我使用\g@addto@macro\mylist{\\{new-entry}}
。宏\g@addto@macro
全局将文本添加到没有参数的宏主体中。
为了迭代此列表,我们将重新定义\\
为迭代器,然后扩展。应该在本地\mylist
重新定义,因为已经做了其他事情。\\
\\
\bgroup % ensure local scope
\let\\\rc@clearconstant % The function I'm mapping over my list is \rc@clearconstant
\rc@clearconstantlist % Map over the list, clearing each constant
\global\let\rc@clearconstantlist\empty % Globally empty the list of constants.
\egroup % This ends the scope and the value of `\\` is restored.
答案2
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\int_new:N \g_tohi_const_int
\int_new:N \g_tohi_const_sub_int
\tl_new:N \g_tohi_const_char_tl
\cs_new_protected:Nn \tohi_print_constant:nn
{
#1 \textsubscript {#2}
}
\NewDocumentCommand\resetconstants{m}
{
\int_gincr:N \g_tohi_const_int
\int_gzero:N \g_tohi_const_sub_int
\tl_gset:Nn \g_tohi_const_char_tl {#1}
}
\NewDocumentCommand\const{m}
{
\tl_if_exist:cTF
{
c_tohi_const_\int_use:N\g_tohi_const_int _#1_tl
}
{
\tl_use:c {c_tohi_const_\int_use:N\g_tohi_const_int _#1_tl }
}
{
\int_gincr:N \g_tohi_const_sub_int
\tl_const:cx {c_tohi_const_\int_use:N\g_tohi_const_int _#1_tl }
{ \exp_not:N\tohi_print_constant:nn {\g_tohi_const_char_tl }{\int_use:N \g_tohi_const_sub_int}}
\tl_use:c {c_tohi_const_\int_use:N\g_tohi_const_int _#1_tl }
}
}
\ExplSyntaxOff
\begin{document}
\resetconstants{D}
This is my first constant \const{name1} and my second constant \const{name2}
but I can also reference my first constant \const{name1}
\resetconstants{E}
New constants are here \const{name1}
\resetconstants{D}
Resetting constants means that previous ones are completely
forgotten so that \const{name1} is a brand new constant.
\end{document}
答案3
\resetconstants
您可以使用在发布时清除的属性列表。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\const}{m}
{
\tohiko_constant_use:n { #1 }
}
\NewDocumentCommand{\resetconstants}{m}
{
\tohiko_constant_reset:n { #1 }
}
\int_new:N \g_tohiko_constant_count_int
\tl_new:N \g_tohiko_constant_name_tl
\prop_new:N \g_tohiko_constant_prop
\cs_new_protected:Nn \tohiko_constant_use:n
{
\prop_if_in:NnF \g_tohiko_constant_prop { #1 }
{
\int_gincr:N \g_tohiko_constant_count_int
\prop_gput:Nnx \g_tohiko_constant_prop
{ #1 }
{ \int_to_arabic:n { \g_tohiko_constant_count_int } }
}
\ensuremath
{
\tl_use:N \g_tohiko_constant_name_tl
\sb { \prop_item:Nn \g_tohiko_constant_prop { #1 } }
}
}
\cs_new_protected:Nn \tohiko_constant_reset:n
{
\tl_gset:Nn \g_tohiko_constant_name_tl { #1 }
\prop_clear:N \g_tohiko_constant_prop
\int_gzero:N \g_tohiko_constant_count_int
}
\ExplSyntaxOff
\begin{document}
\resetconstants{D}
This is my first constant \const{name1} and my second constant \const{name2}
but I can also reference my first constant \const{name1}
\resetconstants{E}
New constants are here \const{name1}
\resetconstants{D}
Resetting constants means that previous ones are completely
forgotten so that \const{name1} is a brand new constant.
\end{document}