The relevant routines are \@starttoc
and \addcontentsline
which in turn use \addtocontents
and \@writefile
.
I try to explain the procedure (toc
stands here for toc
, lof
, lot
and other possible acronyms of personal list of somethings
)
From latex.ltx
(the LaTeX core file)
\def\@starttoc#1{%
\begingroup
\makeatletter
\@input{\jobname.#1}%
\if@filesw
\expandafter\newwrite\csname tf@#1\endcsname
\immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
\fi
\@nobreakfalse
\endgroup}
\def\addcontentsline#1#2#3{%
\addtocontents{#1}{\protect\contentsline{#2}{#3}{\thepage}}}
\long\def\addtocontents#1#2{%
\protected@write\@auxout
{\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
{\string\@writefile{#1}{#2}}}
\def\contentsline#1{\csname l@#1\endcsname}
I'll shift the \@starttoc
explanation to the end.
We see, that \addtocontents
is apart from the formating of the using \contentsline
is effectively a \string\@writefile
, i.e. this string is
written into the .aux
file. (Side note: \label
, \index
and glossary
are 'gobbled', etc. 'disabled' within the .aux
file)
In the 2nd compilation run, this \@writefile
finally sets its contents to the relevant toc
file (i.e. .toc
, .lof
, .lot
. etc.)
Some lines before we find the \@writefile
command, having the #1
as the toc
signature.
\long\def\@writefile#1#2{%
\@ifundefined{tf@#1}\relax
{\@temptokena{#2}%
\immediate\write\csname tf@#1\endcsname{\the\@temptokena}%
}%
}
Now any ToC
- related file is bound to a file handle named \tf@toc
or \tf@lof
etc, i.e. \@writefile
tries to write to the file handle \tf@#1
(you remember #1
has the toc
- extension) -- it checks first if \tf@#1
exists and if so, stores the real content to a token \@temptokena
which is written to \csname tf@#1\endcsname
-- the file handle macro call has to constructed this way due to its variability (#1 as part of the name
).
Now back to \@starttoc
As long no \@starttoc{toc}
command was given, the file handle \tf@#1
does not exist and therefore the \@writefile
commands in the .aux
file does nothing.
But first, the existing \jobname.#1
(i.e. the formatted toc
file) is read and, unless \nofiles
wasn't specified, the handle \tf@#1
is generated and the old \jobname.#1
will be 'erased' and written again, for possible new entries in following runs.
Each \tableof...
or \listof...
command uses \@starttoc{toc}
etc., at least in the versions by the standard classes, e.g. from article.cls
:
\newcommand\tableofcontents{%
\section*{\contentsname
\@mkboth{%
\MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
\@starttoc{toc}%
}
The \section*
command is irrelevant here -- \@starttoc
is the important feature!
Back to \@writefile
The key tool is \@writefile
which has two arguments. You could write basically anything to .aux
capsuled within \@writefile
, which in turn creates the real 'content'
Here's a little sample document (sampletoc.tex
)
\documentclass{book}
\begin{document}
\tableofcontents
\chapter{One}
\section{First}
\section{Second}
\chapter{Two}
\section{First}
\section{Second}
\end{document}
... and its corresponding sampletoc.aux
file
\relax
\@writefile{toc}{\contentsline {chapter}{\numberline {1}One}{3}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{toc}{\contentsline {section}{\numberline {1.1}First}{3}}
\@writefile{toc}{\contentsline {section}{\numberline {1.2}Second}{3}}
\@writefile{toc}{\contentsline {chapter}{\numberline {2}Two}{5}}
\@writefile{lof}{\addvspace {10\p@ }}
\@writefile{lot}{\addvspace {10\p@ }}
\@writefile{toc}{\contentsline {section}{\numberline {2.1}First}{5}}
\@writefile{toc}{\contentsline {section}{\numberline {2.2}Second}{5}}
It's clear, that \contentsline
is written literally to the .toc
wile, while the section and page numbers are used from the very moment when the \addcontentsline
was used (i.e. \thesection
etc. are expanded)
Now, this is the procedure:
- Copy the
\@starttoc
command from latex.ltx
and change the file handle name to something different, say \mypersonaltoc
- Copy
\@writefile
and rename it to,say, \@mywritefile
and change tf@#1
to mypersonaltoc
(without \\
)
- Call
\addtocontents{}{your content}
Or define your own toc
extensions, say, johnB
and use \addtocontents{johnB}{your content}
and \@starttoc{johnB}
at the appropiate place.
\addcontentsline{toc}{section}{foo}
do the trick?etoc
orminitoc
?