3

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?

1
  • 1
    Oh, on your question about \ifstrempty: It works on a "string", so it doesn't expect the argument to be a control sequence and returns true because the argument is not empty (yet). Better use \ifdefempty in this case. Oct 16, 2019 at 20:42

1 Answer 1

4

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}
3
  • Is it possible to store more than one impact and countermeasure on the same label? Oct 18, 2019 at 0:40
  • @leonardocesar It certainly is :-) But the code will depend on how you want the interface. For instance, when calling \impact{Water}, should all the impacts be printed, or should the command be changed to \impact[1]{Water} then \impact[2]{Water}... I'd suggest you ask a new question with the syntax you want to have and link to this one for reference. Oct 18, 2019 at 1:54
  • ok. i've posted the question in tex.stackexchange.com/questions/513101/… Oct 21, 2019 at 16:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.