1

I'm trying to do a command that allow the user to create a specific table for a document but that the person can decide on the fly on the name of the tables (so he can dynamically create multiple tables).

\newcommand{\WIT}[2]{
    \eAddQuoteTableTokens{#1}
    \ifcsname c@#1\endcsname
        \relax
    \else
        \newcounter{#1}

        \expandafter\providecommand*{\csname #1QuoteTkTable\endcsname}{}%
        \expandafter\newtoks\csname @#1Quotetabtoks\endcsname%
        \expandafter\providecommand\csname Add#1QuoteTableToken\endcsname[1]{
            \expandafter\global\csname @#1Quotetabtoks\endcsname\expandafter{
                \expandafter\the\csname @#1Quotetabtoks##1\endcsname%
            }
        }

        \expandafter\providecommand\csname eAdd#1QuoteTableTokens\endcsname[1]{%
            \protected@edef\csname #1QuoteTkTable\endcsname{##1}%
            \expandafter\expandafter\csname Add#1QuoteTableToken\endcsname\expandafter{\csname #1QuoteTkTable\endcsname}%

            \expandafter\providecommand*{\csname #1Table\endcsname}{
                \begin{flushleft}
                    \textbf{#1:} \\
                    Total #1: \arabic{#1}h \\
                \end{flushleft}
                \begin{table}[h]
                    \begin{tabularx}{\textwidth}{llXr}
                        \expandafter\the\csname @#1Quotetabtoks\endcsname
                    \end{tabularx}
                \end{table}
            }
        }
    \fi

    \expandafter\providecommand\csname #1\endcsname[2]{
        \csname eAdd#1QuoteTableTokens\endcsname{##1 \hfill ##2}%
        \addtocounter{#1}{##2}%         
    }
}

So after that, if the user type

\WIT{Analysis}
\WIT{Development}
\WIT{Management}

he should be able to use the followings command

\Analysis{Analysis Activity 1}{30}
\Analysis{Analysis Activity 2}{40}
\Development{Development Activity 1}{150}
\Development{Development Activity 1}{340}
\Management{Management Activity 1}{20}
\Management{Management Activity 2}{35}

and finally, where he want's to put his tables he only have to use

\ManagementTable
\AnalysisTable
\DevelopmentTable

By design, the order of how he uses the \Analysis, \Development, and \Management should not have any impact on the final result of the table. Only the order in which he types them will have an impact on the print order.

My problem is that I got errors around the @edef that I'm not able to get a solution (and I'm pretty sure that I will get other errors after that which I don't know just because I'm stuck there)

Thanks in advance

1 Answer 1

2

There are several problems with your code, the most notable being:

  • If you reference macro arguments of a command that is getting defined in a macro, you have to double #. E.g., #1 refers to the first argument of the current definition, ##1 can be used to refer to the arguments of a macro defined within another macro.

  • You have to make sure that things get expanded in the right order. Something like \providecommand*{ constitutes three tokens, so if you prefix it by \expandafter, the star will be expanded first (without much effect).

enter image description here

\documentclass{article}

\makeatletter
\newcommand{\WIT}[1]%
  {\newcounter{#1}%
   \expandafter\def\csname#1Contents\endcsname{}%
   \expandafter\def\csname#1\endcsname##1##2
     {\addtocounter{#1}{##2}%
      \expandafter\g@addto@macro\csname#1Contents\endcsname{\\##1&##2}%
     }%
   \expandafter\def\csname#1Table\endcsname{\WITtable{#1}{\csname#1Contents\endcsname}}%
  }
\makeatother
\newcommand\WITtable[2]%
  {\begin{flushleft}
   \textbf{#1:} \\
   Total #1: \arabic{#1}h \\
   \end{flushleft}
   \begin{tabular}{@{}p{5cm}r@{}}
   Activity & Hours
   #2
   \end{tabular}
  }

\begin{document}
\WIT{Analysis}
\WIT{Development}
\WIT{Management}
\Analysis{Analysis Activity 1}{30}
\Analysis{Analysis Activity 2}{40}
\Development{Development Activity 1}{150}
\Development{Development Activity 1}{340}
\Management{Management Activity 1}{20}
\Management{Management Activity 2}{35}
\ManagementTable
\AnalysisTable
\DevelopmentTable
\end{document}

Edit: To generate all tables with a single command \SummaryTable, as requested in the comments, add the two lines indicated:

\newcommand\SummaryTable{}% <<<<<<<<<<<<<<<<<<
\makeatletter
\newcommand{\WIT}[1]%
  {\newcounter{#1}%
   ...
   \expandafter\def\csname#1Table\endcsname{\WITtable{#1}{\csname#1Contents\endcsname}}%
   \g@addto@macro\SummaryTable{\csname#1Table\endcsname}% <<<<<<<<<<<<<<<<<<
  }
\makeatother
2
  • Using that technique, could it be possible to also define a command like \SummaryTable that will do the \ManagementTable \AnalysisTable \DevlopmentTable without having to add them manually in the \SummaryTable command? Mar 23, 2017 at 17:19
  • @MirainoHikari See the edit of my answer.
    – gernot
    Mar 23, 2017 at 17:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .