我想创建一个命令,根据其参数创建一个新的部分或子部分(或子子部分或...)。为什么调用\section
和\subsection
via\csname
似乎根本不起作用,我该如何修复它?MWE:
\documentclass{article}
\newcommand{\democmd}[2]{%
\csname #1section \endcsname{#2}%
}
\begin{document}
% Doesn't (visibly, at least) make a subsection.
\democmd{sub}{Should Make a Section}
% Also does not make a section.
\csname section \endcsname{foo}
\end{document}
编辑:修复版本是\csname section\endcsname{foo}
,节后没有空格。但为什么有些宏,如textbf
,会像\csname textbf \endcsname{foo}
与空间,而其他人,如section
和ref
,则没有?
答案1
初步说明在后续中,•
表示代码中的空格,只是为了清楚起见。
事实上,有时\csname•command•\endcsname
这种方法是依赖于具体实现的,因此不应依赖于此。
当然,第一个空格会被忽略,但第二个空格不会被忽略,请参阅绝对基本的 \csname 问题。
它为什么有用\textbf
?
这与写入辅助文件的保护机制有关。诸如此类的命令\textbf
无法通过 TeX 提供的基本写入机制,因此设计了一种保护机制来避免其被扩展。
如果你
latexdef \textbf
从命令行你得到
\textbf:
macro:->\protect \textbf
\textbf :
\long macro:#1->\ifmmode \nfss@text {\bfseries #1}\else \hmode@bgroup \text@command {#1}\bfseries \check@icl #1\check@icr \expandafter \egroup \fi
另一方面,latexdef -s \textbf
会回答
% latex.ltx, line 4054:
\DeclareTextFontCommand{\textbf}{\bfseries}
说明的定义\textbf
是相当高级的。
基本上,\textbf
被定义为扩展为\protect\textbf•
(其中空格是名称的一部分,猜猜看,\textbf•
是使用 定义的\csname
)。
该命令\protect
可以取多个值,具体取决于上下文。在正常排版期间,其含义是\relax
(不执行任何操作),但在写入操作期间,其含义变为\noexpand
(嗯,其实不是,但就这个答案而言,这并不是什么大谎言)。
结果是,在写入操作期间\textbf
首先扩展为\protect\textbf•
,这反过来会执行\noexpand\textbf•
,因此令牌将被写入字面上地。游戏结束时,辅助文件将包含
\textbf••
(一个空格用于名称,另一个空格用于 TeX 写出命令名称的方式)。但是,当读入辅助文件时,TeX 只会看到\textbf
后面跟着两个空格,而规则会忽略这两个空格。
此实现符合预期,但不应利用这一事实。并非所有强大的命令都以这种方式处理。
为什么\section
不让它变得坚固?因为它非常它不太可能出现在需要写入辅助文件的代码中。所以\section•
没有定义(在标准设置下)。因此如果你写
\csname•section•\endcsname
TeX 会默默地用 替换它\relax
。相反,\section
(没有空格) 是定义的,所以
\csname•section\endcsname
相当于\section
。