2

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}
\addtotoclist[api]{api}

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: enter image description here

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}
\addtotoclist[api]{api}

\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}
  • 2
    Welcome to TeX.SX! Please provide a compilable document, not just a fragment. – Bobyandbob Feb 6 '18 at 13:13
  • Thx for the hint! I've added an example document. – abones Feb 6 '18 at 16:50
  • TeX etc. is not very well trained about sorting... – user31729 Feb 7 '18 at 21:58
1

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
  \advance\count255 by 1
  \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
  \advance\count255 by 1
  \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
  \advance\count255 by 1
  \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. – abones 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 – Jasper Habicht 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. – Jasper Habicht 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/…). – Jasper Habicht Feb 8 '18 at 11:53

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.