# Sort custom TOC by name

I have defined a custom TOC with two arguments using \DeclareNewTOC:

\DeclareNewTOC[
type=api,
types=apis,
float,
floattype=5,
name=Api,
floatpos=ht,
listname={API-List}
]{loa}


Currently the entries are listed in the order they appear in the document. Is it possible to order them by name (in my case argument #1)?

It shows up in this form:

Here is a small compilable document for the image above:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% KOMA Document

\documentclass{scrbook}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Packages

\usepackage{array}
\usepackage{tabularx, colortbl}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Macros

\DeclareNewTOC[
type=api,
types=apis,
float,
floattype=5,
name=Api,
floatpos=ht,
listname={API-List}
]{loa}

\makeatletter
\newwrite\@apifile
\newif\if@apifilewritten
\renewcommand*{\@apifilewrittentrue}{\global\let\if@apifilewritten\iftrue}
\renewcommand*{\@apifilewrittenfalse}{\global\let\if@apifilewritten\iffalse}
\newcommand*{\apioverview}{
\closeapioverview
\InputIfFileExists{\jobname-\thechapter.api}{}{
\typeout{No file \jobname-\thechapter.api' found.}
}
}
\newcommand*{\startapioverview}{
\if@apifilewritten\else
\if@filesw
\typeout{Open new api file \jobname-\thechapter.api'}%
\@apifilewrittentrue
\openout\@apifile \jobname-\thechapter.api
\protected@write\@apifile{}{%
\string\begin{tabularx}{\string\textwidth}{|X|c|c|}^^J
\string\hline^^J
\string\textbf{API}&
\string\textbf{Method}&
\string\textbf{Page}\string\\^^J
\string\hline^^J
\string\hline
}%
\fi
\fi
}
\newcommand*{\closeapioverview}{%
\if@apifilewritten
\protected@write\@apifile{}{%
\string\end{tabularx}%
}%
\closeout\@apifile
\@apifilewrittenfalse
\fi
}
\newcommand*{\setapientry}[2]{%
\startapioverview
\protected@write\@apifile{}{ \detokenize{#1}&\detokenize{#2}&\thepage\string\\^^J \string\hline}%
}

\makeatletter
\AtEndDocument{\closeapioverview}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Document Content

\begin{document}
\chapter{Chapter 1}
\section{Overview}
\apioverview
\section{Content}
\subsection{def}
\setapientry{def}{SomeMethod}
\subsection{abc}
\setapientry{abc}{AnotherMethod}

\chapter{Chapter 2}
\section{Overview 2}
\apioverview
\section{Content 2}
\subsection{jkl}
\setapientry{jkl}{SomeMethod}
\subsection{ghi}
\setapientry{ghi}{AnotherMethod}
\end{document}

• Welcome to TeX.SX! Please provide a compilable document, not just a fragment. Feb 6 '18 at 13:13
• Thx for the hint! I've added an example document. Feb 6 '18 at 16:50
• TeX etc. is not very well trained about sorting...
– user31729
Feb 7 '18 at 21:58

You could make use of makeindex. Run the file first with PDFLaTeX, then run MakeIndex and again PDFLaTeX.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% KOMA Document

\documentclass{scrbook}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Packages
\usepackage{array}
\usepackage{tabularx, colortbl}

\usepackage{filecontents, makeidx}
\makeindex

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Macros

\begin{filecontents}{\jobname.mst}
preamble       "\\begin{tabularx}{\\textwidth}{|X|c|c|}\n\\hline\n\\textbf{API}\&\\textbf{Method}\&\\textbf{Page}\\\\\n\\hline\\hline\n"
postamble      "\n\\hline\n\\end{tabularx}\n"
group_skip     "\\hline"
item_0         "\n"
item_1         "\n"
delim_0        "\&"
delim_1        "\&"
delim_t        "\\\\"
\end{filecontents}

\newcommand{\setapientry}[2]{%
\index{\detokenize{#1}&\detokenize{#2}}%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Document Content

\begin{document}
\chapter{Chapter 1}

\section{Overview}

%\apioverview
\printindex

\section{Content}

\subsection{def}
\setapientry{def}{SomeMethod}

\subsection{abc}
\setapientry{abc}{AnotherMethod}

\end{document}


Edit 1: The following makes use of imakeidx instead of makeidx with a bit of tweaking and hacking and allows for multiple chapters. However it spams the project folder and is a bit slow. You have to run PDFLaTeX twice.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% KOMA Document

\documentclass{scrbook}

\newcounter{maxchap}
\setcounter{maxchap}{5}  % Set to the total of chapters in your document

\count255=0
\loop\ifnum\count255<\number\themaxchap
\expandafter\IfFileExists\expandafter{chap\number\count255.idx}{%
\immediate\write18{makeindex -s idxstyle.ist chap\number\count255.idx}{}%
}
\repeat

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Packages
\usepackage{array}
\usepackage{tabularx, colortbl}

\usepackage{filecontents}
\usepackage[noautomatic]{imakeidx}

\count255=0
\loop\ifnum\count255<\number\themaxchap
\begingroup\edef\x{\endgroup
\noexpand\makeindex[name=chap\number\count255]}\x
\repeat

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Macros

\begin{filecontents}{idxstyle.ist}
preamble       "\\begin{tabularx}{\\textwidth}{|X|c|c|}\n\\hline\n\\textbf{API}\&\\textbf{Method}\&\\textbf{Page}\\\\\n\\hline\\hline\n"
postamble      "\n\\hline\n\\end{tabularx}\n"
group_skip     "\\hline"
item_0         "\n"
item_1         "\n"
delim_0        "\&"
delim_1        "\&"
delim_t        "\\\\"
\end{filecontents}

\newcommand{\setapientry}[2]{%
\expandafter\index\expandafter[chap\thechapter]{\detokenize{#1}&\detokenize{#1}}%
}

\newcommand{\apioverview}[1]{%
\expandafter\InputIfFileExists\expandafter{chap\thechapter.ind}{}{}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Document Content

\begin{document}
\chapter{Chapter 1}

\section{Overview}

\apioverview

\section{Content}

\subsection{def}
\setapientry{def}{SomeMethod}

\subsection{abc}
\setapientry{abc}{AnotherMethod}

\chapter{Chapter 2}

\section{Overview}

\apioverview

\section{Content}

\subsection{jkl}
\setapientry{jkl}{SomeMethod}

\newpage

\subsection{ghi}
\setapientry{ghi}{AnotherMethod}

\subsection{abc}
\setapientry{abc}{AgainAnotherMethod}

\end{document}


After changes in the document, you should delete all the chap files and let the script recreate them.

(I got some inspiration from here and here)

Edit 2: I merged your approach with mine. It is much quicker than my first try where loads of index files are generated and processed that may be eventually empty. So here is finally a working solution. To be compiled two times with PDFLaTeX.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% KOMA Document

\documentclass{scrbook}

\newcounter{maxchap}
\setcounter{maxchap}{5}  % Set to the total of chapters in your document

\count255=0
\loop\ifnum\count255<\number\themaxchap
\expandafter\IfFileExists\expandafter{chap\number\count255.idx}{%
\immediate\write18{makeindex -s idxstyle.ist chap\number\count255.idx}{}%
}
\repeat

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Packages

\usepackage{array}
\usepackage{tabularx, colortbl}

\usepackage{filecontents}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Macros

\begin{filecontents}{idxstyle.ist}
preamble       "\\begin{tabularx}{\\textwidth}{|X|c|c|}\n\\hline\n\\textbf{API}\&\\textbf{Method}\&\\textbf{Page}\\\\\n\\hline\\hline\n"
postamble      "\n\\hline\n\\end{tabularx}\n"
group_skip     "\\hline"
item_0         "\n"
item_1         "\n"
delim_0        "\&"
delim_1        "\&"
delim_t        "\\\\"
\end{filecontents}

\makeatletter
\newwrite\@apifile
\newif\if@apifilewritten
\renewcommand*{\@apifilewrittentrue}{\global\let\if@apifilewritten\iftrue}
\renewcommand*{\@apifilewrittenfalse}{\global\let\if@apifilewritten\iffalse}
\newcommand*{\apioverview}{
\closeapioverview
\InputIfFileExists{chap\thechapter.ind}{}{
\typeout{No file chap\thechapter.ind' found.}
}
}
\newcommand*{\startapioverview}{
\if@apifilewritten\else
\if@filesw
\typeout{Open new idx file chap\thechapter.idx'}%
\@apifilewrittentrue
\openout\@apifile chap\thechapter.idx
\fi
\fi
}
\newcommand*{\closeapioverview}{%
\if@apifilewritten
\closeout\@apifile
\@apifilewrittenfalse
\fi
}
\newcommand*{\setapientry}[2]{%
\startapioverview
\protected@write\@apifile{}{ \string\indexentry{\detokenize{#1}&\detokenize{#2}}{\thepage} }%
}

\makeatletter
\AtEndDocument{\closeapioverview}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Document Content

\begin{document}
\chapter{Chapter 1}
\section{Overview}
\apioverview
\section{Content}
\subsection{def}
\setapientry{def}{SomeMethod}
\subsection{abc}
\setapientry{abc}{AnotherMethod}

\chapter{Chapter 2}
\section{Overview 2}
\apioverview
\section{Content 2}
\subsection{jkl}
\setapientry{jkl}{SomeMethod}
\subsection{ghi}
\setapientry{ghi}{AnotherMethod}
\end{document}

• The problem with this solution is, that the index is document wide and not limited to a chapter (as the original code). I've added a second chapter to the example above to show the chapter limitation of the index. Feb 7 '18 at 8:33
• True, but afaik there are ways to use multiple indices. At least the functionality of makeindex allows for sorting Feb 7 '18 at 11:06
• @abones: The solution is to combine both of our approaches: Use your approach to write custom idx files to the working library in a format that can be processed in a second run with makeindex. During the processing with makeindex the table formatting is made and the sub-tocs are put at the correct places. Feb 7 '18 at 17:24
• By the way: Vertical lines in tables are considered relatively bad typographical practice. You should have a look at the booktabs package when typesetting tables (see eg: tex.stackexchange.com/questions/69800/…). Feb 8 '18 at 11:53