如何将 a 的范围限制\newcommand
为 a \section
?这就是我想要的:
- 该命令仅在内部定义
\section
,而不是全局定义; - 命令范围就是它本身
\section
,在其之外是看不到的; - a 是否看到该命令并不重要
\subsection
(如果它也看到该命令,那可能就说得通了);并且 - 可以在不同的命令中再次定义该命令
\section
而不会产生错误(我知道这\renewcommand
可以解决它,但如果可能的话我愿意使用它\newcommand
)。
我所拥有的是(由于这两个定义而产生错误):
\documentclass{article}
\begin{document}
\section{First section}
\newcommand*{\blipo}{Jill}
Hello \blipo{}. \blipo{} is blonde.
\section{Second section}
\newcommand*{\blipo}{ET}
Hello \blipo{}. \blipo{} is green.
\section{Third section}
Not defined here. Attempt to use it generates error.
\end{document}
[编辑] 就我的具体情况而言,我将\newcommand
在一个部分中拥有大约 20-30 个不同的内容,这些内容可能会或可能不会在文档的不同部分中使用(重新定义)。
答案1
您可以添加代码\section
以使其\blipo
未定义:
\documentclass{article}
\usepackage{etoolbox}
\preto\section{\undef\blipo}
\begin{document}
\section{First section}
\newcommand*{\blipo}{Jill}
Hello \blipo{}. \blipo{} is blonde.
\section{Second section}
\newcommand*{\blipo}{ET}
Hello \blipo{}. \blipo{} is green.
\section{Third section}
Not defined here. Attempt to use it generates error.
\blipo{}
\end{document}
以下是终端会话的一部分:
! Undefined control sequence.
l.19 \blipo
{}
?
对于更通用的版本,如果您希望在每个部分中有几个命令未定义,请使用以下列表处理函数etoolbox
:
\documentclass{article}
\usepackage{etoolbox}
%%% The helper macros
\newcommand{\onlysectioncommands}[1]{%
\forcsvlist{\listadd\sectioncommandslist}{#1}}
\preto\section{%
\forlistloop{\undef}{\sectioncommandslist}}
%%% Here we set the special commands; the
%%% list can be augmented anywhere
\onlysectioncommands{\blipo,\foo}
\begin{document}
\section{First section}
\newcommand*{\blipo}{Jill}
\newcommand{\foo}{foo}
Hello \blipo{}. \blipo{} is blonde. \foo
\section{Second section}
\newcommand*{\blipo}{ET}
\newcommand{\foo}{bar}
Hello \blipo{}. \blipo{} is green. \foo
\section{Third section}
\newcommand{\foo}{baz}
Not defined here. Attempt to use it generates error.
\blipo{}
\foo
\end{document}
我们在\preto
的开头添加代码\section
。如果您使用的类或包重新定义\section
,则可能需要使用
\usepackage{xpatch}
\xpretocmd{\section}
{\forlistloop{\undef}{\sectioncommandslist}}
{}{}
反而。
2023 年更新
利用 LaTeX 内核的当前特性:
\documentclass{article}
\ExplSyntaxOn
\clist_new:N \g_daniel_onlysection_commands_clist
\NewDocumentCommand{\onlysectioncommands}{m}
{
\clist_gput_right:Nn \g_daniel_onlysection_commands_clist { #1 }
}
\AddToHook{cmd/section/before}
{
\clist_map_function:NN \g_daniel_onlysection_commands_clist \cs_undefine:N
}
\ExplSyntaxOff
%%% Here we set the special commands and
%%% the list can be augmented anywhere
\onlysectioncommands{\blipo,\foo}
\begin{document}
\section{First section}
\newcommand*{\blipo}{Jill}
\newcommand{\foo}{foo}
Hello \blipo{}. \blipo{} is blonde. \foo
\section{Second section}
\newcommand*{\blipo}{ET}
\newcommand{\foo}{bar}
Hello \blipo{}. \blipo{} is green. \foo
\section{Third section}
\newcommand{\foo}{baz}
\verb|\blipo| is not defined here, attempt to use it generates error.
\blipo{}
\foo
\end{document}
答案2
看起来这个问题可以通过用括号括起来来解决。一个最简单的例子如下:
\documentclass[10pt,a4paper]{article}
\begin{document}
\section{Section A}
{
\newcommand{\sectionowner}{me}
This section belongs to \sectionowner
}
\section{Section B}
{
\newcommand{\sectionowner}{you}
This section belongs to \sectionowner
}
\end{document}
\sectionowner
其中使用 定义了两次命令\newcommand
。
答案3
使用\renewcommand
:
\documentclass{article}
\begin{document}
\section{First section}
\newcommand*{\blipo}{Jill}
Hello \blipo{}. \blipo{} is blonde.
\section{Second section}
\renewcommand*{\blipo}{ET}
Hello \blipo{}. \blipo{} is green.
\section{Third section}
Not defined here. Attempt to use it generates error.
\end{document}