# Generating a table with all entries from all over the document

We're working on a technical document where we define messages in different chapter/section all over the document. All messages have the same structure and are displayed in a table. We thought that it would be nice to have a list with all these messages at the end of the document.

So I started working on a solution, that all table entries get stored in a separate file, which will be included at the end of the document.

This is my working solution:

\documentclass{article}
\RequirePackage{fontspec}
\usepackage{longtable, colortbl,environ}

\NewEnviron{tbl}
{%
\begin{longtable}{|p{2cm}|p{2cm}|p{2cm}|p{2cm}|}%
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4\\\hline%
\BODY%
\end{longtable}%
}

\newwrite\mytabularwrite
\newcommand{\writetotablefile}[1]{\immediate\write\mytabularwrite{\unexpanded{#1}}}

\newcommand{\myrow}[4]{\writetotablefile{\unexpanded{#1&#2&#3&#4\\\hline}}%
#1&#2&#3&#4\\\hline%
}

\AtBeginDocument{\immediate\openout\mytabularwrite=\jobname-table.tex}
\AtEndDocument{}

\begin{document}

\section{Table 1}
\begin{tbl}
\myrow{1äöü€}{2}{3}{4}
\end{tbl}

\section{Table 2}
\begin{tbl}
\myrow{5}{6}{7}{8}
\end{tbl}

\section{Complete Table}

\begin{tbl}
% ATTENTION: Starting with that point here: don't use \myrow anymore! Temp. file is already closed.
\immediate\closeout\mytabularwrite
\input{\jobname-table}
\end{tbl}

\end{document}


The problem, I had to solve, was that (La)TeX cannot write text in append mode to a file. I found workarounds like: reading the tempfile, add my new data, store tempfile, repeat... But I think that is not efficient.

I now open the tempfile with the begin of the document and close it before including the tempfile for the final table.

Ok, I have a working solution, where's the problem? There currently is no problem. But I would like to ask, if there is a better way solving that problem.

• A list of ... would be easier, I think! – user31729 Jul 2 '16 at 11:34
• I already thought about that. Is there a way to generate a list of with a structured information like the message, that consists of 4 parts? – aronadaal Jul 2 '16 at 11:37
• if your list is at the end rather than the beginning then you don't necessarily need a file at all you could just save it in a macro, depends on memory constraints but that is not usually too much of a problem these days. – David Carlisle Jul 2 '16 at 11:39
• Yes, I've done this – user31729 Jul 2 '16 at 11:39
• @aronadaal: see for example my answer here: tex.stackexchange.com/questions/263979/… – user31729 Jul 2 '16 at 11:45

Using a ToC - like approach has the advantage that the file can be included at any time in the document, but only once.

As usual with ToC and longtable: Compile more than once!

\documentclass{article}
\RequirePackage{fontspec}

\usepackage{tocloft}
\usepackage{longtable, colortbl,environ}

\makeatletter

\def\@starttof#1#2{%
\begingroup
\makeatletter
\renewcommand{\arraystretch}{1.5}
% Table format may be changed%%%
\begin{longtable}{|*{4}{p{2cm}|}}
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4\\\hline%

\@input{\jobname.#1}%
\end{longtable}
\if@filesw
\expandafter\newwrite\csname tf@#1\endcsname
\immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
\fi
\endgroup
}

\newcommand{\listofstuff}{%
\@starttof{stuff}{}%
}

\NewEnviron{tbl}
{%
\begin{longtable}{|*{4}{p{2cm}|}}
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4\\\hline%
\BODY%
\end{longtable}%
}

\DeclareRobustCommand{\tablerow}[4]{%
#1&#2&#3&#4 \\
\hline
}

\newcommand{\myrow}[4]{%
#1&#2&#3&#4\\\hline%
}

\begin{document}
\section{Table 1}
\begin{tbl}
\myrow{1äöü€}{2}{3}{4}
\end{tbl}

\section{Table 2}
\begin{tbl}
\myrow{5}{6}{7}{8}
\end{tbl}

\section{Complete Table}

\listofstuff

\end{document}


Improved version

\documentclass{article}
\RequirePackage{fontspec}

\usepackage{xparse}
\usepackage{longtable}
\usepackage{colortbl}
\usepackage{environ}

\newcommand{\foo}{Some stuff}
\newcommand{\foobar}{Other stuff}

\makeatletter

\NewDocumentCommand{\@starttof}{smO{}}{%
\begingroup
\makeatletter
\renewcommand{\arraystretch}{1.5}
\IfBooleanTF{#1}{%
\section*{#3}%
}{%
\section{#3}%
}%
%  Table format may be changed%%%
\begin{longtable}{|*{4}{p{2cm}|}}
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4\\
\hline%
\@input{\jobname.#2}%
\end{longtable}
\if@filesw
\expandafter\newwrite\csname tf@#2\endcsname
\immediate\openout \csname tf@#2\endcsname \jobname.#2\relax
\fi
\endgroup
}

\NewDocumentCommand{\listofstuff}{sO{Complete Table}}{%
\IfBooleanTF{#1}{%
\@starttof*{stuff}[#2]%
}{%
\@starttof{stuff}[#2]%
}%
}

\NewEnviron{tbl}
{%
\begin{longtable}{|*{4}{p{2cm}|}}
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4\\\hline%
\BODY%
\end{longtable}%
}

\DeclareRobustCommand{\tablerow}[4]{%
#1&#2&#3&#4 \\
\hline
}

\newcommand{\myrow}[4]{%
#1&#2&#3&#4\\
\hline%
}

\begin{document}

\listofstuff*

\section{Table 1}
\begin{tbl}
\myrow{1äöü€}{2}{3}{4}
\end{tbl}

\section{Table 2}
\begin{tbl}
\myrow{5}{6}{7}{8}
\end{tbl}

\begin{tbl}
\myrow{\foo}{6}{\foobar}{8}
\end{tbl}

\end{document}


Update with page numbers

\documentclass{article}
\RequirePackage{fontspec}

\usepackage{xparse}
\usepackage{longtable}
\usepackage{colortbl}
\usepackage{environ}

\newcommand{\foo}{Some stuff}
\newcommand{\foobar}{Other stuff}

\makeatletter

\NewDocumentCommand{\@starttof}{smO{}}{%
\begingroup
\makeatletter
\renewcommand{\arraystretch}{1.5}
\IfBooleanTF{#1}{%
\section*{#3}%
}{%
\section{#3}%
}%
%  Table format may be changed%%%
\begin{longtable}{|*{5}{p{2cm}|}}
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4 & Page\\
\hline%
\@input{\jobname.#2}%
\end{longtable}
\if@filesw
\expandafter\newwrite\csname tf@#2\endcsname
\immediate\openout \csname tf@#2\endcsname \jobname.#2\relax
\fi
\endgroup
}

\NewDocumentCommand{\listofstuff}{sO{Complete Table}}{%
\IfBooleanTF{#1}{%
\@starttof*{stuff}[#2]%
}{%
\@starttof{stuff}[#2]%
}%
}

\NewEnviron{tbl}
{%
\begin{longtable}{|*{4}{p{2cm}|}}
\hline\rowcolor[gray]{.8}%
Column 1 & Column 2 & Column 3 & Column 4\\\hline%
\BODY%
\end{longtable}%
}

\DeclareRobustCommand{\tablerow}[5]{%
#1&#2&#3&#4&#5\\
\hline
}

\newcommand{\myrow}[4]{%
#1&#2&#3&#4\\
\hline%
}

\begin{document}

\listofstuff*

\clearpage

\section{Table 1}
\begin{tbl}
\myrow{1äöü€}{2}{3}{4}
\end{tbl}

\clearpage

\section{Table 2}
\begin{tbl}
\myrow{5}{6}{7}{8}
\end{tbl}

\begin{tbl}
\myrow{\foo}{6}{\foobar}{8}
\end{tbl}

\end{document}


• it seems so easy ;) Thank you. What do I have to do, if I want to put the page number in the tof as column 5? – aronadaal Jul 2 '16 at 11:59
• @aronadaal: That's almost the same, just use another parameter for the page number -- this will be expanded at the time of using \addtocontents which is correct then, but do not use \thepage inside of \tablerow, since that command isn't expandable! See the 2nd update at the end! – user31729 Jul 2 '16 at 12:19
• Could you please extend your example with the usage of hyperref? I had a look at the question you linked, but there is too much tex code that I don't understand. – aronadaal Jul 4 '16 at 13:42
• @aronadaal: Well, that's adding one feature after another one -- that's not how TeX.SX works – user31729 Jul 4 '16 at 15:15
• sure, but I thought that would be better than asking a new question with almost the same content. Anyway, I'm happy with the current solution. Thanks for your help. – aronadaal Jul 4 '16 at 15:54