3

I am making a wine list from a CSV file (see my first question here: How to import data from excel and format it as text in LaTeX?) and I need to align the prices on the right.

To do this, I used the datatool package to fetch the informations from my spreadsheet, \DTLforeach to iterate what I wanted to do and \hfill to align my prices on the right. (see code after the picture)

As you can see on the picture, it worked very well for every line but the last one of each (subsub)section, which is slightly misaligned:

enter image description here

Here is my code:

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}

% Pour modifer les marges
\usepackage{geometry}
% Marges du document 
\geometry{hmargin=1.5cm,vmargin=1.5cm}


% To remove the heading of the table of contents ("Contents")
\makeatletter
\renewcommand\tableofcontents{%
    \@starttoc{toc}%
}
\makeatother %%% WAS \makeatotherx = ERROR %%%

% To make itemized lists
% This package provides user control over the layout of the three basic list environments: enumerate, itemize and description. It supersedes both enumerate and mdwlist (providing well-structured replacements for all their funtionality), and in addition provides functions to compute the layout of labels, and to ‘clone’ the standard environments, to create new environments with counters of their own.
\usepackage{enumitem}

% Datatool package to load external files (csv)
\usepackage{datatool}

%--------------------------%

\title{Carte des Vins}
\author{B}
\date{\today}

%--------------------------%
\setcounter{secnumdepth}{-2}
\begin{document}
\maketitle
\tableofcontents

%--------------------------%
\newpage
\section{Bordeaux} 

% Load CSV database (here bordeaux.csv)
% and give it a label (here BOR)
\DTLloaddb{BOR}{bordeaux.csv}

    \subsection{Red}
%%%%%%% CUT CODE %%%%%%%%%%%%%%%%%%%%%%%%%
\newpage

            \subsubsection{Saint-Julien}
%%%%%%%%%%%%%%%
% Iteration for Bordeaux Red Saint-Julien (R03)
\DTLforeach*[\DTLiseq{\Region}{R03}] % Condition
 {BOR} % Database label
     {\Vintage=Vintage,\Name=Name,\Classification=Classification,\Type=Type,\Origin=Origin,\Region=Region,\CostPrice=CostPrice} % Assignment
{% Stuff to do at each iteration:
\begin{itemize} %%% ABSENT IN MY ORIGINAL CODE %%%
    \item[]
    \textbf{\Vintage}
    \textbf{ \Name}
    \textit{ \Classification}
    \hfill\CostPrice
\end{itemize} %%% ABSENT IN MY ORIGINAL CODE %%%
}
%%%%%%%%%%%%%%%

        \subsubsection{Margaux}
%%%%%%%%%%%%%%%
% Iteration for Bordeaux Red Margaux (R04)
%%%%%%%%%%%%%%%%% CUT CODE%%%%%%%
\end{document}

How can I align all my prices on the right?

Excerpt of my CSV file:

