# redefine section style with titleformat

I want to define my own section style by titlesec package, just after in a chapter, the section title show chapter title and section title.

Simple code example:

\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}


A solution changing the definition of \chapter to save the current chapter name in a macro and reuse it in the section title's format:

\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}


Explanation:


Next we'll save the current definition of \chapter into a macro called \CHAPTERBAK with \let\CHAPTERBAK\chapter.

I then define two macros just to parse the arguments to the new \chapter definition. Those two are called \star@processor and \opt@processor. \star@processor will get the star-argument of \chapter (so the optional *). and \opt@processor will get the argument in optional brackets. In the macro definition #1 will be what \ProcessedArgument was defined to in \star@processor and #2 what \ProcessedArgument was in \opt@processor.

The xparse package's \NewDocumentCommand gives us an easy interface to define new commands. We can use argument processors by using >{\<processor>} as a prefix of an argument defining token. The \<processor> should take one argument which is the argument given. You could however use a macro taking two arguments and prefixing with >{\<processor>{<first argument>}}, the second argument would then be the argument given to the macro which is to be defined.

An s argument is an optional star and if it was present (so \chapter* was used) the test \IfBooleanTF{#1} will expand the true-branch, so \def\ProcessedArgument{*} is used by \star@processor.

The O{} type argument is an optional argument in brackets which defaults to be empty (you could give other defaults in the braces). If it is empty \ProcessedArgument will be defined to be empty by \opt@processor, else the argument will be set to [#1] so #2 in the new \chapter macro will be either empty or an argument delimited by brackets.

Now we can easily define \chapter to do what we want. First it'll redefine \Current@Chapter to contain \chaptername~\thechapter\ #3 with #3 being the mandatory argument to \chapter. After that \chapter calls the original \chapter as \CHAPTERBAK.

In \titleformat{\section} we can now include \Current@Chapter in the prefix.

• Although I don’t know the principle, it solved my problem perfectly. – zongxian Jun 15 '18 at 0:09
• @zongxian I've added an exhaustive (and hopefully comprehensible) explanation. – Skillmon Jun 15 '18 at 8:07
• Thank you very much. It helpful to me for learning macros. – zongxian Jun 15 '18 at 9:05
• @zongxian forgot to mention \makeatletter and \makeatother, the first changes @ to be considered as a character so that it is possible to use in macro names, the latter changes it back to be of type "other". – Skillmon Jun 15 '18 at 12:19