I would like to have multiple tables of contents in the document, each based on a simple filter, e.g. containing a specific word in the heading/section title. I may have multiple, but well-defined keywords and for each of them I would like to have a separate table of contents, i.e:

• \tableofcontents “implementation” <- table of contents of all chapters/sections containing the word “implementation” plus their parents
• \tableofcontents “design” <- table of contents of all chapters/subsections containing the word “design” plus their parents
• and so on

One could grep/sed the tex files to find these headings and then generate a list of links, but maybe it is possible to do it directly in latex?

Here is a mode detailed example:

\usepackage{mdframed}

\definecolor{MISRARuleBackgroundColor}{rgb}{0.86,0.88,0.94}
\definecolor{RuleBackgroundColor}{rgb}{0.86,0.94,0.88}
\definecolor{RuleBorderColor}{rgb}{0.29,0.39,0.68}

\newcommand{\MISRARule}[3]{\bigskip\begin{mdframed}[backgroundcolor=MISRARuleBackgroundColor,linecolor=RuleBorderColor,linewidth=1pt]\textbf{Rule #1 (#2)} \newline \textbf{#3} \label{#1}\end{mdframed}\nopagebreak See MISRA C++ 2008 \cite{MISRAC++2008}}

\newcommand{\Rule}[3]{\bigskip\begin{mdframed}[backgroundcolor=MISRARuleBackgroundColor,linecolor=RuleBorderColor,linewidth=1pt]\textbf{Rule #1 (#2)} \newline \textbf{#3} \label{#1}\end{mdframed}\nopagebreak}

.....

\Rule{A0-4-1}{required, toolchain, non-automated}{Floating-point implementation shall comply with IEEE 754 standard.}

\Rule{A0-4-3}{required, toolchain, automated}{The implementations in the chosen compiler shall strictly comply with the C++14 Language Standard.}

\MISRARule{M1-0-2}{required, implementation, non-automated}{Multiple compilers shall only be used if they have a common, defined interface.}

\MISRARule{M15-0-3}{required, implementation, automated}{Control shall not be transferred into a try or catch block using a goto or a switch statement.}

\Rule{A15-0-2}{required, implementation, partially automated}{At least the basic guarantee for exception safety shall be provided for all operations. In addition, each function may offer either the strong guarantee or the nothrow guarantee}

...

Then I  would write something like

\begin{appendix}

\chapter{Allocation of rules to work products}

\section{Rules related to toolchain}

# list here the table of contents / table of references to all rules that are allocated to "toolchain"
\tableofcontents_mframeds_that_contain_string{toolchain}

\section{Rules related to implemtentation}

# list here the table of contents / table of references to all rules that are allocated to "implementation"
\tableofcontents_mframeds_that_contain_string{implementation}

\end{appendix}}


I am not sure what "parents" mean and the question is slightly ambiguous in that it is not entirely clear to me where to search for keywords and if we should match whole words or whether implementations should count as a match for implementation. The format of the many tables of contents is also not specified. As a result the code may not quite meet the OP's requirements, but it should be straightforward to modify it -- except possibly for the unexplained "parents".

My code defines four macros:

• \DefineContentKeywords -- defines the keywords to track. For example, \DefineContentKeywords{design,implementation,toolchain}
• \AddContentsLine -- is used inside \Rule to add the current "rule" to the different table of contents indices (an "internal" command)
• \ContentsForKeyword -- will print the table of contents for one particular keyword. For example, \ContentsForKeyword{design}. This command automatically creates the section header.
• \AllContentsTables print all of the tables of contents. The order that the different tables are printed in is the same as they were defined. This command creates an \appendix and looks after all of the headers.

Internally, what the code does is create various LaTeX3 sequences to store the keywords and the corresponding table of contents lists. The keywords are searched for using the regex macros in LaTeX3. As in the OP, the table of contents must appear after all of the rules. If they need to appear, potentially, before the rules are specified then a different approach will be needed where the data is written to one or more files. This is easy enough to do but the way that the question is phrased the approach that I have taken seems natural.

I am really impressed at how easy it was to do this using LaTeX3, so I guess that I may have stop saying that the syntax in LaTeX3 is awful as this code shows how powerful it really is:)

For the MWE in the OP the code produces the following "tables of contents":

The OP does not say what format these should take so I have given just the rule number and the page number (which is 1 for all of the rules in the MWE but I checked that this does work properly when the page numbers change). I have added hyperref and made the page numbers hyperlinks.

The keywords are searched for in #3 (keywords?) and #4 (description?) of the arguments for \Rule, and they are added to the table of contents if they appear at the start of a word. So design will give a match for design, designs, designed but not for indesign. [Btw, the \label{...} from the OP inside \Rule does not do very much because at that point there is nothing to label, except the page number. I am not sure how this label will be used but it might be better to put \def\@currentlabel{#2} before \label{#2}, which would require sandwiching the macro definition between \makeatletter...\makeatother.]

Here is the full code:

\documentclass{article}

\usepackage{mdframed}
\usepackage{xparse}
\usepackage{hyperref}

\ExplSyntaxOn

\seq_new:N \contents_keywords_seq% a sequence of the keywords to track

% Usage: \DefineContentKeywords{ keyword } define a new keyword to be tracked
\NewDocumentCommand\DefineContentKeywords{ m }{
\seq_set_from_clist:Nn \contents_keywords_seq {#1}
\seq_map_inline:Nn \contents_keywords_seq {
\seq_new:c {contents_for_##1}  % create sequence for each keyword
}
}

\seq_map_inline:Nn \contents_keywords_seq {
\regex_match:nnT { \b##1 }{#2}{ \seq_put_right:cx {contents_for_##1}{#1}}
}
}

\cs_generate_variant:Nn  \int_compare:nNnT { xNNT }

% Usage: \ContentsForKeyword{keyword}
\NewDocumentCommand\ContentsForKeyword{ m }{
\subsection*{Rules~related~to~#1}
\int_compare:xNNT {\seq_count:c {contents_for_#1}} > 0{
\begin{enumerate}
\seq_map_inline:cn {contents_for_#1}{\item[] ##1\dotfill\pageref{##1}}
\end{enumerate}
}
}
\NewDocumentCommand\AllContentsTables{}{
\appendix
\section{Allocation~of~rules~to~work~products}
\seq_map_inline:Nn \contents_keywords_seq {\ContentsForKeyword{##1}}
}

\ExplSyntaxOff
\definecolor{MISRARuleBackgroundColor}{rgb}{0.86,0.88,0.94}
\definecolor{RuleBackgroundColor}{rgb}{0.86,0.94,0.88}
\definecolor{RuleBorderColor}{rgb}{0.29,0.39,0.68}

% define keywords to track
\DefineContentKeywords{design,
implementation,
toolchain
}

% \Rule[background colour]{number}{keywords}{description}
\newcommand{\Rule}[4][]{%
\AddContentsLine{#2}{#3 #4}% search "#3 #4" for keywords
\bigskip%
\begin{mdframed}[backgroundcolor=#1RuleBackgroundColor,
linecolor=RuleBorderColor,
linewidth=1pt]
\textbf{Rule #2 (#3)} \newline \textbf{#4} \label{#2}
\end{mdframed}\nopagebreak%
}

\newcommand{\MISRARule}[3]{%
\Rule[MISRA]{#1}{#2}{#3}%
See MISRA C++ 2008 \cite{MISRAC++2008}%
}

\begin{document}

\Rule{A0-4-1}{required, toolchain, non-automated}{Floating-point implementation shall comply with IEEE 754 standard.}

\Rule{A0-4-3}{required, toolchain, automated}{The implementations in the chosen compiler shall strictly comply with the C++14 Language Standard.}

\MISRARule{M1-0-2}{required, implementation, non-automated}{Multiple compilers shall only be used if they have a common, defined interface.}

\MISRARule{M15-0-3}{required, implementation, automated}{Control shall not be transferred into a try or catch block using a goto or a switch statement.}

\Rule{A15-0-2}{required, implementation, partially automated}{At least the basic guarantee for exception safety shall be provided for all operations. In addition, each function may offer either the strong guarantee or the nothrow guarantee}

...

\newpage
\AllContentsTables

\end{document}


I also rationalised (and fixed the use of background colours in) the code so that \MISRARule now invokes \Rule. I have used \sections and \subsections rather than \chapters and \sections to shorten the output.

• Hi Andrew, thanks a lot, this is what I needed. However, I have a problem that it does not compile in my environment. I think there is a missing } in "\seq_map_inline:cn {contents_for_#1}{\item[] ##1\dotfill\pageref{#1}" at the end. I added it but I get then the errors "undefined control sequence" in each line where Rule or MISRARule is used. – user3275925 Nov 29 '17 at 13:38
• @user3275925 Sorry, I changed the name of something and introduced some typos. I have just fixed the code. (Btw, the TeX.SX way of thanking is up-voting and/or awarding green ticks.) – user30471 Nov 29 '17 at 13:57
• I still have a problem - it builds if i comment the regex_match line: % Usage: \AddContentsLine{number}{description} \NewDocumentCommand\AddContentsLine{ mm }{ \seq_map_inline:Nn \contents_keywords_seq { %\regex_match:nnT { \b##1 }{#2}{ \seq_put_right:cx {contents_for_##1}{#1}} } }. Then the file builds without errors but of course the table rule is not added and the reference table is empty. I maybe there is another bug in this line? – user3275925 Nov 29 '17 at 14:16
• @user3275925 The code is working for me? I just pasted my working code back into the question. Can you please check it again? In the event that it doesn't work please post your error message. – user30471 Nov 29 '17 at 15:08
• I get the error message ! Undefined control sequence. __seq_item:n #1->\regex_match:nnT {\b #1}{required, toolchain, non-automate... l.72 ...tion shall comply with IEEE 754 standard.}. this message appears on each \Rule and \MISRARule. – user3275925 Nov 29 '17 at 15:34