CODE,Vintage,Name,Classification,Origin,Size,Type,Wine,Region,Stockholding,CostPrice,TOTCostPrice,TOTCostPriceBis
GRUAUD LAROSE,1971,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,2.0, £15.00 , £30.00 , £30.00 
LALANDE BORIE,2011,Château Lalande-Borie,,Saint-Julien,Bottle,Red,Bordeaux,R03,35.0, £19.70 , £689.50 , £689.50 
RESERVE LEOV-BARTN,2011,La Réserve de Léoville Barton,,Saint-Julien,Bottle,Red,Bordeaux,R03,12.0, £20.86 , £250.32 , £250.32 
CLOS DU MARQUIS,2004,Clos du Marquis,,Saint-Julien,Bottle,Red,Bordeaux,R03,3.0, £35.83 , £107.49 , £107.49 
GRUAUD LAROSE,2005,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,16.0, £43.49 , £695.84 , £695.84 
DUCRU BEAUCAILLOU,1978,Château Ducru-Beaucaillou,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,2.0, £56.52 , £113.04 , £113.04 
LAGRANGE 3EME SJ,2005,Château Lagrange,3ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,6.0, £58.75 , £352.50 , £352.50 
LEOVILLE POYFERRE,2000,Château Léoville Poyferre,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,2.0, £73.33 , £146.66 , £146.66 
GRUARD LAROSE,1986,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,1.0, £100.00 , £100.00 , £100.00 
13
  • 1
    Unfortunately the code as shown can't be run (a good MWE for LaTeX should start with \documentclass and should have a \begin{document}...\end{document} pair, in this case it would also help if you could supply example .csv data, see tex.meta.stackexchange.com/q/228/35864), so I can only guess that you are missing a % somewhere. – moewe Sep 22 '18 at 13:52
  • 3
    I did compile your document here... Have you noticed you are getting lots of compilation errors? You really shouldn't ignore these. Your code is doing an \item without being wrapped in a list environment (and this is adding a space after the last entry). Try adding \begin{itemize} before the \DTLforeach command and an \end{itemize} after it. The output should look right then. Ooh, and you have a typo. You have \makeatotherx, with an extra x. – Phelype Oleinik Sep 22 '18 at 14:20
  • 2
    I get two kinds of errors: (1) ! Undefined control sequence. l.28 \makeatotherx. It should have been \makeatother instead. (2) ! LaTeX Error: Lonely \item--perhaps a missing list environment.. This is because you have \item[] in your code when there is no itemize or enumerate to make use of it. That causes an error. – moewe Sep 22 '18 at 14:23
  • 2
    Yes, but errors must be fixed even if superficially they don't affect the PDF - the absolutely affect the output. TeX has a limited ability to recover from errors, but usually it has to guess what to do and that is rarely exactly what you intended to happen. (1) Replace \makeatotherx with \makeatother. (2) Either don't use \item at all or wrap it into an \begin{itemize}...\end{itemize}. – moewe Sep 22 '18 at 14:29
  • 1
    no space shows if you follow @moewe advice to add itemize environment to wrap around the entire contents of subsubsection Saint-Julien – user4686 Sep 22 '18 at 14:36
7

There are two obvious problems with your code. You get errors about both of them.

Firstly you mistyped

\makeatother

as \makeatotherx which causes LaTeX to complain

! Undefined control sequence.
l.22 \makeatotherx

Secondly your loop code in \DTLforeach calls \item but there is no surrounding list environment that would know how to deal with it.

Since you want to use \item to get a new line, I suggest a plain trivlist in this case.

%\RequirePackage{filecontents}
\begin{filecontents*}{bordeaux.csv}
CODE,Vintage,Name,Classification,Origin,Size,Type,Wine,Region,Stockholding,CostPrice,TOTCostPrice,TOTCostPriceBis
GRUAUD LAROSE,1971,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,2.0, £15.00 , £30.00 , £30.00 
LALANDE BORIE,2011,Château Lalande-Borie,,Saint-Julien,Bottle,Red,Bordeaux,R03,35.0, £19.70 , £689.50 , £689.50 
RESERVE LEOV-BARTN,2011,La Réserve de Léoville Barton,,Saint-Julien,Bottle,Red,Bordeaux,R03,12.0, £20.86 , £250.32 , £250.32 
CLOS DU MARQUIS,2004,Clos du Marquis,,Saint-Julien,Bottle,Red,Bordeaux,R03,3.0, £35.83 , £107.49 , £107.49 
GRUAUD LAROSE,2005,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,16.0, £43.49 , £695.84 , £695.84 
DUCRU BEAUCAILLOU,1978,Château Ducru-Beaucaillou,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,2.0, £56.52 , £113.04 , £113.04 
LAGRANGE 3EME SJ,2005,Château Lagrange,3ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,6.0, £58.75 , £352.50 , £352.50 
LEOVILLE POYFERRE,2000,Château Léoville Poyferre,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,2.0, £73.33 , £146.66 , £146.66 
GRUARD LAROSE,1986,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,1.0, £100.00 , £100.00 , £100.00 
\end{filecontents*}
\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}

