# generating LaTeX tabular code during compilation

I use LaTeX for scientific reporting in brain imaging (fMRI). I have a tabular array in LaTeX, that contains quite a lot of rows and columns, which both are brain regions and in the each intersecting cell there is some data about their connections.


So, the \newcommand definitions look like this:

\newcommand{\origREGIONONEdestREGIONONE}{ NA } % NA for cells on the diagonal.
\newcommand{\origREGIONONEdestREGIONTWO}{ - } % this is the default case.


...

\newcommand{\origREGINOTWOdestREGIONTWO}{ NA }
\newcommand{\origREGIONTWOdestREGIONONE}{ \ref{Spielberg1981} }
\newcommand{\origREGIONTWOdestREGIONTHREE}{ bilateral \ref{Cameron1989} }


...

There is a specific \newcommand definition for all column x row intersections.

The tabular array code looks like this (a 3x3 example but in reality it is bigger than 20x20):

\tiny
\begin{table}
\scalebox{0.6}{
\hline
\to/from :={} & REGIONONE :={} & REGIONTWO :={} & REGIONTHREE :={} \\
\hline
to REGIONONE :={} & \origREGIONONEdestREGIONONE :={} & \origREGIONTWOdestREGIONONE :={} &\origREGIONTHREEdestREGIONONE :={} \\
to REGIONTWO :={} & \origREGIONONEdestREGIONTWO :={} & \origREGIONTWOdestREGIONTWO :={} &\origREGIONTHREEdestREGIONTWO :={} \\
to REGIONTHREE :={} & \origREGIONONEdestREGIONTHREE :={} & \origREGIONTWOdestREGIONTHREE :={} &\origREGIONTHREEdestREGIONTHREE :={} \\
\hline
} % end scalebox
\caption{A table of connections between brain regions 1, 2 & 3}
\begin{enumerate}
\item \cite{Spielberg1981}\label{Spielberg1981}
\item \cite{Cameron1989}\label{Cameron1989}
\end{enumerate}
\end{table}
\normalsize


Now what I want is to be able to generate a similar tabular definition dynamically according to a list or an array of strings (or using any possible datatype):

in MATLAB syntax it would be: ListOfBrainRegions = { 'BRAINREGIONABC', 'BRAINREGIONDEF', 'BRAINREGIONXYZ' }

In Python syntax: ListOfBrainRegions = [ 'BRAINREGIONABC', 'BRAINREGIONDEF', 'BRAINREGIONXYZ' ]

The list or array would be translated into a code like this inside spreadtab (or without spreadtab if it causes some problems):

            \hline
\to/from :={} & REGIONABC :={} & REGIONDEF :={} & REGIONXYZ :={} \\
\hline
to REGIONABC :={} & \origREGIONABCdestREGIONABC :={} & \origREGIONDEFdestREGIONABC :={} &\origREGIONXYZdestREGIONABC :={} \\
to REGIONDEF :={} & \origREGIONABCdestREGIONDEF :={} & \origREGIONDEFdestREGIONDEF :={} &\origREGIONXYZdestREGIONDEF :={} \\
to REGIONXYZ :={} & \origREGIONABCdestREGIONXYZ :={} & \origREGIONDEFdestREGIONXYZ :={} &\origREGIONXYZdestREGIONXYZ :={} \\
\hline


So, how should I define ListOfBrainRegions in LaTeX? And then how can I generate LaTeX code during compiling of a .tex file? If I was to program this in some other programming language, for example in MATLAB, Common Lisp or awk the task (generating program code) would not be difficult at all. It seems that LaTeX does not have built-in arrays, if ... elseif ... else commands nor for or while loops, although some packages provide some added functionality. So, how this could be implemented? Or, which LaTeX commands, packages and/or extra tools should I use for this task?

Thank you for any help :)

-
If you feel that TeX lacks a real programming language or programming using the TeX constructs feels fussy, you might be interested in LuaTeX. –  Marco Apr 19 '12 at 0:04
@Marco LuaTeX might be an interesting option. But is there a way for a generic transformation (a regular expression or something) to convert any LaTeX file into a valid LuaTeX file? What I find most difficult in LaTeX, in addition to the lack of common programming constructs, is getting the packages work together (I currently have 19). –  nrz Apr 19 '12 at 21:08
There is not much to convert, LuaTeX is only the backend engine. Since LuaTeX is -more or less- a superset of pdfTeX, you can keep your existing files and packages. The most noticeable difference is the font handling and the encoding; and, of course, the embedded scripting language. It's probably a few lines of change in the preamble to switch from pdfTeX to LuaTeX. However, it changes nothing regarding the package mess. –  Marco Apr 19 '12 at 21:23

