[Tex/LaTex] How to generate summary table automatically

etoolboxmacrostables

I have to generate a summary of impacts and actions in many enviromental reports. Sometimes there are two or more impacts in the analyses, so I have to create the lines manually in the table. Is there a smarter way to create this table, without define a lot of newcommands?

\documentclass{article}
\usepackage{etoolbox}
\usepackage{nameref}

\begin{document}


\section{Impacts on the Environment}

\subsection{Air quality}
\label{sec:air}

Analysis of air quality.

%conclusion
\newcommand{\ImpactAir}{Wood burning}

\newcommand{\CountermeasureAir}{Sleeve filter installation}


\textbf{Impact}: \ifstrempty{\ImpactAir}{Not applicable.}{\ImpactAir}   

\textbf{Countermeasure}: \ifstrempty{\CountermeasureAir}{Not applicable.}{\CountermeasureAir}

\subsection{Water resources}
\label{sec:water}

Analysis of water resources.

%conclusion

\newcommand{\ImpactWater}{}

\newcommand{\CountermeasureWater}{}

\textbf{Impact}: \ifstrempty{\ImpactWater}{Not applicable.}{\ImpactWater} 

\textbf{Countermeasure}: \ifstrempty{\CountermeasureWater}{Not applicable.}{\CountermeasureWater}


\subsection{Noise level}
\label{sec:noise}

Analysis of noise level.

%conclusion

\newcommand{\ImpactNoise}{High noise level}

\newcommand{\CountermeasureNoise}{Acoustic engine insulation}


\textbf{Impact}: \ifstrempty{\ImpactNoise}{Not applicable.}{\ImpactNoise} 

\textbf{Countermeasure}: \ifstrempty{\CountermeasureNoise}{Not applicable.}{\CountermeasureNoise}\\


\section{Conclusion}

A succinct conclusion. See Table \ref{tab:sumary}.

\begin{table}[htb!]
\centering
\caption{Summary of impacts and countermeasures}
\label{tab:sumary}
\begin{tabular}{lll}
\hline
\textbf{Analyse} & \textbf{Impact} & \textbf{Countermeasure}\\
\hline
\nameref{sec:air}   & \ifstrempty{\ImpactAir}{-}{\ImpactAir}     & \ifstrempty{\CountermeasureAir}{-}{\CountermeasureAir}\\
\nameref{sec:water} & \ifstrempty{\ImpactWater}{-}{\ImpactWater} & \ifstrempty{\CountermeasureWater}{-}{\CountermeasureWater} \\
\nameref{sec:noise} & \ifstrempty{\ImpactNoise}{-}{\ImpactNoise} & \ifstrempty{\CountermeasureNoise}{-}{\CountermeasureNoise}\\
\hline
\end{tabular}
\end{table}

\end{document}

enter image description here

A little detail, the command \ifstrempty doesn't work like expected. How to expand it?

Best Answer

You can use expl3's property lists to store the data for you, and then loop through the items in the property list to lay the table out.

I defined a command \DeclareImpact{<label>}{<impact>}{<countermeasure>}, which replaces your \newcommand{\Impact<label>}{<impact>} and \newcommand{\Countermeasure<label>}{<countermeasure>}.

After a <label> is defined with that you can use \impact{<label>} and \countermeasure{<label>} to retrieve the stored texts. If the <label> was never defined, then a fallback text (default Not applicable) is returned.

I also defined a \TableBody{<list-of-labels>} command which takes a <list-of-labels> and typesets the table body based on a template given to \SetRowFormat (the argument of \SetRowFormat is used once for each <label> in the <list-of-labels>).

enter image description here

\documentclass{article}
\usepackage{nameref}
\usepackage{booktabs}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g__leonardo_impact_prop
\prop_new:N \g__leonardo_counter_prop
\makeatletter
\NewDocumentCommand \DeclareImpact { m +m +m }
  {
    \@bsphack
      \prop_gput:Nnn \g__leonardo_impact_prop {#1} {#2}
      \prop_gput:Nnn \g__leonardo_counter_prop {#1} {#3}
    \@esphack
  }
\makeatother
\NewExpandableDocumentCommand \impact { O{Not~applicable} m }
  {
    \prop_if_in:NnTF \g__leonardo_impact_prop {#2}
      { \prop_item:Nn \g__leonardo_impact_prop {#2} }
      { \exp_not:n {#1} }
  }
\NewExpandableDocumentCommand \countermeasure { O{Not~applicable} m }
  {
    \prop_if_in:NnTF \g__leonardo_counter_prop {#2}
      { \prop_item:Nn \g__leonardo_counter_prop {#2} }
      { \exp_not:n {#1} }
  }
%
\NewExpandableDocumentCommand \TableBody { m }
  { \clist_map_function:nN {#1} \__leonardo_table_row:n }
\NewDocumentCommand \SetRowFormat { m }
  { \cs_gset:Npn \__leonardo_table_row:n ##1 {#1} }
\cs_new_eq:NN \StrLowerCase \str_lowercase:n
\ExplSyntaxOff

\begin{document}

\section{Impacts on the Environment}
\subsection{Air quality}
\label{sec:air}
Analises of air quality.
\DeclareImpact{Air}{Wood burning}{Sleeve filter installation}

\textbf{Impact}: \impact{Air}

\textbf{Countermeasure}: \countermeasure{Air}

\subsection{Water resources}
\label{sec:water}
Analises of water resources.

\textbf{Impact}: \impact{Water}

\textbf{Countermeasure}: \countermeasure{Water}

\subsection{Noise level}
\label{sec:noise}
Analises of noise level.
\DeclareImpact{Noise}{High noise level}{Acoustic engine insulation}

\textbf{Impact}: \impact{Noise}

\textbf{Countermeasure}: \countermeasure{Noise}

\section{Conclusion}
A succinct conclusion. See Table \ref{tab:sumary}.

% Set table row format:
\SetRowFormat
  {%
    \nameref{sec:\StrLowerCase{#1}}
  & \impact[--]{#1}
  & \countermeasure[--]{#1} \\
  }

\begin{table}[htb!]
  \centering
  \caption{Summary of impacts and countermeasures}
  \label{tab:sumary}
  \begin{tabular}{lll}
    \toprule
      \textbf{Analyse} & \textbf{Impact} & \textbf{Countermeasure}\\
    \midrule
      \TableBody{Air,Water,Noise}
    \bottomrule
  \end{tabular}
\end{table}

\end{document}
Related Question