\makeatletter
\renewcommand\tableofcontents{%
    \@starttoc{toc}%
}
\makeatother

\usepackage{enumitem}
\usepackage{datatool}

\begin{document}
\section{Bordeaux} 
\DTLloaddb{BOR}{bordeaux.csv}
\subsection{Red}
\subsubsection{Saint-Julien}

\begin{trivlist}
\DTLforeach*[\DTLiseq{\Region}{R03}] % Condition
 {BOR} % Database label
     {\Vintage=Vintage,\Name=Name,\Classification=Classification,\Type=Type,\Origin=Origin,\Region=Region,\CostPrice=CostPrice} % Assignment
{% Stuff to do at each iteration:
    \item[]
    \textbf{\Vintage}
    \textbf{ \Name}
    \textit{ \Classification}
    \hfill\CostPrice
}
\end{trivlist}

\end{document}

Possibly a table (tabular) would be a better fit.

5

Apart from the problem in the code, the root issue is that \CostPrice always has an ending space, as one can see by using \texttt{\meaning\CostPrice}+++.

enter image description here

This comes from the fact that your csv data has spaces before the commas, as datatool doesn't trim leading or trailing spaces.

Note that spaces count in the usual TeX manner and won’t be trimmed from either side of the separators. (p. 46 of the datatool user manual)

Thanks to @NicolaTalbot who kindly pointed it out in a comment.

Here is an excerpt of your data file:

GRUARD LAROSE,1986,Château Gruaud-Larose,2ème Grand Cru Classé ,Saint-Julien,Bottle,Red,Bordeaux,R03,1.0, £100.00 , £100.00 , £100.00 

where the spaces show around the monetary items.

With the following (from @moewe's comment to OP)

\begin{itemize}
%%%%%%%%%%%%%%%
% Iteration for Bordeaux Red Saint-Julien (R03)
\DTLforeach*[\DTLiseq{\Region}{R03}] % Condition
 {BOR} % Database label
     {\Vintage=Vintage,\Name=Name,\Classification=Classification,\Type=Type,\Origin=Origin,\Region=Region,\CostPrice=CostPrice} % Assignment
{% Stuff to do at each iteration:
    \item[]
    \textbf{\Vintage}
    \textbf{ \Name}
    \textit{ \Classification}
    \hfill\CostPrice
}
%%%%%%%%%%%%%%%
\end{itemize}

there is no problem

enter image description here

The extra space doesnt show then. (it is suppressed by item paragraph)

Remark: in fact even with your buggy code you could have avoided the sapce this way:

%%%%%%%%%%%%%%%
% Iteration for Bordeaux Red Saint-Julien (R03)
\DTLforeach*[\DTLiseq{\Region}{R03}] % Condition
 {BOR} % Database label
     {\Vintage=Vintage,\Name=Name,\Classification=Classification,\Type=Type,\Origin=Origin,\Region=Region,\CostPrice=CostPrice} % Assignment
{% Stuff to do at each iteration:
    \item[]
    \textbf{\Vintage}
    \textbf{ \Name}
    \textit{ \Classification}
    \hfill\CostPrice
}%<----- suppress space from line end
%%%%%%%%%%%%%%%

Because then there is only ONE not TWO space tokens at the end of paragraph. Of course much better is to wrap in itemize else \item is illegal.

2
  • datatool doesn't trim leading or trailing spaces. (p. 46 of the user manual: "Note that spaces count in the usual TeX manner and won’t be trimmed from either side of the separators.") – Nicola Talbot Sep 22 '18 at 17:09
  • @NicolaTalbot ok! (if you ever need it, xinttools has \xintZapSpaces which in two expansion steps removes leading and trailing spaces of its argument #1; you need some \expandafter if #1 is \Foo, to unpack its contents, so typically \oodef\FooStripped{\expandafter\xintZapSpaces\expandafter{\Foo}} where \oodef is xint's lingua for two expansions) (page 174 of xint.pdf doc) – user4686 Sep 22 '18 at 17:44

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.