1

I'm aware that using package titletoc one can easily change the format of ToC. But, I'm wondering if there exist some solutions to make the left margin in ToC flexible. By "flexible", I mean that the left margin of certian level will change according to the current label number. For example, if there exist a \chapter, but no \section, \subsection and \subsubsection, then an immediate \paragraph will have the same margin in TC as the normal \section. I know that the margin of a section title is basically controlled by the <left> option in titletoc package. So my naive idea is to combine this with some \ifthenelse.

\documentclass{book}
\usepackage{xifthen}
\usepackage{titletoc}

\setcounter{tocdepth}{4}
\setcounter{secnumdepth}{4}

\newlength{\TOCparagraphskip}
\setlength{\TOCparagraphskip}{9em}

\titlecontents*
    {paragraph}
    [\ifnum\pdfmatch{.[.].[.].[.]0[.].}{\thecontentslabel}=1
        \setlength{\TOCparagraphskip}{7em}%
        \ifnum\pdfmatch{.[.].[.]0[.]0[.].}{\thecontentslabel}=1
            \setlength{\TOCparagraphskip}{3.8em}%
            \ifnum\pdfmatch{.[.]0[.]0[.]0[.].}{\thecontentslabel}=1
                \setlength{\TOCparagraphskip}{1.5em}%
                \ifnum\pdfmatch{0[.]0[.]0[.]0[.].}{\thecontentslabel}=1
                    \setlength{\TOCparagraphskip}{0em}%
                \fi
            \fi
        \fi
    \else
        \setlength{\TOCparagraphskip}{9em}%
    \fi    
    \TOCparagraphskip]{}{\textbullet{}\;}{}{}[\quad]



\begin{document}
    \tableofcontents
    \paragraph{paragraph}


    \chapter{chapter one}

   
\end{document}

But, unfortunately, my naive try give error message.

 (./test.toc
./test.toc:1: Missing number, treated as zero.
<to be read again> 
                   \protect 
l.1 ...aph}{\numberline {0.0.0.0.1}paragraph}{1}{}
                                                  %
A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)

./test.toc:1: Illegal unit of measure (pt inserted).
<to be read again> 
                   \protect 
l.1 ...aph}{\numberline {0.0.0.0.1}paragraph}{1}{}
                                                  %
Dimensions can be in units of em, ex, in, pt, pc,
cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!
I'll assume that you meant to say pt, for printer's points.
To recover gracefully from this error, it's best to
delete the erroneous units; e.g., type `2' to delete
two letters. (See Chapter 27 of The TeXbook.)


./test.toc:1: Package calc Error: `\let ' invalid at this point.

See the calc package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.1 ...aph}{\numberline {0.0.0.0.1}paragraph}{1}{}
                                                  %
I expected to see one of: + - * / )

But I've checked that with or without my personal hack, the .toc file are in fact the same.

\contentsline {paragraph}{\numberline {0.0.0.0.1}paragraph}{1}{}%
\contentsline {chapter}{\numberline {1}chapter one}{3}{}%
\contentsfinish 

So, I don't know where is the problem. Or, maybe someone else has some better idea to implement this functionality?

