4.3. Configuring Pantry

The Pantry configuration file is XML. If you know nothing about XML, the Wikipedia article is a good place to start.

In this section we'll walk through how to create your own Pantry configuration file. The default name for this file is ~/.pantryrc.xml. If you want to use a different filename for your configuration file, you may specify it by setting an environment variable named PANTRYRC.

So, to get started open a text file named ~/.pantryrc.xml in your favorite text editor. Every .pantryrc.xml file contains the root element pantry-config, so start by including that in your .pantryrc.xml:

Example 4.9. Beginning a .pantryrc.xml file

<pantryrc>
</pantryrc>

4.3.1. Configuring a search path

You can have pantry search several directories for files that you are searching. The concept is similar to the PATH variable that shells use. This way, you need not be in the same directory as the files you are searching, and you will not need to specify the entire path.

The search path feature works only for files that you are searching for foods. It has no effect on the --add option, for example; the --add option will always assume its argument is in the current directory, unless you specify a pathname in the argument. The search path works similarly to the same feature in shells: the path is searched only if the filename does not include a slash. If the filename does include a slash, then only the appropriate directory is searched for the file.

If you do not specify a search path, Pantry will search only the current directory for files.

To specify a search path, create one path element for each directory you wish to be in your path. Each element has a single attribute, dir. As with shells, you must specify the current directory if you want pantry to include it when searching. To specify the current directory, use a single period.

The next example specifies two directories, the current directory and the /home/massysett/pantry directory, for the search path.

Example 4.10. .pantryrc.xml with search path specified

<pantryrc>
	<path dir='.' />
	<path dir='/home/massysett/pantry' />
</pantryrc>

4.3.2. Specifying your own nutrient lists, and a default nutrient list

Using your .pantryrc.xml, you may specify your own nutrient lists. You may also specify which nutrient list is the default--that is, which nutrient list Pantry uses when you do not use the --nutrient-list option.

4.3.2.1. Specifying a default nutrient list

The default nutrient list is the one Pantry uses when you do not specify a nutrient list using the --nutrient-list option. The default nutrient list can be one of the nutrient lists included with Pantry, or it can be a nutrient list you create yourself. You can set a default nutrient list even if you do not define any of your own nutrient lists, but of course then you will need to choose only from one of the nutrient lists included with Pantry. If you do not specify a default nutrient list, Pantry will use facts.

To specify a default nutrient list, add a default-nutrient-list element. This element has a single attribute, name, which specifies the name of the default nutrient list. This name is case-sensitive. In the following example, the default nutrient list is facts.

Example 4.11. Specifying a default nutrient list in .pantryrc.xml

<pantryrc>
	<path dir='.' />
	<path dir='/home/massysett/pantry' />

	<default-nutrient-list name='facts' />
</pantryrc>

4.3.2.2. Specifying your own nutrient lists

You may specify nutrient lists of your own in your .pantryrc.xml file. Each nutrient list you create will reside inside a nutrient-list element. To define multiple nutrient lists, you may define multiple nutrient-list elements; each nutrient-list element must be the direct descendant of the nutrient-lists element.

Each nutrient-list element has a single attribute, name, which defines the name of the nutrient list. name must begin with a letter, with subsequent characters being either letters or numbers. The nutrient-list element is parent to one or more empty nutrient elements.

Each nutrient element has three attributes. The first is name, such as Calories or Protein. The second is units, or the units corresponding to the name. For Calories this would be kcal; for Protein, this would be g. The third attribute, goal, is optional. If you wish to set a goal for your intake of this nutrient, set attribute equal to your numeric goal. If on the other hand you are including this nutrient in your nutrient list only because you want to see this nutrient printed in reports, you may set the goal attribute to the empty string ("") or you may simply omit this attribute.

The name and units values you use in your nutrient elements must correspond to one of the possible nutrients in Pantry. To see a list of all the possible nutrients in Pantry, use --nutrient-list all --print list:

Example 4.12. Showing all available nutrients

