0

This question is directly related to this one. I used the code and wanted to have an empty pagestyle on pages having a section start and at the same time the header should be customized like this one. When I use the codes together it won't work anymore, because the title in the header is now the title from the table of contents.

When a section starts there is no header:

first

When a section starts and has another [sub]section in it there should be a header but is not.

second

When there is no section at the page the header should have the rightmark if it's not blank, else the leftmark. That worked before merging the codes, now it doesn't (in this example it should be the current section):

third

Here are some cases for what should be inside the header and when there should be a header:

  • If the page starts with a section and has no previous text that breaked to the page there shouldn't be a header.
  • If there is text that breaks to the page from a [*]section there should be a header containing the number and title of [*].
  • If the page doesn't has breaking text and starts with a sub[*]section it should have a header and in the header the number and title of the upper section e.g. if the page starts a subsection it should hold the section title.

How can I get both working, no header at section start and a customized header on pages, which don't have a section start or have [sub]sections which break to this page?

Here is a MWE:

\documentclass[12pt,a4paper,ngerman]{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}
\hypersetup{breaklinks=true,
            pdfborder={0 0 0},
            ngerman}
\usepackage{times}
\usepackage{microtype}
\usepackage[parfill]{parskip}

\usepackage[
    a4paper,
    left=4cm,
    right=3cm,
    top=3cm,
    bottom=3cm,
    %showframe,
    headheight=15pt,
    includeheadfoot
]{geometry}
\linespread{1.25}

\usepackage{blindtext}

\renewcommand{\sfdefault}{\rmdefault}

\usepackage{fancyhdr}
\usepackage{chngcntr}
\usepackage{xparse}
\fancyhf{}
\lhead{\nouppercase{\rightorleftmark}}
\cfoot{\thepage}

\fancypagestyle{section}{%
  \fancyhf{}%
  \fancyfoot[C]{\thepage}
  \renewcommand{\headrulewidth}{0pt}
}

\counterwithin{figure}{section}
\counterwithin{table}{section}

