如题。
MWE1:仅仅使用\pagestyle{empty}
\documentclass[landscape,openany]{book}
\usepackage[a6paper]{geometry}
% \usepackage{tocloft}
% \tocloftpagestyle{empty}
\begin{document}
\pagestyle{empty}
\frontmatter
\title{This is a title}
\author{Explorer}
\date{\today}
\maketitle
\tableofcontents \clearpage
\mainmatter
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\end{document}
效果图1:
MWE2:使用tocloft
宏包提供的\tocloftpagestyle{empty}
\documentclass[landscape,openany]{book}
\usepackage[a6paper]{geometry}
\usepackage{tocloft}
\tocloftpagestyle{empty}
\begin{document}
% \pagestyle{empty}
\frontmatter
\title{This is a title}
\author{Explorer}
\date{\today}
\maketitle
\tableofcontents \clearpage
\mainmatter
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\end{document}
效果图2:
MWE3: combine both of them...固然可行,但是觉得很不优雅
\documentclass[landscape,openany]{book}
\usepackage[a6paper]{geometry}
\usepackage{tocloft}
\tocloftpagestyle{empty}
\begin{document}
\pagestyle{empty}
\frontmatter
\title{This is a title}
\author{Explorer}
\date{\today}
\maketitle
\tableofcontents \clearpage
\mainmatter
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\end{document}
What's is the BEST Practice to clear the page in toc?
其实这几个问题的共同原因都在 \chapter
命令的定义中了, 参见 book.cls
中的定义:
\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
\thispagestyle{plain}%
\global\@topnum\z@
\@afterindentfalse
\secdef\@chapter\@schapter}
这个命令里面的 \thispagestyle{plain}
就产生了这个页码. 而对应的 \tableofcontents
的定义如下:
\newcommand\tableofcontents{%
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse
\fi
\chapter*{\contentsname
\@mkboth{%
\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
\@starttoc{toc}%
\if@restonecol\twocolumn\fi
}
这个里面调用的是 \chapter*
命令,其实就是上面的那个 \@schapter
命令. 所以说解决办法也就很简单了, 在一个局部里面, 把 \tableofcontents
内部的这个 \chapter*
改一下就行了. 你可以选择重定义前者,也可以选择重定义后者. 这里我使用前者:
\documentclass[landscape,openany]{book}
\usepackage[a6paper]{geometry}
\makeatletter
\renewcommand\tableofcontents{%
\if@twocolumn
\@restonecoltrue\onecolumn
\else
\@restonecolfalse
\fi
\@schapter{\contentsname
\@mkboth{%
\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
\@starttoc{toc}%
\if@restonecol\twocolumn\fi
}
\makeatother
\begin{document}
\pagestyle{empty}
\tableofcontents
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\end{document}
编译结果如下:
为了更好的理解这个问题,你可以试试下面这个例子:
\documentclass[landscape,openany]{book}
\usepackage[a6paper]{geometry}
\makeatletter
\begin{document}
\pagestyle{empty}
\@schapter{Contents}
\thispagestyle{plain} % comment this line to test page style
\@starttoc{toc}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\end{document}
至于你后面提到的 tocloft
宏包,你可以自己去看它的实现.
非常感谢Eureka老师的详细回答以及对@
恐惧症患者的鼓励.
下面有一个小小的疑惑,如果采用重定义\chapter*
定义的操作是不是会影响后续如果需要使用\chapter*
的功能,虽然可以在局部修改,但是个人觉得这种方式远不如修改\tableofcontenst
(将\chapter*
替换为\@schapter
)来得优雅简单.
\documentclass[landscape,openany]{book}
\usepackage[a6paper]{geometry}
\begin{document}
\pagestyle{empty}
\begingroup
\makeatletter
\renewcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi
%\thispagestyle{plain}%
\global\@topnum\z@
\@afterindentfalse
\secdef\@chapter\@schapter
}
\makeatother
\tableofcontents
\endgroup
% \mainmatter % 读源码的力量 get!
\cleardoublepage
\pagenumbering{arabic}
\chapter{First}
\chapter{Second}
\chapter{Third}
\chapter*{First}
\chapter*{Second}
\chapter*{Third}
\chapter{First}
\chapter{Second}
\chapter{Third}
\end{document}
顺便补充几个命令定义(其实看macro名称也能大致看出它的含义):
\pagenumbering:
macro:#1->\global \c@page \@ne \gdef \thepage {\csname @#1\endcsname \c@page }
\secdef:
macro:#1#2->\@ifstar {#2}{\@dblarg {#1}}
\@starttoc:
macro:#1->\begingroup \makeatletter \@input {\jobname .#1}\if@filesw \expandafter \newwrite \csname tf@#1\endcsname \immediate \openout \csname tf@#1\endcsname \jobname .#1\relax \fi \@nobreakfalse \endgroup
\def\@schapter#1{\if@twocolumn
\@topnewpage[\@makeschapterhead{#1}]%
\else
\@makeschapterhead{#1}%
\@afterheading
\fi}
\def\@makeschapterhead#1{%
\vspace*{50\p@}%
{\parindent \z@ \raggedright
\normalfont
\interlinepenalty\@M
\Huge \bfseries #1\par\nobreak
\vskip 40\p@
}}
对于补充的思考练习:
\thispagestyle{plain}
行,则可以去除所有ToC标题:这是因为和正确的结果相比,上面的操作相当于用更底层的\@schapter
命令排版了无编号的标题,同时不改变页码设置,相当于跳过了原有\chapter*
中设定为plain
的步骤,并且直接将当前section
的信息写入.toc
文件读取并刷新缓存;
\thispagestyle{plain}
)虽然\@schapter
在排版标题时并没有页码样式仍为empty
,但由于首页还未自然结束,故而会继续进行ToC的排版,而在进行\@schapter
排版之前已经指定了\thispagestyle{plain}
,因此首页ToC会出现页码而后续ToC不出现页码。
\clearpage
断页
[上图有个typo,正文是被\chapter
设置为plain
....]
tocloft
下次一定不过我觉得这个
book.cls
这种\tableofcontents
的行为有点迷惑,我认为一个合格的文档类,不应该在定义\tableofcontents
的时候使用已经定义了\pagestyle{plain}
的\chapter
,而应该直接用更底层\@chapter
和\@schapter
来定义,不然很容易让一些用户在使用\pagestyle{empty}
处理目录时十分迷惑。@u70550 其实你可以重定义
plain
这个页面样式的,每一个页面样式<style>
都对应着一个命令\ps@<style>
. 但是从使用者着这个角度来看,你可以直接使用fancyhdr
这个包对这个plain
样式进行重定义.