0

I want to use one \part (so, not all) as numbered sectioning command (so, no \part*), but I want to have a separate entry for the actual part title, separate one for the TOC typeset in PDF, and separate entry for the TOC in/as PDF bookmarks.

With the following MWE, I can achieve almost all that:

\documentclass{book}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

% http://stackoverflow.com/questions/2785260/hide-an-entry-from-toc-in-latex
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline=\nocontentsline#1{#2}\egroup}

% copy of hyperref.sty \phantomsection:
\makeatletter
\def\phantompart{%
  \Hy@MakeCurrentHrefAuto{part}%
  \Hy@raisedlink{\hyper@anchorstart{\@currentHref}\hyper@anchorend}%
}
\makeatother


\begin{document}

\tableofcontents

\chapter*{Important notes}

A very important part comes ahead.

\section{A numbered section}

This should show in the TOC, too...

\def\ptitle{Test title}

\tocless\part{%
  \texorpdfstring{%
    % tex string for \part itself
    Introduction: \emph{\ptitle} - \textbf{and more}. %
  }{%
    % pdf string for PDF Bookmarks TOC
    Introduction: \ptitle%
  }%
}
% tex string for the PDF typeset TOC
% \refstepcounter{part} - already done!
% \phantompart % for correct links in \addcontentsline
% \thepart \hspace{1em} from def of @part in book.cls:
\addcontentsline{toc}{part}{\thepart\hspace{1em} Introduction: \emph{\ptitle}.}

Something in this part...

\chapter{Inside the part}

The chapter inside the part...

\section{More inside the part}

The section more inside the part...

\end{document}

... except the TOC links are wrong; without the \phantompart (implemented by analogy to \phantomsection which has been said to fix these kind of issues), the test.toc file contains a correctly named link (part.1), but wrong page number (7):

\contentsline {section}{\numberline {0.1}A numbered section}{3}{section.0.1}
\contentsline {part}{I\hspace {1em} Introduction: \emph {Test title}.}{7}{part.1}
\contentsline {chapter}{\numberline {1}Inside the part}{9}{chapter.1}
\contentsline {section}{\numberline {1.1}More inside the part}{9}{section.1.1}

... and with the \phantompart uncommented, it's even worse - a wrongly named link (part.3), and wrong page number (7):

\contentsline {section}{\numberline {0.1}A numbered section}{3}{section.0.1}
\contentsline {part}{I\hspace {1em} Introduction: \emph {Test title}.}{7}{part.3}
\contentsline {chapter}{\numberline {1}Inside the part}{9}{chapter.1}
\contentsline {section}{\numberline {1.1}More inside the part}{9}{section.1.1}

I'd want the link to be called part.1, and to point to page 5, which is where the part title actually appears:

test.png

... and what you get in the .toc file (...{5}{part.1}) if you don't use \tocless and \addcontentsline.

So, how could I achieve the entry

\contentsline {part}{I\hspace {1em} Introduction: \emph {Test title}.}{5}{part.1}

... automatically in .toc, while having all three custom entries for a numbered \part?

  • I've added a better version – user31729 Nov 21 '14 at 2:29
2

This could be a possible solution, by providing a \enhancedpart command, having an 3rd argument containing the bookmark title.