% https://tex.stackexchange.com/a/187853/49121
\let\originalsection\section
\RenewDocumentCommand{\section}{som}{%
  \IfBooleanTF{#1}
    {\originalsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsection{#3}}
      {\originalsection[#2]{#3}}%
    }%
  \thispagestyle{section}%
}

%https://tex.stackexchange.com/a/101926/49121
\makeatletter
\newcommand{\rightorleftmark}{%
  \begingroup\protected@edef\x{\rightmark}%
  \ifx\x\@empty
    \endgroup\leftmark
  \else
    \endgroup\rightmark
  \fi}
\makeatother

\begin{document}
  \pagestyle{plain}
  \pagenumbering{Roman}
  \setcounter{page}{1} % when using custom titlepage

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Inhaltsverzeichnis}{tableofcontents}
  \markboth{Inhaltsverzeichnis}{}
  \tableofcontents

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Abbildungsverzeichnis}{listoffigures}
  \listoffigures

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Tabellenverzeichnis}{listoftables}
  \listoftables


  \cleardoublepage
  \phantomsection
  \pagenumbering{arabic}
  \pagestyle{fancy}
  \cleardoublepage
  \blinddocument

\end{document}
  • Since you never set the \rightmark, obviously the last set one (that is, the TOC title) is used. – egreg Dec 16 '16 at 22:26
  • I didn't set it before, too. But it worked before. – Tim Dec 16 '16 at 22:27
  • I'm not sure it does what you want, but adding \renewcommand{\subsectionmark}[1]{\markright{#1}} (or variant thereof if you need the number) should do. – egreg Dec 16 '16 at 22:43
  • Thanks that's the right direction. But I want the [sub]section title from the previous page not from the current. So the reader of the breaking block knows what was the title of it. – Tim Dec 16 '16 at 22:48
  • Now there are all cases IMO. Thanks for having a look I will put some bounty on this asap. – Tim Dec 16 '16 at 22:58
1

Here is a solution for the real original problem, including the third requirement (text header of next higher (*)section command if the page starts with a sub(*)section. I don't know if it covers all corner cases, but the normal cases seem to work well. I have put this as a separate answer because both address slightly different problems.

\documentclass[12pt,a4paper,ngerman]{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}
\hypersetup{breaklinks=true,
            pdfborder={0 0 0},
            ngerman}
\usepackage{times}
\usepackage{microtype}
\usepackage[parfill]{parskip}

\usepackage[
    a4paper,
    left=4cm,
    right=3cm,
    top=3cm,
    bottom=2.9cm,
    %showframe,
    headheight=15pt,
    includeheadfoot
]{geometry}
\linespread{1.25}

\usepackage{blindtext}

\renewcommand{\sfdefault}{\rmdefault}

\usepackage{chngcntr}

\counterwithin{figure}{section}
\counterwithin{table}{section}

\usepackage{xparse}
\usepackage{ifthen}
\usepackage{extramarks}

\usepackage{fancyhdr}
\pagestyle{fancy} % give \pagestyle{fancy} here to initialize fancyhdr.
\fancyhf{}

% We are going to use \rightmark for the section or subsection title to be
% placed in the header and \firstleftmark (from the extramarks package)
% to indicate where it comes from:
% prev = from a (sub)section on the previous page
% newpage = from a \newpage command 
% section = from a \section command on this page
% subsection = from a \subsection command on this page
% We use \firstleftmark because the normal \leftmark gives us the LAST
% left mark on the page instead of the first one.
%
% Our solution is to issue a \markboth command with "prev" as left part
% before each \(sub)section command. This serves two purposes:
% (1) In this way the previous (sub)section title will be used in the header.
% (2) When the pagebreak comes just before the \section command, the
% previous page will have a "prev" (last) \leftmark and the current page
% will have a "section" \firstleftmark. This combination determines that
% there is a section at the top of the page.
% In order to work properly, \newpage must also issue such a mark. In
% that case we put "newpage" in the leftmark, but that information is
% currently not used.

% Test if there is a section at the top of the page.

\newcommand{\iftopsection}[2]{% %1 = true action, #2 = false action
     \ifthenelse{\equal{\firstleftmark}{section}}{#1}{#2}}

% If there is a section on top of the page, suppress the header
% If it is a subsection, use the last section title (in \firstleftxmark)
% If it is a subsubsection, use the last subsection title (in \firstrightxmark).
% Otherwise we have overflow from the previous page and we use \rightmark
% (which should be the current (*)section from \prevmark).

\lhead{\nouppercase{%
     \iftopsection{}
       {\ifthenelse{\equal{\firstleftmark}{subsection}}
         {\firstleftxmark}%
         {\ifthenelse{\equal{\firstleftmark}{subsubsection}}
           {\firstrightxmark}{\rightmark}}}}}

%% \rhead{\firstleftmark} % This is for debugging!!!!!
\cfoot{\thepage}

% If there is a \section command on the top of the page, make \headrule empty.

\let\originalheadrule\headrule
\renewcommand{\headrule}{%
     \iftopsection{}{\originalheadrule}}

% Define the format the (*)section titles have in the header

\newcommand{\secTH}[1]{\thesection\quad #1}
\newcommand{\subsecTH}[1]{\thesubsection\quad #1}
\newcommand{\subsubsecTH}[1]{\thesubsubsection\quad #1}

% Mark commands for the (*)sections. We set the title in the rightmark,
% and also keep the extramarks current (last section and subsection title).

\renewcommand{\sectionmark}[1]{\markboth{section}{\secTH{#1}}%
   \extramarks{\secTH{#1}}{}}
\renewcommand{\subsectionmark}[1]{\markboth{subsection}{\subsecTH{#1}}%
  \extramarks{\prevsection}{\subsecTH{#1}}}
\renewcommand{\subsubsectionmark}[1]{\markboth{subsubsection}{\subsubsecTH{#1}}}

% We remember the title of the previous (*)section in \prevmark.
% We have also commands to remember the last section and subsection
% titles specifically. We will remember these with \extramarks.

\newcommand{\prevmark}{}
\newcommand{\prevsection}{}
\newcommand{\prevsubsection}{}

% This inserts the \prevmark as a mark before the (sub)section command.
% There is a \nopagebreak before it, so that (hopefully) it will stick
% with the previous text. So we hope the page will be broken after it if necessary.
% And then we set the new \prevmark value to the (sub)section title.
% We set the last section and subsection titles with \extramarks.

\newcommand{\insertprevmark}[1]{%
  \nopagebreak
  \ifx\prevmark\empty\else\markboth{prev}{\prevmark}%
  \extramarks{\prevsection}{\prevsubsection}\fi
  \renewcommand{\prevmark}{#1}%
}

% Change \section so that it will insert a "prev" mark first. 
% http://tex.stackexchange.com/a/187853/49121
\let\originalsection\section
\RenewDocumentCommand{\section}{som}{%
  \insertprevmark{\secTH{#3}}%
  \renewcommand{\prevsection}{\secTH{#3}}%
  \renewcommand{\prevsubsection}{}%
  \IfBooleanTF{#1}
    {\originalsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsection{#3}}
      {\originalsection[#2]{#3}}%
    }%
}

% Change \subsection so that it will insert a "prev" mark first. 
\let\originalsubsection\subsection
\RenewDocumentCommand{\subsection}{som}{%
  \insertprevmark{\subsecTH{#3}}%
  \renewcommand{\prevsubsection}{\subsecTH{#3}}%
  \IfBooleanTF{#1}
    {\originalsubsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsubsection{#3}}
      {\originalsubsection[#2]{#3}}%
    }%
}

% Change \subsubsection so that it will insert a "prev" mark first. 
\let\originalsubsubsection\subsubsection
\RenewDocumentCommand{\subsubsection}{som}{%
  \insertprevmark{\subsubsecTH{#3}}%
  \IfBooleanTF{#1}
    {\originalsubsubsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsubsubsection{#3}}
      {\originalsubsubsection[#2]{#3}}%
    }%
}

% adapt \newpage so that it issues a "prev" mark, and makes \prevmark empty

\let\originalnewpage\newpage
\renewcommand{\newpage}{\markboth{newpage}{\prevmark}\global\let\prevmark\empty\originalnewpage}

\begin{document}
  \pagestyle{plain}
  \pagenumbering{Roman}
  \setcounter{page}{1} % when using custom titlepage

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Inhaltsverzeichnis}{tableofcontents}
  \markboth{Inhaltsverzeichnis}{}
  \tableofcontents

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Abbildungsverzeichnis}{listoffigures}
  \listoffigures

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Tabellenverzeichnis}{listoftables}
  \listoftables

  \cleardoublepage
  \phantomsection
  \pagenumbering{arabic}
  \pagestyle{fancy}
  \section{This is a test section}
  \blindtext
  \subsection{This is a subsection}
  \blindtext
  \section{This is another section}


This is some text.   This is some text.   This is some text.   
This is some text.   This is some text.   This is some text.   
This is some text.   This is some text.   This is some text.   
This is some text.   This is some text.   This is some text.   

\subsection{This is another subsection}

  Some more text. 

 \cleardoublepage
  \blinddocument

\end{document}
  • That's nearly perfect! One thing that I see that doesn't work is if you put some \blindtext commands (like 5) in a sequence after the \blinddocument then there is text filling the complete page, belonging to the same section. But it differs in it's header titles. – Tim Dec 22 '16 at 16:24
  • The empty line is still there, where should be no header. I try to find out what is the problem, maybe some other package I use. – Tim Dec 22 '16 at 16:28
  • 1
    I'll look into it. – Piet van Oostrum Dec 22 '16 at 19:48
2

Original answer: Instead of testing if the \rightmark is empty and then choosing \leftmark it is much easier to make sure that when the \leftmark is set, also the \rightmark is set to the same value.

This can be done with:

\renewcommand{\sectionmark}[1]{\markboth{\thesection. #1}{\thesection. #1}}

and the you can just use \rightmark:

\lhead{\nouppercase{\rightmark}}

Edit: Below I have added what I think is a complete solution to the original problem.

Change Note Dec 20,2016: I have replaced the solution with a simpler one, that does not need \topmark. I think it is more robust.

However the OP brought to my attention that it doesn't satisfy the third requirement:

  • If the page doesn't has breaking text and starts with a sub[*]section it should have a header and in the header the number and title of the upper section e.g. if the page starts a subsection it should hold the section title.

Instead on a page that starts with a sub[*]section it uses the title of that sub[*]section in the header. I am working to find a solution to the other requirement.

Now here is a solution to the original (complicated) problem. It's quite some trickery with marks, and I hope I have covered all the corner cases. Explanation is in the comments.

\documentclass[12pt,a4paper,ngerman]{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}
\hypersetup{breaklinks=true,
            pdfborder={0 0 0},
            ngerman}
\usepackage{times}
\usepackage{microtype}
\usepackage[parfill]{parskip}

\usepackage[
    a4paper,
    left=4cm,
    right=3cm,
    top=3cm,
    bottom=3cm,
    %showframe,
    headheight=15pt,
    includeheadfoot
]{geometry}
\linespread{1.25}

\usepackage{blindtext}

\renewcommand{\sfdefault}{\rmdefault}

\usepackage{chngcntr}

\counterwithin{figure}{section}
\counterwithin{table}{section}

\usepackage{xparse}
\usepackage{ifthen}
\usepackage{extramarks}

\usepackage{fancyhdr}
\pagestyle{fancy} % give \pagestyle{fancy} here to initialize fancyhdr.
\fancyhf{}

% We are going to use \rightmark for the section or subsection title to be
% placed in the header and \firstleftmark (from the extramarks package)
% to indicate where it comes from:
% prev = from a (sub)section on the previous page
% section = from a \section command on this page
% subsection = from a \subsection command on this page
% We use \firstleftmark because the normal \leftmark gives us the LAST
% left mark on the page instead of the first one.
%
% Our solution is to issue a \markboth command with "prev" as left part
% before each \(sub)section command. This serves two purposes:
% (1) In this way the previous (sub)section title will be used in the header.
% (2) When the pagebreak comes just before the \section command, the
% previous page will have a "prev" (last) \leftmark and the current page
% will have a "section" \firstleftmark. This combination determines that
% there is a section at the top of the page. In order to work properly,
% a \newpage must also issue such a mark.

% If there is a section command at the top, don't put a header (put an
% empty header)

% Test if there is a section at the top of the page.

\newcommand{\iftopsection}[2]{% %1 = true action, #2 = false action
     \ifthenelse{\equal{\firstleftmark}{section}}{#1}{#2}}

\lhead{\nouppercase{%
     \iftopsection{}{\rightmark}}}
%\rhead{\firstleftmark} % This is for debugging!!!!!
\cfoot{\thepage}

% If there is a \section command on the top of the page, make \headrule empty.

\let\originalheadrule\headrule
\renewcommand{\headrule}{%
     \iftopsection{}{\originalheadrule}}

\renewcommand{\sectionmark}[1]{\markboth{section}{\thesection\ #1}}
\renewcommand{\subsectionmark}[1]{\markboth{subsection}{\thesubsection\ #1}}

% We remember the title of the previous (sub)section in \prevmark.

\newcommand{\prevmark}{}
% This inserts the \prevmark as a mark before the (sub)section command.
% There is a \nopagebreak before it, so that (hopefully) it will stick
% with the previous text. So we hope the page will be broken after it if necessary.
% And then we set the new \prevmark value to the (sub)section title.

\newcommand{\insertprevmark}[1]{%
  \nopagebreak
  \ifx\prevmark\empty\else\markboth{prev}{\prevmark}\fi
  \renewcommand{\prevmark}{#1}%
}

% Change \section so that it will insert a "prev" mark first. 
% http://tex.stackexchange.com/a/187853/49121
\let\originalsection\section
\RenewDocumentCommand{\section}{som}{%
  \insertprevmark{\thesection\ #3}%
  \IfBooleanTF{#1}
    {\originalsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsection{#3}}
      {\originalsection[#2]{#3}}%
    }%
}

% Change \subsection so that it will insert a "prev" mark first. 
\let\originalsubsection\subsection
\RenewDocumentCommand{\subsection}{som}{%
  \insertprevmark{\thesubsection\ #3}%
  \IfBooleanTF{#1}
    {\originalsubsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsubsection{#3}}
      {\originalsubsection[#2]{#3}}%
    }%
}

% Change \subsubsection so that it will insert a "prev" mark first. 
\let\originalsubsubsection\subsubsection
\RenewDocumentCommand{\subsubsection}{som}{%
  \insertprevmark{\thesubsubsection\ #3}%
  \IfBooleanTF{#1}
    {\originalsubsubsection*{#3}}
    {\IfNoValueTF{#2}
      {\originalsubsubsection{#3}}
      {\originalsubsubsection[#2]{#3}}%
    }%
}

% adapt \newpage so that it issues a "prev" mark, and makes \prevmark empty

\let\originalnewpage\newpage
\renewcommand{\newpage}{\markboth{prev}{\prevmark}\global\let\prevmark\empty\originalnewpage}

\begin{document}
  \pagestyle{plain}
  \pagenumbering{Roman}
  \setcounter{page}{1} % when using custom titlepage

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Inhaltsverzeichnis}{tableofcontents}
  \markboth{Inhaltsverzeichnis}{}
  \tableofcontents

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Abbildungsverzeichnis}{listoffigures}
  \listoffigures

  \cleardoublepage
  \phantomsection
  \pdfbookmark{Tabellenverzeichnis}{listoftables}
  \listoftables

  \cleardoublepage
  \phantomsection
  \pagenumbering{arabic}
  \pagestyle{fancy}
  \section{This is a test section}
  \blindtext
  \subsection{This is a subsection}
  \blindtext
  \section{This is another section}


This is some text.   This is some text.   This is some text.   
This is some text.   This is some text.   This is some text.   
This is some text.   This is some text.   This is some text.   
This is some text.   This is some text.   This is some text.   

Comment out these two lines so that the next subsection starts at the top
of the page. Then the header will become that subsection title.

  \subsection{This is another subsection}
  Some more text. 

 \cleardoublepage
  \blinddocument

\end{document}
  • 1
    I have been thinking about this (even while I was sleeping) and maybe I can find a solution. But I have to find the time to work on it. – Piet van Oostrum Dec 17 '16 at 6:55
  • 1
    I thought that it wouldn't be possible with marks. Yet I found such a solution. Never say never!! – Piet van Oostrum Dec 17 '16 at 16:02
  • 1
    Added subsubsection support. – Piet van Oostrum Dec 17 '16 at 17:14
  • 1
    Ok, I think I overlooked that requirement. But now suppose you have Section 2, followed by subsection 2.1 on a page. The next page starts with subsection 2.2. Then you want to have the Section 2 title in the header? That's difficult because normally you would have 2.1 or 2.2. And adding subsubsections makes it even harder. It would mean the system has to keep a stack of titles, rather than only the previous and the current title. I don't know if the mark system can handle that. But then I said that before and still found a way. But now I think it is much harder. – Piet van Oostrum Dec 19 '16 at 20:07
  • 1
    And remember, that section could have started several pages before the current page, and there could have been many subsections and subsubsections in between. And if there would be one word left over from subsection 2.1 then the 2.1 title would have to be used. If the 2.2 subsection started one line earlier, then 2.2 would be used. But if 2.2 starts at the top of the page section 2 would be used. And then you have the same thing again one lever lower. Mind boggling. – Piet van Oostrum Dec 19 '16 at 20:11

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.