在使用 ctexbook 文档类编写中文文档时,我希望实现如下逻辑:当某级标题(如 chapter、section、subsection)后紧跟的是下一级标题,则正常渲染,不插入额外间距;但若标题后直接接正文内容(普通段落),则在标题和正文之间自动插入一段自定义的垂直距离(如vspace{2em})。这个需求不能通过简单设置 afterskip 解决,因为它会作用于所有情况,无法区分是否有子标题。请问如何优雅地实现该自动判断逻辑,并与 CTEXsetup 设定的章节样式兼容?
附上最小可复现示例代码:
\documentclass[UTF8,oneside,a4paper,12pt]{ctexbook}
\usepackage{ctex}
\CTEXsetup[
name={},
break = ,
number={\arabic{chapter}}, % 章节编号设置为阿拉伯数字格式
format+={\zihao{-2}\heiti},
aftername={\,\,\,},
beforeskip={-1.5em},
afterskip={1.3em}
]{chapter}
\CTEXsetup[
format={\zihao{4}\heiti},
nameformat+={\zihao{4}\heiti},
aftername={\,\,\,},
titleformat={\zihao{4}\heiti},
beforeskip={0.3em},
afterskip={0.1em}
]{section}
\CTEXsetup[
format={\zihao{-4}\heiti},
nameformat+={\zihao{-4}\heiti},
aftername={\,\,\,},
titleformat={\zihao{-4}\heiti},
beforeskip={0em},
afterskip={0.62em}
]{subsection}
\CTEXsetup[
format={\zihao{-4}\heiti},
nameformat+={\zihao{-4}\heiti},
aftername={\,\,\,},
titleformat={\zihao{-4}\heiti},
beforeskip={0ex},
afterskip={0ex}
]{subsubsection}
\setcounter{secnumdepth}{3}
\begin{document}
\chapter{这是章标题这是章标题这是章标题}
\section{SECTION-SECTION-SECTION-SECTION}
\subsection{SUBSECTION-SUBSECTION-SUBSECTION-SUBSECTION}
\subsubsection{SUBSUBSECTION-SUBSUBSECTION-SUBSECTION-SUBSECTION}
\vspace{3em}
\chapter{这是章标题这是章标题这是章标题}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\section{SECTION-SECTION-SECTION-SECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\subsection{SUBSECTION-SUBSECTION-SUBSECTION-SUBSECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\subsubsection{SUBSUBSECTION-SUBSUBSECTION-SUBSECTION-SUBSECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\end{document}
Hope this may help u: using l3bool
\documentclass[AutoFakeBold, oneside,a4paper,12pt]{ctexbook}
\makeatletter
\ExplSyntaxOn
\bool_new:N \l_@@_chapter_afterskip_bool
\hook_gput_code:nnn { cmd / chapter / before } {.}
{ \bool_gset_true:N \l_@@_chapter_afterskip_bool }
\hook_gput_code:nnn { cmd / @startsection / before } {.}
{ \bool_if:NT \l_@@_chapter_afterskip_bool { \vskip -2em } }
% 使用 vskip: 否则 chapter 后紧挨着的正文结尾、和接下来第一个 section 标题
% 之间距离会变小甚至重叠
\DeclareDocumentCommand \banchapterskip {}
{ \bool_gset_false:N \l_@@_chapter_afterskip_bool }
\ExplSyntaxOff
\makeatother
\ctexset{
secnumdepth = 3,
chapter = {
name = {}, break = ,
number = \arabic{chapter},
format+ = \zihao{-2}\heiti,
aftername = \,\,\,,
beforeskip = -1.5em,
afterskip = 3.3em
},
section = {
format = \zihao{4}\heiti,
nameformat+ = \zihao{4}\heiti,
aftername = \,\,\,,
titleformat = \zihao{4}\heiti,
beforeskip = 0.3em,
afterskip = 0.1em,
aftertitle+ = \banchapterskip
},
subsection = {
format = \zihao{-4}\heiti,
nameformat+ = \zihao{-4}\heiti,
aftername = \,\,\,,
titleformat = \zihao{-4}\heiti,
beforeskip = 0em,
afterskip = 0.62em
},
subsubsection = {
format = \zihao{-4}\heiti,
nameformat+ = \zihao{-4}\heiti,
aftername = \,\,\,,
titleformat = \zihao{-4}\heiti,
beforeskip = 0ex,
afterskip = 0ex
}
}
\begin{document}
\chapter{这是章标题这是章标题这是章标题}
\section{SECTION-SECTION-SECTION-SECTION}
\subsection{SUBSECTION-SUBSECTION-SUBSECTION-SUBSECTION}
\subsubsection{SUBSUBSECTION-SUBSUBSECTION-SUBSECTION-SUBSECTION}
\vspace{3em}
\chapter{这是章标题这是章标题这是章标题}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\section{SECTION-SECTION-SECTION-SECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\subsection{SUBSECTION-SUBSECTION-SUBSECTION-SUBSECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\subsubsection{SUBSUBSECTION-SUBSUBSECTION-SUBSECTION-SUBSECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\end{document}
优雅的方法可能是重定义\@startsection
,或者可能用\AddToHook
也行(我不会)?
只会一个不优雅的方法,重新定义\chapter
,\section
,...让它们多读一个参数,对这个参数进行判断。
存在的问题:
\vspace{3em}
前面的空行我删除了。\label{section-1}
后面的内容,这段代码处理不了。\documentclass[UTF8,oneside,a4paper,12pt]{ctexbook}
\usepackage{ctex}
\CTEXsetup[
name={},
break = ,
number={\arabic{chapter}}, % 章节编号设置为阿拉伯数字格式
format+={\zihao{-2}\heiti},
aftername={\,\,\,},
beforeskip={-1.5em},
afterskip={1.3em}
]{chapter}
\CTEXsetup[
format={\zihao{4}\heiti},
nameformat+={\zihao{4}\heiti},
aftername={\,\,\,},
titleformat={\zihao{4}\heiti},
beforeskip={0.3em},
afterskip={0.1em}
]{section}
\CTEXsetup[
format={\zihao{-4}\heiti},
nameformat+={\zihao{-4}\heiti},
aftername={\,\,\,},
titleformat={\zihao{-4}\heiti},
beforeskip={0em},
afterskip={0.62em}
]{subsection}
\CTEXsetup[
format={\zihao{-4}\heiti},
nameformat+={\zihao{-4}\heiti},
aftername={\,\,\,},
titleformat={\zihao{-4}\heiti},
beforeskip={0ex},
afterskip={0ex}
]{subsubsection}
\setcounter{secnumdepth}{3}
\ExplSyntaxOn
\cs_new:Npn \__My_judgement:nn #1#2
{
\tl_if_in:nnTF {#1}{#2}
{\par #2}
{\vspace{3em minus 3em}\par #2}
}
\cs_set_eq:NN \__My_oldchapter \chapter
\cs_set_eq:NN \__My_oldsection \section
\cs_set_eq:NN \__My_oldsubsection \subsection
\cs_set_eq:NN \__My_oldsubsubsection \subsubsection
\RenewDocumentCommand{\chapter}{somm}
{
\IfBooleanTF{#1}
{ \IfNoValueTF {#2} { \__My_oldchapter*{#3} } { \__My_oldchapter*[#2]{#3} } }
{ \IfNoValueTF {#2} { \__My_oldchapter{#3} } { \__My_oldchapter[#2]{#3} } }
\__My_judgement:nn {\chapter,\section,\subsection,\subsubsection}{#4}
}
\RenewDocumentCommand{\section}{somm}
{
\IfBooleanTF{#1}
{ \IfNoValueTF {#2} { \__My_oldsection*{#3} } { \__My_oldsection*[#2]{#3} } }
{ \IfNoValueTF {#2} { \__My_oldsection{#3} } { \__My_oldsection[#2]{#3} } }
\__My_judgement:nn {\chapter,\section,\subsection,\subsubsection}{#4}
}
\RenewDocumentCommand{\subsection}{somm}
{
\IfBooleanTF{#1}
{ \IfNoValueTF {#2} { \__My_oldsubsection*{#3} } { \__My_oldsubsection*[#2]{#3} } }
{ \IfNoValueTF {#2} { \__My_oldsubsection{#3} } { \__My_oldsubsection[#2]{#3} } }
\__My_judgement:nn {\chapter,\section,\subsection,\subsubsection}{#4}
}
\RenewDocumentCommand{\subsubsection}{somm}
{
\IfBooleanTF{#1}
{ \IfNoValueTF {#2} { \__My_oldsubsubsection*{#3} } { \__My_oldsubsubsection*[#2]{#3} } }
{ \IfNoValueTF {#2} { \__My_oldsubsubsection{#3} } { \__My_oldsubsubsection[#2]{#3} } }
\__My_judgement:nn {\chapter,\section,\subsection,\subsubsection}{#4}
}
\ExplSyntaxOff
\begin{document}
\chapter{这是章标题这是章标题这是章标题}
\section{SECTION-SECTION-SECTION-SECTION}
\subsection{SUBSECTION-SUBSECTION-SUBSECTION-SUBSECTION}
\subsubsection{SUBSUBSECTION-SUBSUBSECTION-SUBSECTION-SUBSECTION}
\vspace{3em}
\chapter{这是章标题这是章标题这是章标题}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\section{SECTION-SECTION-SECTION-SECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\subsection{SUBSECTION-SUBSECTION-SUBSECTION-SUBSECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\subsubsection{SUBSUBSECTION-SUBSUBSECTION-SUBSECTION-SUBSECTION}
正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
\end{document}
顺带提一嘴:
CTEXsetup
是已过时的命令,不建议使用,可使用\ctexset
请问:ctex中,各级标题都是调用@startsection吗?我想要在section和subsection之间实现同样的效果,却发现会对chapter和section也造成影响?
@u154230
(应该)并不完全是,我们可以先看
book.cls
的默认行为:而
\chapter
(按道理来讲,一个名为\@startsection
的命令怎么可能越级控制\chapter
呢?)看下面的源码...
\chapter
并没被\@startsection
影响同时要注意的是,
ctex-kit
为了更加符合中文用户的使用,对原始的book.cls
打了补丁,但是并没有修改book.cls
的大致逻辑,可以看下面的例子:这将输出:

至于怎么改最合适,还是交给@u79794 吧😀
P.S. 上面的修改更多的基于latex3,如要想得到和「ctex宏包」最无缝贴合的定义修改方式,我可能会更建议同步到:
提问。
谢谢您
book.cls
截图和@u66435 对我的提醒,这段代码似乎实现了我的需求: