2

I wonder if there is a way to sort a table of contents, by sectionames.

For example the actual table looks like this:

Toc:
   x  .... 2
   d  .... 3
   a  .... 5

but what I would like to see:

Toc:
   a  .... 5
   d  .... 3
   x  .... 2

I add the entries to the toc by calling

 \addcontentsline{toc}{section}{a}

but I can change this if needed.

Update as requested in comments: I need to generate a few (about 200) pages which are populated by a script from a database like list, for each entry I make a single page with some boxes on it and add the local name of the item to the toc by calling addcontentsline and pretending its a section (its not, and should not look one there, but the features of a section are usefull). Since it looked halfway as intended I started to add some code to add more entries (every item in the list has at least two names: a scientific and a common name) to a second fake-toc. Now I need to sort both of my tables. Since my "book" need to have to tocs: one for the scientific and one for the common names

 \usepackage{titletoc}
 \usepackage{tocloft}
 \newcommand{\listexamplename}{Other Name}
 \newlistof{example}{exp}{\listexamplename}
 \newcommand{\example}[1]{%
 \refstepcounter{example}
 \addcontentsline{exp}{example}
 {\protect{}#1}\par}

If you think its better to use something else, please point me to the code, I am not sure whats the "right" way to archive this. To make it even more complicated, I guess I will move the items later sorted by category into subsections. Therefor the "keep it in toc"-idea looked most promissing earlier. But now I am not sure anymore.

  • Please tell us more about the use case you have in mind. (I must confess to so far never having encountered a table of contents in which the sections aren't sorted in ascending order by page number (or section number...) and, instead, are sorted alphabetically by the names of the sectioning headers.) – Mico Oct 1 '17 at 18:29
  • 3
    this sounds more like an alphabetic index than a table of contents. LaTex usually defers sorting of indices to a separate program (makeindex) a "table of contents" is always in the order of the contents. – David Carlisle Oct 1 '17 at 18:37
  • you might need to say more about your use case, why do you need \addcontentsline{toc}{section} ? \section adds to the table of contents by default. – David Carlisle Oct 1 '17 at 18:38
2

One could use etoc + l3sort for that. However simplest is to sort a copy of the .toc file generated on first pass for example in an Emacs buffer (or do it automatized via unix command line tools), creating say foosorted.toc file. Then you only need to input the file. Something like

\documentclass{article}
\begin{document}
\IfFileExists{\jobname sorted.toc}{{\csname c@tocdepth\endcsname -1 \tableofcontents}\input{\jobname sorted.toc}}{\tableofcontents}
\addcontentsline{toc}{section}{Z}
\addcontentsline{toc}{section}{A}
\addcontentsline{toc}{section}{D}
\addcontentsline{toc}{section}{C}

\end{document}

edited to force opening of write stream so that the \addcontentsline{toc} actually work (would be easier with facilities from etoc package)

and to not use \section because numbering of course ruins sort

And you can actually use \addcontentsline{bar}{section}{...} to have to manipulate a \jobname.bar and \jobname sorted.bar for example. But you then need to open the write stream manually \tf@bar something like that, making it independent of regular \tableofcontents.

Problem of method above is one of actualization. You have to do the sort again after each new addition of sections. Or you wait final stage. Or you use shell-escape having added sort or whatever to list of allowed binaries.

  • I have actually tested (now) and it does work as promised! – user4686 Oct 1 '17 at 20:16
0

If you use latexmk you can put in your rule a call to a python script that reads the file generated by the latex compiler and sort the content.

This is the script I used to do this task:

#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Esse script organiza uma lista latex (toc) em ordem alfabética.
Ncessário indicar o do arquivo com a lista na variável filename.
'''

filename = 'path to resulted toc file after a compile sequence'

with open(filename) as f:
    content = f.readlines()

with open(filename, 'w') as f:
    for i in sorted(content):
        f.write(i)

The only thing you should do is indicate the path to file with the list to be sorted in the variable filename. This file is usually named [main tex file name].[defined toc name]. The script will open the file, read the lines, sort the lines alphabetically and then save the content in the same file.

You can call it right after you latexmk call in your Makefile.

That is my main rule in my Makefile:

latexmk -pdf -pdflatex="pdflatex -interactive=nonstopmode" -use-make $< && sort_list.py && pdflatex $(PROJNAME).tex

sort_list.py is the name I gave to the script.

If you not use latexmk you can execute your compile sequence, execute the python script and call a final pdflatex. This will organize your TOC.

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.