Actually the LaTeX format does have loops \@tfor etc, but in tables TeX is in a bit of a delicate state so here I have just use plain expansion.

\documentclass{article}

\ifx\relax#1%
\expandafter\\
\else
&\textbf{#1}%
\fi}

\def\listbody{%
\expandafter\xlistbody\regionlist,\relax,}

\def\xlistbody#1,{%
\ifx\relax#1%
\else
\textbf{#1}%
\gdef\thisrow{#1}%
\expandafter\xlistdata\regionlist,\relax,%
\expandafter\xlistbody
\fi}

\def\xlistdata#1,{%
\ifx\relax#1%
\expandafter\\
\else
&\csname origREGION\thisrow destREGION#1\endcsname
\expandafter\xlistdata
\fi}

\def\preamble{\expandafter\xpreamble\regionlist,\relax,}
\def\xpreamble#1,{%
\ifx\relax#1%
\else
c|%
\expandafter\xpreamble
\fi}

\def\tablestart{%
\edef\temp{\noexpand\begin{tabular}{|c|\preamble}}%
\temp}

\begin{document}

\newcommand\regionlist{ONE,TWO,THREE}

\def\origREGIONONEdestREGIONONE{1/1}
\def\origREGIONONEdestREGIONTWO{1/2}
\def\origREGIONONEdestREGIONTHREE{1/3}

\def\origREGIONTWOdestREGIONONE{2/1}
\def\origREGIONTWOdestREGIONTWO{2/2}
\def\origREGIONTWOdestREGIONTHREE{2/3}

\def\origREGIONTHREEdestREGIONONE{3/1}
\def\origREGIONTHREEdestREGIONTWO{3/2}
\def\origREGIONTHREEdestREGIONTHREE{3/3}

\tablestart
\hline
\hline
\listbody
\hline
\end{tabular}

\end{document}

-
Thank you a lot, this is an excellent answer and helps me enormously. I have been searching and looking for a solution for months every now and then. –  nrz Apr 18 '12 at 22:30

Here's a solution with expl3 which shows some nice features of the language:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\generatetable}{m}{\nrz_generate_table:n {#1}}

\tl_new:N \l_nrz_preamble_tl
\tl_new:N \l_nrz_body_tl

\cs_new_protected:Npn \nrz_generate_table:n #1
{
\seq_set_split:Nnn \l_nrz_head_seq { , } { #1 }
\nrz_generate_table_data:
\nrz_output_table:
}

\cs_new_protected:Npn \nrz_generate_table_data:
{
\tl_set:Nn \l_nrz_preamble_tl { | c | }
\tl_clear:N \l_nrz_body_tl
{
\tl_put_right:Nn \l_nrz_preamble_tl { c | }
\tl_put_right:Nn \l_nrz_header_tl { & \textbf{ ##1 } }
\tl_put_right:Nn \l_nrz_body_tl { \textbf{ ##1 } } % first col
{
\tl_put_right:Nn \l_nrz_body_tl { & \use:c { origREGION ##1 destREGION ####1 } }
}
\tl_put_right:Nn \l_nrz_body_tl { \\ }
}
}
\cs_new_protected:Npn \nrz_output_table:
{
\begin{tabular}{ \tl_use:N \l_nrz_preamble_tl }
\hline
\hline
\tl_use:N \l_nrz_body_tl
\hline
\end{tabular}
}
\ExplSyntaxOff

\begin{document}

\def\origREGIONONEdestREGIONONE{1/1}
\def\origREGIONONEdestREGIONTWO{1/2}
\def\origREGIONONEdestREGIONTHREE{1/3}

\def\origREGIONTWOdestREGIONONE{2/1}
\def\origREGIONTWOdestREGIONTWO{2/2}
\def\origREGIONTWOdestREGIONTHREE{2/3}

\def\origREGIONTHREEdestREGIONONE{3/1}
\def\origREGIONTHREEdestREGIONTWO{3/2}
\def\origREGIONTHREEdestREGIONTHREE{3/3}

\generatetable{ONE,TWO,THREE}

\end{document}


The body of the table is built with a mapping function inside another mapping function, using the same sequence for the mapping!

First of all we build the sequence from the list passed as argument to \generatetable; then we proceed to use the sequence so obtained to build the table preamble (starting with |c| and adding c| at each step), the table header (adding & <string> at each step and a final \\) and the table body, one row at a time. Rows are built similarly, with an inner loop.

-