我想通过 titlesec 包定义我自己的章节样式,就在章节之后,章节标题显示章节标题和章节标题。
简单代码示例:
\documentclass[]{book}
\usepackage{fancyhdr}
\usepackage{titlesec}
\pagestyle{fancy}
\titleformat{\chapter}[block]{\filleft}
{\chaptername~ \thechapter}{1em}{\bf}[\vspace{-0.6em}\rule{\linewidth}{1pt}]
%
%
\titleformat{\section}[block]{\filleft}
{\thesection}{1em}{}[\vspace{-0.6em}\rule{\linewidth}{1pt}]
\begin{document}
\chapter{ch01}
\section{sec01}
\end{document}
答案1
解决方案是改变定义以\chapter
将当前章节名称保存在宏中并在章节标题的格式中重复使用它:
\documentclass[]{book}
\usepackage{fancyhdr}
\usepackage{titlesec}
\pagestyle{fancy}
\usepackage{xparse}
\titleformat{\chapter}[block]{\filleft}
{\chaptername~ \thechapter}{1em}{\bfseries}[\vspace{-0.6em}\rule{\linewidth}{1pt}]
\makeatletter
\newcommand*\Current@Chapter{}
\let\CHAPTERBAK\chapter
\newcommand\star@processor[1]
{%
\IfBooleanTF{#1}
{\def\ProcessedArgument{*}}
{\def\ProcessedArgument{}}%
}
\newcommand\opt@processor[1]
{%
\if\relax\detokenize{#1}\relax
\def\ProcessedArgument{}%
\else
\def\ProcessedArgument{[#1]}%
\fi
}
\RenewDocumentCommand \chapter { >{\star@processor}s >{\opt@processor}O{} m }
{%
\gdef\Current@Chapter{\chaptername~\thechapter\ #3}%
\CHAPTERBAK#1#2{#3}
}
\titleformat{\section}[block]{\filleft}
{\Current@Chapter\ \thesection}{1em}{}[\vspace{-0.6em}\rule{\linewidth}{1pt}]
\makeatother
\begin{document}
\tableofcontents
\chapter{ch01}
\section{sec01}
\end{document}
解释:
首先,我们定义一个宏,用于保存当前章节的名称和编号。这是通过 完成的\newcommand*\Current@Chapter{}
。我使用\newcommand
来确保没有冲突,因为\newcommand
检查宏的名称是否已定义。
接下来我们将把的当前定义保存\chapter
到名为的宏\CHAPTERBAK
中\let\CHAPTERBAK\chapter
。
然后,我定义两个宏来解析新定义的参数\chapter
。这两个宏称为\star@processor
和\opt@processor
。\star@processor
将获取 的星号参数\chapter
(因此是可选的*
)。并将\opt@processor
获取可选括号中的参数。宏定义中将#1
是\ProcessedArgument
中定义的内容\star@processor
和中的#2
内容。\ProcessedArgument
\opt@processor
该xparse
包为\NewDocumentCommand
我们提供了定义新命令的简单接口。我们可以使用参数处理器,方法是使用>{\<processor>}
作为参数定义标记的前缀。应该\<processor>
采用一个参数,即给定的参数。但是,您可以使用采用两个参数并以作为前缀的宏>{\<processor>{<first argument>}}
,那么第二个参数将是要定义的宏的给定参数。
参数s
是一个可选的星号,如果它存在(因此\chapter*
被使用),则测试\IfBooleanTF{#1}
将扩展真正的分支,因此\def\ProcessedArgument{*}
被使用\star@processor
。
类型O{}
参数是括号中的可选参数,默认为空(您可以在括号中指定其他默认值)。如果它是空的,\ProcessedArgument
则将被定义为空\opt@processor
,否则参数将被设置为[#1]
,因此#2
新\chapter
宏中的参数将为空或由括号分隔的参数。
现在我们可以轻松定义\chapter
来执行我们想要的操作。首先,它将重新定义\Current@Chapter
为 包含\chaptername~\thechapter\ #3
,其中#3
是 的强制参数\chapter
。之后\chapter
将原始调用\chapter
为\CHAPTERBAK
。
我们现在\titleformat{\section}
可以\Current@Chapter
在前缀中包含它。