11

I am trying to generate an inline Table of Contents that would have no title, a depth of two and the following formatting:

1. Section one ‖ 1.1. Subsection one; 1.2. Subsection two ‖ 2. Section two

I played with titletoc and almost got the right result, except that the ToC is left aligned rather than justified, and my formatting actually overrides the standard one which I don't know how to restore afterwards.

So I tried redefining \tableofcontents, \contensline and \numberline but got stuck with the following problems:

  1. How can I find out from inside \numberline what level of heading I am formatting (so as to differentiate between bold for \sections and italics for \subsections? Or alterantively,
  2. How can I get rid of the call to \numberline inside the #2 argument for \contensline in file.toc? And,
  3. How can I know if the (sub)section I am formatting is the first or the last one in row, so as to put the "‖" and ";" separators in the right places?

I'm actually more interested in learning to write macros in TeX than to solve this particular problem, so I would be most grateful for an explanation rather than simply a solution, if it's not a problem.

Edit: A minimal example (ignore "‖"  missing from the standard font; this isn't a problem):

\documentclass{article}

\makeatletter
\renewcommand{\tableofcontents}{\noindent\@starttoc{toc}}
\renewcommand{\l@section}[2]{#1~‖}           % How can I tell here if anything (and what?) follows?
\renewcommand{\l@subsection}[2]{#1;}         % As above.
\renewcommand{\numberline}[1]{\textbf{#1}.~} % How can I tell here if it's a section or a subsection?
\makeatother

\begin{document}
\tableofcontents
\section{Section one}
\subsection{Subsection one}
\subsection{Subsection two}
\section{Section two}
\end{document}

What the above gives is this:

1. Section one ‖ 1.1. Subsection one; 1.2. Subsection two; 2. Section two ‖

The problems are:

  1. Subsection numbers are in bold rather than italic.
  2. Subsection two is followed by a semicolon.
  3. Section two is followed by a "‖".
1
  • 4
    You should show what you've got so far, with a minimal example of code, so that somebody can start from there.
    – egreg
    Feb 23, 2012 at 22:23

2 Answers 2

6
+50

The following solution adheres to your requirements:

enter image description here

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newtoggle{section}\togglefalse{section}% "In section" toggle
\newtoggle{atstarttoc}% "First entry in ToC" toggle
\newcounter{tocsubsection}% Keep track of first subsection
\makeatletter
\renewcommand{\tableofcontents}{\noindent\toggletrue{atstarttoc}\@starttoc{toc}}
\renewcommand{\l@section}[2]{%
  \iftoggle{atstarttoc}{\togglefalse{atstarttoc}\relax}
    {$\vert$~}%
  \setcounter{tocsubsection}{0}%
  \toggletrue{section}% We're in a section
  #1%  
}
\renewcommand{\l@subsection}[2]{%
  \ifnum\value{tocsubsection}<1
    $\vert$~%
  \else
    \unskip;~%
  \fi%
  \stepcounter{tocsubsection}%
  \togglefalse{section}% We're not in a section
  #1}         % As above.
\renewcommand{\numberline}[1]{%
  \iftoggle{section}
    {\textbf{#1}.~}
    {\textit{#1}.~}%
}
\makeatother
\begin{document}
\tableofcontents
\section{Section one}
\subsection{Subsection one}
\subsection{Subsection two}
\section{Section two}
\subsection{Subsection one}
\subsection{Subsection two}
\subsection{Subsection three}
\subsection{Subsection four}
\section{Section three}
\section{Section four}
\subsection{Subsection one}
\subsection{Subsection two}
\end{document}

etoolbox provides "toggles" (boolean true/false variables) that is used to identify (1) section - whether you're setting a specific title (\section or \subsection) or (2) atstarttoc - whether you're at the start of the ToC or not.

The above solution assumes that you only have \section and \subsection titles, although it can be extended to accommodate more levels.

1
  • Fantastic, this is just what I wanted, thanks a lot! I will award the bounty as soon as I can (it says I can only do it in 19 hours.)
    – Kamil S.
    Feb 27, 2012 at 0:12
4

First, I will try to explain why fully answering your answer is quite difficult.

\l@section and friends are commands that define the appearance of various items in the table of contents, and at this point LaTeX does not have the means to know in which section or subsection we are.

If you want to influence the way they are processed, you should do it at a higher level, i.e. in the definition of the sectioning commands. All lower divisions (starting from section downward) are defined in LaTeX2e using the \@startsection command which, obviously, you would be very unwise to try to modify. You can have a look at it in the latex.ltx file.

Besides, LaTeX processes these document divisions when it sees them – so we have means to know whether some section or subsection is the first one (or second one, etc.), but we have no easy way of finding out whether it is the last one. If you wanted to do that, you would need to ask LaTeX to write the number of the counter before each reset to a separate file, then retrieve it in a second run of LaTeX so as to use it. This, for instance, is how tables of contents are written (and why they need two compilations).


The solution I am proposing will try to solve the first problem [edit: and the second one too]. We are going to redefine the \subsection command so that the first subsection will always typeset || before itself, and each subsection will end with a semi-colon in the table of contents [edit: except the last subsection of each section]. We will also define a command that takes care of formatting the number of the subsection.

% Used for playing around with the semicolons
\usepackage{refcount}

\makeatletter

\renewcommand{\tableofcontents}{\noindent\@starttoc{toc}}
\renewcommand{\l@section}[2]{#1}% No other modification needed here
\renewcommand{\l@subsection}[2]{#1}% No other modification needed here
\renewcommand{\numberline}[1]{\textbf{#1}.~}
% Create a new command for italic numbers in the TOC
\newcommand{\numbersubsec}[1]{\textit{#1}.~}

% Create a new counter for the semicolons. It is reset at every \section
\newcounter{cntsemicolon}[section]

% Save the old definition of \subsection under the name \oldsubsection
\let\oldsubsection=\subsection

% Overwrite \subsection
\renewcommand{\subsection}[1]{%
    % Increase the subsection counter, as it will not be increased automatically + Increase the semicolon counter
    \refstepcounter{subsection}%
    \refstepcounter{cntsemicolon}\label{mycounterref@\thesection}%
    % Check whether this is the first subsection or not
    \ifnum\value{subsection}<2%
        % If the value of the subsection counter is <2, it is the first subsection
        % Add the subsection to the TOC with the extra || (\textbar) and ;
        \addcontentsline{toc}{subsection}{\unskip~\textbar\textbar~\numbersubsec{\thesubsection}#1%
        % If the value of the subsection counter is not equal to the maximum value of the semicolon counter for the section, add a semicolon
        \ifnum\value{subsection}=\number\numexpr\getrefnumber{mycounterref@\number\value{section}}~\textbar\textbar~\unskip\else;\fi}%
    \else%
        % Else (i.e. if it is not the first subsection)
        % Add the subsection to the TOC with ; at the end
        \addcontentsline{toc}{subsection}{\numbersubsec{\thesubsection}#1%
        % If the value of the subsection counter is not equal to the maximum value of the semicolon counter for the section, add a semicolon
        \ifnum\value{subsection}=\number\numexpr\getrefnumber{mycounterref@\number\value{section}}~\textbar\textbar~\unskip\else;\fi}%
    \fi%
    % Create a subsection heading in the main text
    % The \hspace command create the white-space between the number and the text.
    % Its value is copied from the original \subsection command.
    \oldsubsection*{\thesubsection\hspace{1.5ex \@plus .2ex}#1}}

\makeatother

Note: we use the starred version of \subsection, which does NOT increase the counter and does not add anything to the TOC (it also does not set any page headers, so you might need to set them manually inside the new command, too). This way, it is possible to tamper with the data that will actually be added to the table of contents.

As you can see, after three runs, it will result in something like:

1. Section one || 1.1. Subsection one; 1.2. Subsection two || 2. Section two 3. Section three

The output

Edit: Added a solution to the semicolon issue using @egreg's answer to this post. Edit 2: Added the || before the next section instead of the semicolon too, as I just noticed they were there in the OP's question.

6
  • As for #2: a method like in tex.stackexchange.com/questions/38561/… might do the trick, I guess.
    – mbork
    Feb 26, 2012 at 22:50
  • @mbork Thank you for your comment. I tried to find a solution using your code, but ended up finding something more suitable for the current needs (or at least easier for me to work on).
    – ienissei
    Feb 26, 2012 at 23:33
  • Thank you for the answer! I'm sorry you don't get the bounty but Werner's solution was closer to what I wanted.
    – Kamil S.
    Feb 27, 2012 at 0:16
  • @KamilS. Well, I suppose your requirements could have been read in several ways (i.e. whether to surround the subsections with || as I did, or whether to separate the sections with || as Werner did). But that's fine, I am glad you got what you wanted!
    – ienissei
    Feb 27, 2012 at 0:21
  • @ienissei I'm sorry if I wasn't clear enough. But at least one bit is for sure, and that is the ‖ at the very end. I sincerely wish you better luck next time, and thank you for your answer again.
    – Kamil S.
    Feb 27, 2012 at 0:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .