通过 csname 调用部分

通过 csname 调用部分

我想创建一个命令,根据其参数创建一个新的部分或子部分(或子子部分或...)。为什么调用\section\subsectionvia\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} 与空间,而其他人,如sectionref,则没有?

答案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

相关内容