8
  • The tocloft package is also designed for controlling the appearance of the ToC, etc. Nov 16, 2021 at 19:42
  • I have no idea why you would want to follow a \chapter by a \paragraph with no intermediate divisions. As a reader I would find that very confusing. Nov 17, 2021 at 18:10
  • @PeterWilson So, the structure of my note is as follows. Basically I will arrange my note into different down-to-the-earth topics, for example, maybe the first topic will be a summarization of a paper and the second will be one of my thoughts got during my bath. I will continuously enlarge and rearrange every topics during my study. In LaTeX file, every topic is a paragraph. Then, I will group my topics. But, this grouping is not bottom-to-up, but up-to-bottom to comply with the structure of a LaTeX file.
    – Qi Tianluo
    Nov 18, 2021 at 6:06
  • That is to say, if I want to group two topics, then the first thing I will do is to create a chapter (I don't like part so I don't use it), then if subdivision is needed, I will create sections and so on. So, it is often the case that my chapter will govern only many paragraph, but with no section since I find subdivision is not needed. For example when there are only two topics (paragraph), then I hardly find no cause to create sections.
    – Qi Tianluo
    Nov 18, 2021 at 6:09
  • "In LaTeX file, every topic is a paragraph" this means that I use paragraphs to identify topics in the LaTeX file. I will also use some specific formatting style to make readers (actually, usually I'm the only reader of my note) know that ok this is a topic and this is a new topic. To summarize, basically my note is consisted of many paragraphs (topics), and only when needed, I will then try to group them into chapters, sections, and so on.
    – Qi Tianluo
    Nov 18, 2021 at 6:12

1 Answer 1

2

Here's how I would implement what you want instead.

Basic example:

\documentclass{book}
\usepackage{titletoc}

\setcounter{tocdepth}{4}
\setcounter{secnumdepth}{4}

\newlength{\TOCparagraphskip}
\setlength{\TOCparagraphskip}{9em}

\titlecontents*
    {paragraph}
    [\TOCparagraphskip]{}{\textbullet{}\;}{}{}[\quad]



\begin{document}
    \tableofcontents
    \paragraph{paragraph}

    \chapter{chapter one}
    \addtocontents{toc}{\setlength{\TOCparagraphskip}{1em}}

    \paragraph{paragraph 2}
   
\end{document}

You see that but inserting various \setlength into the toc file you can change the left indent on the fly.

Now let's try to automate it. Unfortunately the <after code> in titlesec doesn't work because it results in the contents line being printed too early. However, trying to use etoolbox to append code to run after sectioning commands is prone to unexpected errors.

In the solution below, what we do is the following:

  • We patch the \paragraph command so that before the normal \paragraph is called, we check to see if the indentation needs changing. If it does, then we issue an \addtocontents to do so.
  • The checking is done with a boolean toggle that we defined. After we issue the \addtocontents, we reset the toggle.
  • Patching before the command is less problematic, since you don't have to worry about * forms or other shenanigans. I did it by hand below, but I think using the \pretocmd macro from etoolbox would work just as well.
  • We patch each sectioning command (\chapter, \section, \subsection, and so on; I got tired of typing so you have to add the additional levels yourself) to indicate that the indentation level has changed, and store the appropriate lengths.
  • The sectioning commands now set the boolean toggle to true, and then store the appropriate lengths so that when \paragraph is called the right length is placed in the .toc file.
  • The boolean toggle is not strictly necessary: it helps keep the size of the .toc file down (otherwise you print one \setlength command for each \paragraph). In the example below it would be 7 times without the toggle, and 5 times with the toggle.
\documentclass{book}
\usepackage{titletoc}

\setcounter{tocdepth}{4}
\setcounter{secnumdepth}{4}

\newlength{\TOCparagraphskip}
\setlength{\TOCparagraphskip}{9em}


\titlecontents*
    {paragraph}
    [\TOCparagraphskip]{}{\textbullet{}\;}{}{}[\quad]

\makeatletter
\newif\ifqt@tocskipchanged
\qt@tocskipchangedfalse

% Some helper macros to simplify typing
\newcommand\qt@tocchangepskip[1]{\addtocontents{toc}{\setlength{\TOCparagraphskip}{#1}}}

% Patch the sectioning commands
\let\qt@chap\chapter
\def\chapter{\qt@tocskipchangedtrue\gdef\qt@prepare{\qt@tocchangepskip{1.5em}}\qt@chap}
\let\qt@sec\section
\def\section{\qt@tocskipchangedtrue\gdef\qt@prepare{\qt@tocchangepskip{4em}}\qt@sec}
\let\qt@ssec\subsection
\def\subsection{\qt@tocskipchangedtrue\gdef\qt@prepare{\qt@tocchangepskip{7em}}\qt@ssec}
%% insert additional definitions here for subsubsections etc.
% Patch the paragraph command
\let\qt@para\paragraph
\def\paragraph{\ifqt@tocskipchanged\qt@prepare\fi\qt@tocskipchangedfalse\qt@para}
% In case there are paragraphs outside of traditional chapters. Call this after \tableofcontents
\def\setdefaultparaskip{\qt@tocskipchangedtrue\gdef\qt@prepare{\qt@tocchangepskip{0em}}}
\makeatother

\begin{document}
    \tableofcontents

    \setdefaultparaskip % Only necessary if there is a paragraph before any chapters
    \paragraph{paragraph}

    \chapter{chapter one} 
    \paragraph{paragraph 2}

    \section{Section one}

    \paragraph{paragraph 3}
    
    \section{Section two}

    \paragraph{paragraph 4}

    \paragraph{paragraph 4.5}

    \paragraph{paragraph 4.6}

    \chapter{chapter two}
    \paragraph{paragraph 5}
  
\end{document}

The output TOC from the code above:

enter image description here

8
  • Brilliant! Yesterday I was stuck with the idea of implementing this redefinition at the beginning of \paragraph, but your idea is surely more elegant!
    – Qi Tianluo
    Nov 16, 2021 at 10:56
  • Hey, I tried your suggestion of adding \addtocontents{toc}{\setlength{\TOCparagraphskip}{1em}} to the <after code> of \titleformat. But this does not fix the problem. It seems that now every paragraph item in ToC is typeset as if it all follows a \chapter command. I suspect that this is because ToC itself come with a \chapter command. I also get this suspect form the fact that the \titleformat's <after code> version will get an additional line \TOCparagraphskip 1.5em\relax in the beginning of toc file if 1.5em is the skip I set after \chapter.
    – Qi Tianluo
    Nov 18, 2021 at 14:09
  • 1
    You are right that it didn't work, but that has to do with the order in which the commands were written to the .toc file. Let me see if I can hack a workaround. Nov 18, 2021 at 22:35
  • 1
    @QiTianluo: updated. Instead of using titlesec I just did the length setting by hand in this version. Nov 18, 2021 at 23:09
  • Thank you very much! I find your answer very helpful!
    – Qi Tianluo
    Nov 21, 2021 at 11:48

You must log in to answer this question.

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