generating LaTeX tabular code during compilation
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}
\def\listheadings{%
\expandafter\xlistheadings\regionlist,\relax,}
\def\xlistheadings#1,{%
\ifx\relax#1%
\expandafter\\%
\else
&\textbf{#1}%
\expandafter\xlistheadings
\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
\listheadings
\hline
\listbody
\hline
\end{tabular}
\end{document}
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}}
\seq_new:N \l_nrz_head_seq
\tl_new:N \l_nrz_preamble_tl
\tl_new:N \l_nrz_header_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_header_tl
\tl_clear:N \l_nrz_body_tl
\seq_map_inline:Nn \l_nrz_head_seq
{
\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
\seq_map_inline:Nn \l_nrz_head_seq % other cols
{
\tl_put_right:Nn \l_nrz_body_tl { & \use:c { origREGION ##1 destREGION ####1 } }
}
\tl_put_right:Nn \l_nrz_body_tl { \\ }
}
\tl_put_right:Nn \l_nrz_header_tl { \\ }
}
\cs_new_protected:Npn \nrz_output_table:
{
\begin{tabular}{ \tl_use:N \l_nrz_preamble_tl }
\hline
\tl_use:N \l_nrz_header_tl
\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.