0

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}

enter image description here

2

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:

First we define a macro which we'll use to save the current chapter's name and number. This is done with \newcommand*\Current@Chapter{}. I use \newcommand to make sure there is no conflict, as \newcommand checks whether the macro's name is already defined.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.