$ pantry --nutrient-list all --print list
==========
pantry-dev: warning: you did not specify any files to search.
==========
Nutrient Name             Units          Goal  
------------------------------------------------
10:0                      g              None  
12:0                      g              None  
13:0                      g              None  
14:0                      g              None  
14:1                      g              None  
15:0                      g              None  
15:1                      g              None  
16:0                      g              None  
16:1 c                    g              None  
16:1 t                    g              None  
[ trimmed to save space ]

4.3.2.2.1. Specifying your own nutrient lists: an example

To get started, let's suppoose I made a New Year's resolution to eat less. I want to eat 1800 calories a day. I also want to make sure I eat 40 grams of fat per day, 90 grams of protein a day, and 270 grams of carbs a day. I'm also curious about how much calcium I am taking in, but I don't want to bother setting a goal for that. I decide to create a new nutrient list called eatless to help me meet my goals. Here is what my .pantryrc.xml would look like:

Example 4.13. .pantryrc.xml with new nutrient list

<pantryrc>
	<path dir='.' />
	<path dir='/home/massysett/pantry' />

	<default-nutrient-list name='facts' />
	<nutrient-list name='eatless'>
		<nutrient name='Calories' units='kcal' goal='1800' />
		<nutrient name='Total Fat' units='g' goal='40' />
		<nutrient name='Protein' units='g' goal='90' />
		<nutrient name='Total Carbohydrate' units='g' goal='270' />
		<nutrient name='Calcium' units='mg' />
	</nutrient-list>
</pantryrc>

To use my new nutrient list, I can just specify --nutrient-list eatless when I use pantry:

Example 4.14. Using a new nutrient list

$ pantry --name "Apples, raw, with skin" --print traits-nuts \
> --nutrient-list eatless master
Apples, raw, with skin
Group: Fruits and Fruit Juices
Refuse: 8 percent Core and stem
100 g (100g)
Nutrient                  Amount         %G     %TOT  
-------------------------------------------------------
Calories                  52   kcal       3      100   
Total Fat                 0    g          0      100   
Protein                   0    g          0      100   
Total Carbohydrate        14   g          5      100   
Calcium                   6    mg         NA     100   

If I wanted to make eatless the new default nutrient list so that pantry would use it even if I do not use the --nutrient-list eatless, I would add <default-list name='eatless' /> right after any path elements in my .pantryrc.xml.

4.3.3. Specifying custom sort orders

As we learned previously, you can use the --sort to sort the reports that Pantry prints by the traits of the foods. But this only sorts the strings into your system's collation order. What if you want to sort something into an arbitrary order? For instance, you might want to sort your meals into the order Breakfast, Lunch, and Dinner, which certainly is not alphabetical order.

To do this you can specify a sort order in your .pantryrc.xml file. You may do this for any trait that is not a numeric trait--that is, for any trait except the qty and pctRefuse traits. To do this, include an element named sort-order in your .pantryrc.xml file. This element must have a single attribute, trait. For example, here we wish to specify a custom sort order for the meal trait, so we set the trait attribute to meal.

Inside the sort-order element, include a single item element for each value you wish to include in your sort order. Each item element must have a single attribute, value. Here, for example, is how to sort meals into the order Breakfast, Lunch, and Dinner. If the value of a food's trait is not in the sort order list (for example, supper), it is sorted alphabetically with other foods whose trait value is not in the list.

Example 4.15. .pantryrc.xml with sort-order element

<pantryrc>
	<path dir='.' />
	<path dir='/home/massysett/pantry' />

	<default-nutrient-list name='facts' />
	<nutrient-list name='eatless'>
		<nutrient name='Calories' units='kcal' goal='1800' />
		<nutrient name='Total Fat' units='g' goal='40' />
		<nutrient name='Protein' units='g' goal='90' />
		<nutrient name='Total Carbohydrate' units='g' goal='270' />
		<nutrient name='Calcium' units='mg' />
	</nutrient-list>

	<sort-order trait='meal'>
		<item value='Breakfast' />
		<item value='Lunch' />
		<item value='Dinner' />
	</sort-order>
</pantryrc>