假设我想重新定义,\@seccntformat
以便每当打印部分计数器时,它都以 为前缀Section
,但其他计数器不应更改。
这是我的失败的尝试:
\documentclass{article}
\makeatletter
\def\mytest{section}%
\def\myarg#1{#1}
\def\@seccntformat#1{%
\ifx\myarg#1\mytest{Section}\fi%
\csname the#1\endcsname\quad}
\makeatother
\begin{document}
\section{Foo} % Should be printed as "Section 1 Foo"
\subsection{Bar} % Should be printed as "1.1 Bar"
\end{document}
由于某种原因,当时我无法获取\myarg#1
并\mytest
比较相等。这是我第一次使用,所以我希望我遗漏了一些琐碎的事情。#1
section
\ifx
我将非常感激有关如何调试此类宏的一些提示。有没有办法查看每个中间扩展步骤并观察\ifx
实际接收的参数?
答案1
条件\ifx
不进行扩展,而是比较接下来的两个标记。因此,在您的测试中,它\myarg
与中的第一个标记进行比较#1
。
因此测试将始终为错误,因为它#1
是部分级计数器的名称。
\expandafter
在之前添加\ifx
没有帮助,甚至在周围添加括号#1
:
\expandafter\ifx\myarg{#1}\mytest
会成为
\ifx section\mytest
s
与相比,它返回 false e
。
您可以使用\pdfstrcmp
(或者更好的是,\pdf@strcmp
使用pdftexcmds
包):
\def\@seccntformat#1{%
\ifnum\pdf@strcmp{#1}{section}=\z@
Section % a space is wanted
\fi
\csname the#1\endcsname\quad}
完整示例:
\documentclass{article}
\usepackage{pdftexcmds}
\makeatletter
\def\@seccntformat#1{%
\ifnum\pdf@strcmp{#1}{section}=\z@
Section %
\fi
\csname the#1\endcsname\quad}
\makeatother
\begin{document}
\section{Foo} % Should be printed as "Section 1 Foo"
\subsection{Bar} % Should be printed as "1.1 Bar"
\end{document}
请注意,尝试\ifx
以以下方式进行比较
\def\section@argument{section}
\def\@seccntformat#1{%
\def\@argument{#1}%
\ifx\@argument\section@argument
Section %
\fi
\csname the#1\endcsname\quad}
也行不通。这是因为\@seccntformat
通过了\edef
(格式为\protected@edef
),所以我们会得到一个错误
Undefined control sequence
为\@argument
。\noexpand
在 前面添加\@argument
不会有帮助,因为 期间条件被扩展了\edef
。这反而会起作用
\def\section@argument{section}
\def\@seccntformat#1{%
\unexpanded{%
\def\@argument{#1}%
\ifx\@argument\section@argument
Section %
\fi
}
\csname the#1\endcsname\quad
}
因为在 期间 的参数\unexpanded
不会改变\edef
,所以它将在之后涉及排版时进行处理。
请注意,是必需的,因为我们必须在执行宏时获取或的\protected@edef
展开。一种免费解决方案是可能的,方法是将部分隐藏在宏中:\thesection
\thesubsection
\@seccntformat
\unexpanded
\def\section@argument{section}
\def\check@section#1{%
\def\@argument{#1}%
\ifx\@argument\section@argument
Section %
\fi
}
\def\@seccntformat#1{%
\noexpand\check@section{#1}%
\csname the#1\endcsname\quad}