Since hyperref automatically adds the bookmarks via \addcontentsline, this has to be kicked out. The bookmark package provides some features, but the destination key has to be set then. This is automatically done using a \hypertarget{...} to the part title. (I have posted a question some while ago concerning to switch off/bypass this feature of \addcontentsline, but it is still unanswered so far :-( Preventing automatic Hy@writebookmark in \addcontentsline)

\documentclass{book}

\usepackage{xcolor}%
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{etoolbox}%

\makeatletter
\newcommand{\enhancedpart@opt}[3][]{%
  \begingroup%
  \renewcommand{\Hy@writebookmark}[5]{}{}{}{}{}% Drop it%
  \phantomsection%
  \part[#1]{\hypertarget{bookmark::\number\value{part}}{}{#2}}
  \bookmark[level=-1,color={blue},dest={bookmark::\number\value{part}}]{#3}%
  \endgroup%
}%

\newcommand{\enhancedpart@noopt}[2]{%
  \enhancedpart[#1]{#1}{#2}%
}%

\newcommand{\enhancedpart}{%
\@ifnextchar[{\enhancedpart@opt}{\enhancedpart@noopt}
}%

\makeatother


\usepackage{hyperref}
\usepackage{bookmark}


% http://stackoverflow.com/questions/2785260/hide-an-entry-from-toc-in-latex
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline=\nocontentsline#1{#2}\egroup}

% copy of hyperref.sty \phantomsection:
%\makeatletter
%\def\phantompart{%
%  \Hy@MakeCurrentHrefAuto{part}%
%  \Hy@raisedlink{\hyper@anchorstart{\@currentHref}\hyper@anchorend}%
%}
%\makeatother


\begin{document}

\tableofcontents

\chapter*{Important notes}

A very important part comes ahead.

\section{A numbered section}

This should show in the TOC, too...


\enhancedpart{Test Title}{Title for bookmark}



Something in this part...

\chapter{Inside the part}

The chapter inside the part...

\section{More inside the part}

The section more inside the part...

\enhancedpart[Another title for the ToC]{A part for the book}{And even another title for the bookmarks}

\end{document}

Other version with xparse approach

In this way, the \enhancedpart command works as \part[]{} and does not generate a bookmark entry, or \part{}[] will use the {} argument as Toc entry, but [...] for the bookmark entry.

\documentclass{book}

\usepackage{xcolor}%
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{xparse}

\makeatletter
\NewDocumentCommand{\enhancedpart}{+o+m+o}{%
    \begingroup
    \renewcommand{\Hy@writebookmark}[5]{}{}{}{}{}%
    \phantomsection
    \IfNoValueTF{#3}{%
      \IfNoValueTF{#1}{%
        \part{#2}%
      }{%
        \part[#1]{#2}%
      }%
    }{%
      \IfNoValueTF{#1}{%
        \part{#2}\hypertarget{bookmark::\number\value{part}}{}
        }{%
          \part[#1]{#2}\hypertarget{bookmark::\number\value{part}}{}%
        }%          
      \bookmark[level=-1,color={blue},dest={bookmark::\number\value{part}}]{#3}
    }%
    \endgroup%
  }%
\makeatother

\usepackage[bookmarksnumbered=false]{hyperref}%
\usepackage{bookmark}%


\begin{document}

\tableofcontents

\chapter*{Important notes}

A very important part comes ahead.

\section{A numbered section}

This should show in the TOC, too...


% Toc entry different from main entry, No entry to the bookmarks
\enhancedpart[Test Title for Toc]{Part title}



Something in this part...

\chapter{Inside the part}

The chapter inside the part...

\section{More inside the part}

The section more inside the part...

% Toc entry, main entry, bookmark entry%
\enhancedpart[Another title for the ToC]{A new part for the book}[And even another title for the bookmarks]

% Toc entry the same as main entry and some bookmark%

\enhancedpart{A part for the book}[And even another title for the bookmarks, but the same for the TOC]

% Toc entry and main entry alike, no bookmarks
\enhancedpart{The ultimate part}

\end{document}
| improve this answer | |
  • Many thanks @ChristianHupfer - turns out, \part has an optional argument, where \texorpdfstring can be used to control all this without much hacking (see my post below); but I'll accept this because I like the new command approach that has three arguments. Cheers! – sdaau Nov 21 '14 at 1:28
  • 1
    @sdaau: A better approach (had no time ;-)) would be a key-value approach and even the bookmark title as a 2nd possible optional argument, via xparse – user31729 Nov 21 '14 at 1:29
  • 1
    @sdaau: All sectioning commands have this optional argument which must be catched somehow – user31729 Nov 21 '14 at 1:31
2

The end of the ToC clears the page (two pages for two-sided). So the \addcontentsline is being executed when TeX is already on page 7. To avoid this, you can add the contents line first, manually clearing the pages to ensure that the ToC does not need to start a new page:

\documentclass{book}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}

% http://stackoverflow.com/questions/2785260/hide-an-entry-from-toc-in-latex
\newcommand{\nocontentsline}[3]{}
\newcommand{\tocless}[2]{\bgroup\let\addcontentsline\nocontentsline#1{#2}\egroup}

% copy of hyperref.sty \phantomsection:
\makeatletter
\def\phantompart{%
  \Hy@MakeCurrentHrefAuto{part}%
  \Hy@raisedlink{\hyper@anchorstart{\@currentHref}\hyper@anchorend}%
}
\makeatother


\begin{document}

  \tableofcontents

  \chapter*{Important notes}

  A very important part comes ahead.

  \section{A numbered section}

  This should show in the TOC, too...

  \def\ptitle{Test title}

  \cleardoublepage
  \addcontentsline{toc}{part}{\thepart\hspace{1em} Introduction: \emph{\ptitle}.}%
  \tocless\part{%
    \texorpdfstring{%
      Introduction: \emph{\ptitle} - \textbf{and more}. %
    }{%
      Introduction: \ptitle%
    }%
  }

  Something in this part...

  \chapter{Inside the part}

  The chapter inside the part...

  \section{More inside the part}

  The section more inside the part...

\end{document}

ToC

| improve this answer | |
  • Many thanks for that, @cfr - now I finally understand why I was getting "7" as a page number there :) I just realized (my post below) that I can use the optional argument of \part to do this; but otherwise this is even more in the spirit of the MWE - so I'm really undetermined if I should change the accept here! :) I'll have to return to that later, though - thanks again and cheers! – sdaau Nov 21 '14 at 1:33
  • @sdau That's for you to decide ;). But I'm glad the explanation helped! All sectioning commands have this optional argument... – cfr Nov 21 '14 at 1:42
0

Ok, I think I got it; first, found like this that \part - or rather \@part - actually has an optional argument:

$ texdef -t latex -c book part -f
\part first defined in "book.cls".

\part:
\long macro:->\if@openright \cleardoublepage \else \clearpage \fi \thispagestyle {plain}\if@twocolumn \onecolumn \@tempswatrue \else \@tempswafalse \fi \null \vfil \secdef \@part \@spart 

$ texdef -t latex -c book @part -f
\@part first defined in "book.cls".

\@part:
macro:[#1]#2->\ifnum \c@secnumdepth >-2\relax \refstepcounter {part}\addcontentsline {toc}{part}{\thepart \hspace {1em}#1}\else \addcontentsline {toc}{part}{#1}\fi \markboth {}{}{\centering \interlinepenalty \@M \normalfont \ifnum \c@secnumdepth >-2\relax \huge \bfseries \partname \nobreakspace \thepart \par \vskip 20\p@ \fi \Huge \bfseries #2\par }\@endpart 

This optional argument is used exactly for setting the TOC entries - and using the \texorpdfstring in there, we can control either the PDF-typeset TOC, or the PDF Bookmark/Index TOC. So, the solution is to change this part in the OP MWE:

% ...
\def\ptitle{Test title}

% the \part optional argument handles either:
% pdf-typeset TOC (\contentsline), or PDF Bookmark/Index TOC!
\part[%
  \texorpdfstring{%
    Introduction: A \emph{\ptitle}.%
  }{%
    % pdf string for PDF Bookmarks TOC
    Introduction: B \ptitle%
  }%
]{%
  % tex string for \part itself
  Introduction: \emph{\ptitle} - \textbf{and more}. %
}

Something in this part...
% ...

So, no \tocless is needed; nor a separate \addcontentsline - and inside the .toc file, the expected entry is generated:

\contentsline {part}{I\hspace {1em}Introduction: A \emph {Test title}.}{5}{part.1}

... which also means the the correct page number is shown in TOC.

Hope that was it...

| improve this answer | |

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.