GeneralUsing datatool to structure a book of recipes

LaTeX specific issues not fitting into one of the other forums of this category.
Post Reply
petersfreeman
Posts: 19
Joined: Wed Apr 28, 2021 9:40 am

Using datatool to structure a book of recipes

Post by petersfreeman »

I’m using the datatool package to structure a book of family recipes for my wife and I to use. I plan to divide it into three parts:

Common (recipes that we both use)
Mary (recipes that only she likes)
Peter (recipes that only I like)

To define the book structure, I’m starting simply using an Excel spreadsheet to layout the structure and save it as a CSV file as shown below (The first line is the header):

"Part","Chapter","Section"
"Common","Breakfast","Banana Pancakes"
"Common","Breakfast","Tortilla de Patatas"
"Common","Candy","Chocolate Salami"
"Common","Cookies","Cranberry Walnut Oatmeal Cookies"
"Common","Cookies","Gingersnap Cookies"
"Mary","Salads","Caesar Salad"
"Mary","Salads","Quinoa and Black Beans Salad"
"Peter","Muffins","Bran Muffins"
"Peter","Muffins","Cornmeal Muffins"
"Peter","Soups","Thai Coconut Chicken Soup"

Using datatool, I want output similar to as if I hard coded this way:

Code: Select all

\documentclass[]{book}

\begin{document}
	\part{Common}
	\chapter{Breakfast}
	\section{ Banana Pancakes}
	\section{Tortilla de Patatas}

	\chapter{Candy}
	\section{Chocolate Salami}

	\chapter{Cookies}
	\section{Cranberry Walnut Oatmeal Cookies}
	\section{Gingersnap Cookies}

	\part{Mary}
	\chapter{Salads}
	\section{Caesar Salad}
	\section{Quinoa and Black Beans Salad}

	\part{Peter}
	\chapter{Muffins}
	\section{Bran Muffins}
	\section{Cornmeal Muffins}
	\chapter{Soups}
	\section{Thai Coconut Chicken Soup}

\end{document}
The problem is that it keeps repeating all fields even though I have placed conditional statements to control that aspect. Below is my code. What am I doing wrong?
Recipes.csv
(461 Bytes) Downloaded 620 times

Code: Select all

\documentclass[]{book}

\usepackage[]{datatool}

% Load the CSV file
\DTLloaddb{recipes}{Recipes.csv}

\begin{document}
	
	% Initialize variables to store previous values
	\newcommand{\prevpart}{}
	\newcommand{\prevchapter}{}
	\newcommand{\prevsection}{}
	
	% Iterate through the database and insert the data into the corresponding LaTeX commands
	\DTLforeach{recipes}{\partname=Part,\chaptername=Chapter,\sectionname=Section}{%
		% Insert \part if different from the previous one
		\ifx\partname\prevpart\else
			\part*{\partname}
			\renewcommand{\prevpart}{\partname}
		\fi
		
		% Insert \chapter if different from the previous one
		\ifx\chaptername\prevchapter\else
			\chapter*{\chaptername}
			\renewcommand{\prevchapter}{\chaptername}
		\fi
		
		% Insert \section if different from the previous one
		\ifx\sectionname\prevsection\else
			\section*{\sectionname}
			\renewcommand{\prevsection}{\sectionname}
		\fi
	}
	
\end{document}


Peter

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

petersfreeman
Posts: 19
Joined: Wed Apr 28, 2021 9:40 am

Using datatool to structure a book of recipes

Post by petersfreeman »

I just tested the code and it fails to find Recipes.csv. How do I connect it so the code finds it? ~ Peter
rais
Posts: 419
Joined: Sun Nov 16, 2014 8:51 pm

Using datatool to structure a book of recipes

Post by rais »

petersfreeman wrote:I just tested the code and it fails to find Recipes.csv. How do I connect it so the code finds it? ~ Peter
Just put it into a filecontents environment into your preamble, then the file will be created wherever the .tex file is run.

Code: Select all

\begin{filecontents*}{Recipes.csv}
% dump contents here
\end{filecontents*}
(the starred form should suppress its usual comment lines, which might confuse datatool later)

Your choice for the macro names is, hmm, adventurous, considering that at least two of them are already defined by the class you're using. You see what I mean when trying, say, the unstarred version of \part within your \DTLforeach statement.

Code: Select all

		\ifx\partname\prevpart\else
			\part*{\partname}
			\renewcommand{\prevpart}{\partname}
		\fi
As far as \ifx is concerned, \partname and \prevpart can never be the same this way: both have different expansion levels. What you want to do is expand \partname to its contents and put that into \prevpart.

Code: Select all

		\edef\tmppa{\partname}%
		\ifx\tmppa\prevpart\else
		  \typeout{+-+ p/c (\prevpart/\partname)}%
			\part*{\partname}
			\edef\prevpart{\partname}%
			\edef\prevchapter{}%
		\fi
expands \partname, then puts the resulting string into \tmppa (and later into \prevpart). This way, \tmppa and \prevpart can contain the same and the \ifx test no longer fails.
The additional \edef\prevchapter{} clears \prevchapter just after outputting a new part for the case that the last chapter of the previous part has the same title as the first chapter from this new part.

But then, as already indicated, I wouldn't use \partname and the like for running variables :roll:

KR
Rainer
Post Reply