Consider this MWE:


\newenvironment{dayreport}{\begin{tabular}{ll}\hline Task & Time\\\hline}{\hline\end{tabular}}
\newcommand{\task}[2]{#1 & #2\\}

\task{a}{1 hr\hphantom{s}}
\task{b}{2 hrs}
\task{c}{1 hr 30 mins}

The output looks like this:


I would like to automate some tasks like inputing time and calculating total times. Time inputing examples:

  • \task{a}{1} would produce a & 1 hr\hphantom{s}
  • \task{a}{1:30} would produce a & 1 hr 30 mins
  • \task{a}{2} would produce a & 2 hrs

Total time calculation:


would produce Total time: & 4 hrs 30 mins \\ when ending dayreport.

Is something like that possible in LaTeX (I would probably need string splitting, simple arithmetic and if-then-else constructs)? Should I rather write a short program to parse the input and output the appropriate LaTeX code?

    % no minutes
    #1 hr\ifnum#1=\@ne\hphantom{s}\else s\fi
    #1 hr\ifnum#1=\@ne\else s\fi
    \ #2 mins




The problem is to parse the result. After \task{1} the token list is

\@task 1::\@nil

so that #1 is 1, while #2 and #3 are empty (the arguments to \@task are delimited by semicolons and by \@nil). After \task{1:30} we get

\@task 1:30::\@nil

so #1 is 1, #2 is 30 and #3 is :. The rest is just following the conditional: \if\relax\detokenize{#2}\relax is true when #2 is empty. It's just a matter to add some \def in the branches of the conditional if one wants to store the time for calculations.

| improve this answer | |

Putting together the advice given by egreg on questions Converting command to result, Storing environment arguments, What are the exact semantics of \detokenize? as well as this one, I managed to create what I wanted.

For the sake of completeness, I am providing the code. There are still some rough edges: task{0:15} will print 0 hrs 15 mins, the tables don't take up the whole \textwidth, etc. As a proof of concept, I am very satisfied.



\begin{dayreport}{June 13, 2011}
\task{First task}{3}
\task{Second task}{1:12}
\task{Third task}{3:15}

\begin{dayreport}{June 14, 2011}
\task{Fourth task}{1:15}
\task{Fifth task}{2}
\task{Sixth task}{1}




Task report


% workreport.cls

% infix arithmetic

% setting section titles

% nicer looking table rules

% counters for time calculation

% required for xappto command

\section*{Total Work Hours}
Day     &   Work hours \\
\emph{Total work hours:} & \displaytime{\thehours:\theminutes}\\

% prints time and advances time counters, format is \tasktime{hh:mm}
    % add hours time to counter
    % if there are no minutes, detokenize is empty so \relax=\relax
    % output hour/hours 
        #1 hr\ifnum#1=\@ne\hphantom{s}\else s\fi
        % check if minutes are greater than 0
            % add minutes to counter and output time
            #1 hr%
                % '\' is for spacing
                \else s\fi \ #2 mins
        % if the minutes are not greater than 0
            #1 hr\ifnum#1=\@ne\hphantom{s}\else s\fi

% prints time but does not advance the time counters
        #1 hr\ifnum#1=\@ne\hphantom{s}\else s\fi
            #1 hr%
                \else s\fi \ #2 mins
            #1 hr\ifnum#1=\@ne\hphantom{s}\else s\fi

\newcommand{\task}[2]{#1 & \tasktime{#2}\\}

    \appto\totaltimerows{#1 & }
    Task                    &   Approximate time \\
    \emph{Total time:}  &   \displaytime{\thehours:\theminutes}\\
| improve this answer | |
  • That is a very helpful piece of code. – brannerchinese Dec 26 '12 at 23:05

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.