![如何在部分开始时隐藏自定义标题](https://linux22.com/image/346205/%E5%A6%82%E4%BD%95%E5%9C%A8%E9%83%A8%E5%88%86%E5%BC%80%E5%A7%8B%E6%97%B6%E9%9A%90%E8%97%8F%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E9%A2%98.png)
这个问题直接关系到这一。我使用了代码,并希望在具有部分开始的页面上使用空的页面样式,同时应该自定义标题,例如这一。当我一起使用代码时它不再起作用,因为页眉中的标题现在是目录中的标题。
当一个部分开始时,没有标题:
当某个部分开始并且其中包含另一个 [子] 部分时,应该有一个标题,但是却没有。
当页面上没有部分时,如果标题不为空,则标题应有右标记,否则应有左标记。在合并代码之前,这种方法有效,但现在无效(在本例中,它应该是当前部分):
以下是标头内应包含的内容以及何时应该有标头的一些情况:
- 如果页面以某个部分开始,且没有中断该页面的先前文本,则不应该有页眉。
- 如果有文本从 [*] 部分中断到页面,则应该有一个包含 [*] 的编号和标题的页眉。
- 如果页面没有分隔文本并且以子[*]节开头,则它应该有一个标题,并且在标题中显示上部节的编号和标题,例如,如果页面开始一个子节,它应该包含节标题。
如何才能让两者同时工作,在部分开始处没有标题,并且在没有部分开始的页面上自定义标题或者是否有 [sub]sections 中断至此页面?
以下是 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}
答案1
这是针对真正的原始问题的解决方案,包括第三个要求(如果页面以子(*)部分开头,则下一个更高(*)部分命令的文本标题)。我不知道它是否涵盖了所有特殊情况,但正常情况似乎效果很好。我把它作为一个单独的答案,因为它们解决的问题略有不同。
\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}
答案2
原始答案:
无需测试是否为\rightmark
空然后选择\leftmark
它,只需确保当\leftmark
设置时,也将\rightmark
设置为相同的值即可。
可以通过以下方式实现:
\renewcommand{\sectionmark}[1]{\markboth{\thesection. #1}{\thesection. #1}}
并且你可以使用\rightmark
:
\lhead{\nouppercase{\rightmark}}
编辑:下面我添加了我认为是原始问题的完整解决方案。
2016年12月20日变更说明:我用一个更简单的解决方案替换了该解决方案,该解决方案不需要\topmark
。我认为它更加强大。
然而 OP 提醒我它不满足第三个要求:
- 如果页面没有分隔文本并且以子[*]节开头,则它应该有一个标题,并且在标题中显示上部节的编号和标题,例如,如果页面开始一个子节,它应该包含节标题。
相反,在以子节开头的页面上,它会在标题中使用该子节的标题。我正在努力寻找其他要求的解决方案。
现在,这是原始(复杂)问题的解决方案。它对标记进行了相当多的欺骗,我希望我已经涵盖了所有极端情况。解释在评论中。
\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}