1

I have the following situation: I get a record like this

\row{day,dayShort,date}{come,go,break,breakGo}{hours,days}{project} 

from an external program. This program commits 30 or 40 records and I have to create a time sheet then in LaTex using longtable. I think, that THIS is not very useful, like one of the User said, but that's the way I get the data.

I have already found a way with csv, but it's not really a perfect way for us.

I also have tried something like this, but I cannot handwrite every single record, because I don't know how many records I'll get:

\documentclass[10pt,a4paper]{article}
\usepackage[ngerman]{babel} 
\usepackage{longtable}

\newcommand*{\FormDay}[1]{#1}
\newcommand*{\FormDayShort}[1]{#1}
\newcommand*{\FormDate}[1]{#1}
\newcommand*{\FormType}[1]{#1}
\newcommand*{\FormCome}[1]{#1}
\newcommand*{\FormGo}[1]{#1}
\newcommand*{\FormBreak}[1]{#1}
\newcommand*{\FormBreakGo}[1]{#1}
\newcommand*{\FormHours}[1]{#1}
\newcommand*{\FormDays}[1]{#1}
\newcommand*{\FormProject}[1]{#1}

\newenvironment{timesheet}
{\begin{longtable} 
{@{}p{0.075\textwidth}p{0.125\textwidth}p{0.075\textwidth}p{0.1\textwidth}p{0.1\textwidth}p{0.075\textwidth}p{0.075\textwidth}p{0.15\textwidth}}     
Day   & Date    & Type  & Come   & Go   & Hours   & Days    & Project   \tabularnewline[2ex]
 \FormDayShort{Di}      & \FormDate {01.09.2015}    & \FormType{U}      &
 \FormCome{08:00}       & \FormGo{17:00}            &
 %\FormBreak{12:00}     & \FormBreakGo{13:00}       &
 \FormHours{08,00}      & \FormDays{1}              & \FormProject{Airplane Hangar}                 \tabularnewline
\endhead
}
{
\hline 
\end{longtable}
}
\begin{document}

{\huge Timesheet} \hfill 

\begin{timesheet}

\end{timesheet}

\end{document}

So, if anyone have a solution in a completely different way for me, I would be deeply grateful.

Thanks in advance!

SamHoff
  • 89
  • 2
    I don't understand the question. Do you really have a \row{} command in the data file, or only the comma separated values? Anyway, I would use an external scripting language (python, ruby..) to read that csv and generate the latex table. You can even use Lua and integrate it with latex, via lualatex. – JLDiaz Oct 06 '15 at 07:43
  • @JLDiaz, you're right, i get the comma separated values, the \row{} was an example for that. Another scripting language is no solution for us and for the csv i have also a solution. But I'm searching for something WITHOUT csv data. I'd rather cut the values after the comma and put them into variables, like in the example, but I want to create automatically the needed number of rows in the longtable I also get from the external program, do you understand..?! – SamHoff Oct 06 '15 at 07:58
  • @JLDiaz: I have answered that other question linked by the O.P. If the \row command is really this bad, it's perhaps necessary to use this approach, unfortunately –  Oct 06 '15 at 07:59
  • @JLDiaz: If you have csv data take a look into datatools package –  Oct 06 '15 at 08:02

1 Answers1

2

Not sure if I correctly understood your question. I guess you want to type this in your document:

{\huge Timesheet} \hfill

\begin{timesheet}
\row{Dienstag,Di,01.09.2015}{08:00,17:00,12:00,13:00}{{08,00},1}{Airplane Hangar}
\row{Mittwoch,Mi,02.09.2015}{08:30,17:30,12:00,13:00}{{08,00},1}{Spaceship Hangar}
\row{Donnerstag,Do,03.09.2015}{08:30,17:00,12:00,13:00}{{07,50},1}{Autocar Hangar}
\row{Freitag,Fr,04.09.2015}{08:15,17:15,12:00,13:00}{{08,00},1}{Airplane Hangar}
\end{timesheet}

and get this:

enter image description here

Of course you can also have all the \rows in an external file, and then \input it in your main document like this:

\begin{timesheet}
\input{data}
\end{timesheet}

Is this the goal? If so, the following macros can get the job done.

First, one macro which extract a list of comma-separated values into a list of comma-separated macros. You can call it like this: \ExtractData{first,second}{\foo,\bar}, and you'll get \foo containing first and \bar containing second. It is kind of a hack using pgffor to parse the comma-separated list:

\def\ExtractData#1#2{% #1 List of values, #2 list of macros
\def\ccc{i}%
\foreach \data in {#1} {% We create auxilar macros called \auxi, \auxii, \auxiii...
  \expandafter\xdef\csname aux\ccc\endcsname{\data}%
  \xdef\ccc{\ccc i}% 
  }%
\xdef\ccc{i}%
\foreach \macro in {#2} {% And then store them into the provided macros
  \expandafter\xdef\macro{\csname aux\ccc\endcsname}%
  \xdef\ccc{\ccc i}%
  }%
}

Now, using above macro, \row is easy to define:

\def\row#1#2#3#4{%
\ExtractData{#1}{\formday,\formdayshort,\formdate}%
\ExtractData{#2}{\formcome,\formgo,\formbreak,\formbreakgo}%
\ExtractData{#3}{\formhours,\formdays}%
\ExtractData{#4}{\formproject}%
 \FormDayShort{\formdayshort} & \FormDate{\formdate}       & \FormType{U} &
 \FormCome{\formcome}         & \FormGo{\formgo}           &
%\formBreak{\formbreak}       & \FormBreakGo{\formbreakgo} &
 \FormHours{\formhours}       & \FormDays{\formdays}       & \FormProject{\formproject}
 \tabularnewline
}

As you can see, we first extract the data from the row parameters and store it into appropiately (lowercase) named macros. Then we use those macros to generate a row for the table, making use of your (camelcase) macros to format each entry. Not sure why you defined those, though, but I decided to leave them.

The complete code (which produces the table pasted at the beginning) is then:

\documentclass[10pt,a4paper]{article}
\usepackage[ngerman]{babel} 
\usepackage{longtable}
\usepackage{pgffor}

\def\ExtractData#1#2{% #1 List of values, #2 list of macros
\def\ccc{i}%
\foreach \data in {#1} {% We create auxilar macros called \auxi, \auxii, \auxiii...
  \expandafter\xdef\csname aux\ccc\endcsname{\data}%
  \xdef\ccc{\ccc i}% 
  }%
\xdef\ccc{i}%
\foreach \macro in {#2} {% And then store them into the provided macros
  \expandafter\xdef\macro{\csname aux\ccc\endcsname}%
  \xdef\ccc{\ccc i}%
  }%
}

\def\row#1#2#3#4{%
\ExtractData{#1}{\formday,\formdayshort,\formdate}%
\ExtractData{#2}{\formcome,\formgo,\formbreak,\formbreakgo}%
\ExtractData{#3}{\formhours,\formdays}%
\ExtractData{#4}{\formproject}%
 \FormDayShort{\formdayshort} & \FormDate{\formdate}       & \FormType{U} &
 \FormCome{\formcome}         & \FormGo{\formgo}           &
%\formBreak{\formbreak}       & \FormBreakGo{\formbreakgo} &
 \FormHours{\formhours}       & \FormDays{\formdays}       & \FormProject{\formproject}
 \tabularnewline
}

% Your original macros (I guess their purpose is to be able to change the formatting of the fields)
\newcommand*{\FormDay}[1]{#1}
\newcommand*{\FormDayShort}[1]{#1}
\newcommand*{\FormDate}[1]{#1}
\newcommand*{\FormType}[1]{#1}
\newcommand*{\FormCome}[1]{#1}
\newcommand*{\FormGo}[1]{#1}
\newcommand*{\FormBreak}[1]{#1}
\newcommand*{\FormBreakGo}[1]{#1}
\newcommand*{\FormHours}[1]{#1}
\newcommand*{\FormDays}[1]{#1}
\newcommand*{\FormProject}[1]{#1}

% Your original environment (whith the sample row deleted)
\newenvironment{timesheet}
{\begin{longtable} 
{@{}p{0.075\textwidth}p{0.125\textwidth}p{0.075\textwidth}p{0.1\textwidth}p{0.1\textwidth}p{0.075\textwidth}p{0.075\textwidth}p{0.25\textwidth}}     
Day   & Date    & Type  & Come   & Go   & Hours   & Days    & Project   \tabularnewline[2ex]
\endhead
}
{
\hline 
\end{longtable}
}

% Example of usage
\begin{document}
{\huge Timesheet} \hfill

\begin{timesheet}
\row{Dienstag,Di,01.09.2015}{08:00,17:00,12:00,13:00}{{08,00},1}{Airplane Hangar}
\row{Mittwoch,Mi,02.09.2015}{08:30,17:30,12:00,13:00}{{08,00},1}{Spaceship Hangar}
\row{Donnerstag,Do,03.09.2015}{08:30,17:00,12:00,13:00}{{07,50},1}{Autocar Hangar}
\row{Freitag,Fr,04.09.2015}{08:15,17:15,12:00,13:00}{{08,00},1}{Airplane Hangar}
\end{timesheet}
\end{document}

Remark

Note that your comma-separated list of values cannot use the comma inside a string. You had a 08,00 value for "hours", and I had to escape it by putting braces around it. The program which generates those rows should do this too, or avoid the use of the comma in the strings.

JLDiaz
  • 55,732
  • yay, that's it! Thank you very much! :) This is exactly what I want.

    Not sure why you defined those, though, but I decided to leave them.< I thought, this could be good approach.. ;-) Is there a way to do it shorter or easier?

    Note that your comma-separated list of values cannot use the comma inside a string.< I thought so and maybe we can change it from comma to dot, but with the escape it works for now.

    – SamHoff Oct 06 '15 at 09:40
  • What I meant with "Not sure why" is that you defined all those macros as simple "echoes" for their arguments, so I was not sure of their purpose. I guessed that eventually you'll use them to format differently each field (eg: date in italics, time in boldface, etc.) But perhaps this was not their purpose, and you were only trying to suggest some approach to parse the comma-separated value. If this is the case, all those CamelCase macros are not needed, and you can use directly my lowercase ones which hold the data to show. – JLDiaz Oct 06 '15 at 09:46
  • Ah, okay, yes, I understand. It is entirely possible, that I have to format each field, so I will still use these macros. – SamHoff Oct 06 '15 at 09:52
  • I have another question to this solution.
    So, I have many rows and for better readability, I want to set '\rowcolor' for the saturdays and sundays.
    I also ask this here: http://tex.stackexchange.com/questions/271764/if-condition-without-any-package , but maybe I have a better fortune here in this topic.
    – SamHoff Oct 14 '15 at 10:21
  • @SamHoff Answered your other question at: http://tex.stackexchange.com/a/272938/12571 – JLDiaz Oct 14 '15 at 11:10