# Pantry User Guide

Version &version; released &release-date;
Omari
Norman
&copyright;

## About Pantry

As you can see, this user manual is of some length. Right now you are probably wondering what Pantry does, whether it is right for you, and how it compares to similar programs.

### What Pantry is

Pantry is a command-line oriented nutrient analysis program. That's right, command-line oriented. What's more, Pantry is a true command-line program: there are no menus, there are no prompts. Instead, you simply type commands from your shell prompt, and Pantry does what you ask it to do, displaying results if you have asked it to do that. Thus, Pantry is different from other programs which run in a text-based terminal but which also present the user with menus; Wikipedia calls such programs text-user interface programs.

In addition to using Pantry from your shell prompt, you also interact with it through XML files. Using XML, you can edit Pantry's configuration file. You can also add nutrient information for custom foods (though Pantry includes nutrient information for over 7,000 foods to get you started) and recipes using XML.

### Pantry's advantages

Pantry's true command-line interface gives it many advantages. Because Pantry works from your shell prompt, you can easily combine it with other text-processing tools. You can also easily write scripts incorporating Pantry, in ways that even I cannot anticipate. This is the strength of the Unix "toolbox" way of using a computer.

In addition, nothing beats the speed of a command-line program for something you use frequently and are familiar with. If you are using a nutrient-analysis program to track your daily food intake, you will appreciate how quickly you can use Pantry for this purpose. Indeed, I developed Pantry due to my frustration with current tools because it was very tedious to use them to quickly tally a day's food intake.

Because Pantry runs from a text console, you can easily set it up on one computer that has an SSH server running. You may then access your nutrient data from any computer that has an SSH client. Though Web-based nutrition-tracking services also offer the ability to access your data from any Internet-connected computer, Pantry is more private than Web-based services.

### Pantry disadvantages

The biggest disadvantage of using Pantry is the same as its biggest advantage: its command-line interface. Graphical user interface programs attempt to be self-documenting: just sit down, click on some buttons, and hopefully you can figure things out. With Pantry, on the other hand, you will absolutely have to read this manual to figure out how it works, and you will need some practice before you are comfortable with Pantry. In this way, Pantry resembles other command-line oriented Unix programs. As with other Unix programs, once you learn Pantry, you will love its speed and efficiency--but you will have to spend some time learning.

Similarly, because of its command-line interface, you will find that you are most efficient with Pantry if you know your way around a Unix shell prompt. For example, you will find that you can use Pantry more quickly if you know how to use your shell's features to manipulate your command history. Such knowledge is useful for any Unix command-line program, not just Pantry; however, building up this knowledge takes some time.

Pantry has no tools to graphically visualize your food intake. I might eventually add such features using Gnuplot or something similar.

A final disadvantage of using Pantry is that it is still new. I am still tweaking it, making changes, adding features, and improving the documentation. But perhaps this is not such a disadvantage: software that improves is nice. If you have any features that you would like, ask!

### Alternatives

I know I like to check out many possible programs before settling on one to learn to use--and I always like trying new programs too. Here are some possible alternatives to Pantry that you might take a look at:

NUT

  This is probably the leading nutrient analysis program for Unix. It has a text user interface and is very mature. NUT website.

Crosstrainer

  The best GUI program for nutrient analysis that I have ever seen. It does more than nutrient analysis, too--for example it can track your exercise too. (Pantry will never do anything other than nutrients.) Crosstrainer only runs on Windows though, and I have not used Windows in quite awhile. Crosstrainer is also somewhat expensive. Crosstrainer website.

nutritiondata.com

  This website has great tools, and neat graphical features. Using it as a food diary is somewhat cumbersome, however. nutritiondata.com website.

Fitday

  This is the best food diary website that I have found. Fitday website.

### Getting support and reporting bugs

For help using Pantry, join the Pantry users email list. Signup info is here. You can also report bugs by sending an email to pantry-users@lists.sourceforge.net. You need not join the email list in order to send mail to it.

## Installing Pantry

This section will tell you how to install Pantry on a Unix-like operating system, such as Linux, Mac OS X, or one of the BSDs. Theoretically, Pantry also runs on Windows. I say "theoretically" for two reasons. First, though I have a copy of Windows XP, I almost never use it and have made little effort to test Pantry on Windows. I know basic Pantry commands work in Windows, but that is all I know. For me to be confident there are no Pantry Windows bugs, more testing would be necessary. Second, I doubt anyone would be interested in running Pantry in Windows. Windows software is hostile to the command line (for instance, the Windows command-line shell is absolutely awful) and Windows users are hostile to the command line, as they think it is primitive. If you successfully use Pantry under Windows, I'd like to hear from you. If you have bugs to report, I'd like to hear those too. I'd expect that if you love the command line but use Windows anyway, you're probably using Cygwin. Pantry should work fine under Cygwin; again, please report any bugs you may encounter. I'll assume you're comfortable using command-line tools--if you weren't, you probably wouldn't be attempting to use a command-line nutrient analysis program.

First, you'll need Python 2.4 or later in order to use Pantry. Any recent Linux distribution, as well as the latest versions of all the major BSDs, either have Python 2.4 already installed or make it available through their package manager or ports system. However, Mac OS X 10.4 ("Tiger", the latest release of Mac OS as of this writing) includes Python 2.3, which is too old to run Pantry. You'll have to look into installing a newer Python (either 2.4 or the newer 2.5 will work), either from the Python website or by using a tool such as Fink.

If you want to see what version of Python you have installed, run `python -c 'import sys; print sys.version'` at a command prompt.

### Installation instructions

You may be used to compiling programs by hand using `./configure; make; make install`. Since Pantry is written in Python, an interpreted language, no compilation is required. Instead, to follow Pantry, follow the directions below.

1. Unpack the Pantry distribution file using `tar -xzf pantry-&version;.tar.gz`. Change to the newly made directory with `cd pantry-&version;/`.

2. Become root, and issue `python setup.py install`. That's it!

3. Optional: install manual page. The Pantry installer only installs the Panty source code and a very short script used to start Pantry. The installer does not install the man page. In the Pantry distribution, you will find a file `docs/pantry.1`. Copy this to a location where your other locally installed section 1 manpages are--on my system, that is `usr/local/share/man/man1/`.

   You will also find the manpage in .

The installer does not install documentation or many other handy files that are in the Pantry distribution tarball. So you will want to keep handy the directory where you unpacked the Pantry tarball. We'll use some of those files later on.

Speaking of documentation, you will find this manual in many formats (including PDF, plain text, and the XML source code) in the `docs/` directory.

### Tailoring your installation

If you want to install Pantry as a non-root user, you'll want to read the Python distutils manual, which explains various options for the `setup.py` script.

Also, I should warn you that Python's distutils has no way to uninstall what it installs. If you want to easily remove Pantry, users of most distributions should look into using CheckInstall. Gentooists can easily write an ebuild for Pantry using the distutils eclass.

### About the documentation

The Pantry User Guide, the document that you are reading right now, is available in several formats in the Pantry distribution in the directory named `docs`. There you will find one gigantic HTML file and a plain-text version as well. You will also find an HTML version that has been "chunked" into smaller files in the `docs/html-chunk` directory. Finally, you will also find a PDF version in US Letter-sized paper. Unfortunately, right now I do not know how to make a good PDF in A4 paper, so US Letter is all you will find.

There are many examples sprinkled throughout the text. In these examples, your shell prompt is indicated with `$`. Many of the lines we will be entering in the examples are quite long. When you type them into your computer, you can just enter them on one line. However, this would look bad in the printed documentation, so we use the backslash to continue lines across line breaks. The beginning of each continued line is indicated with a `>`. Don't enter the `>` if you are entering the lines at your computer.

Some of the examples are too wide to fit on the PDF pages, so they got cut off. I don't know how to fix this, but you can always look at the HTML version to see examples that are not cut off.

## Basic Pantry commands

The core program of Pantry is named, appropriately enough, `pantry`. In this section you'll learn how `pantry` works. But first you'll need to understand the way Pantry was designed--that is, the Pantry Paradigm.

### The Pantry Paradigm

The basic unit of Pantry is the food. Foods are grouped together and stored on your computer in files. There are four different kinds of files that store foods, but the most important kind is simply called a Pantry native file. You'll notice if you run the Unix program `file` on a Pantry native file, it is most likely a Berkeley DB file. Unix geeks will cringe at the fact that this file is not plain text.

Pantry works very quickly with Pantry native files, even if the file contains thousands of foods.

Pantry comes with a Pantry native file named `master` that contains 7,519 foods. These foods come from the U.S. Department of Agriculture's National Nutrient Databse for Standard Reference, release 20. A big thank-you goes to these folks for producing this database--without it Pantry would never have been written. Most food databases that you will find anywhere, such as the one at NutritionData.com, are derived from the same USDA database.

Every food has several traits. Later on you will learn how you can set a food's traits; foods in the `master` file already have their traits set. The traits are:

#### Food traits

`name`

  The name of this food, such as `Bananas, raw`.

`date`

  The date on which you ate this food. This is a string; no special date formatting rules apply to it.

`meal`

  The meal in which you ate this food (`Breakfast` `Lunch`, `midnight snack`, etc--whatever you wish)

`group`

  Useful for grouping foods together. You can use familiar food groups (such as `Dairy`, `Poultry`, etc.) or you might group foods together if you eat them together (for instance you might have a group "Cereal and Milk" in which you place those two foods.) We'll learn more about how you can use groups later.

  In the `master` file, each food's `group` trait is already set to one of twenty-four food groups, such as `Fruits and fruit juices` or `Snacks`.

`qty`

  How much of this food you ate. Pantry records this internally as a string; Pantry internally converts it to a number as necessary to perform calculations. You therefore set the `qty` trait to a string that will convert to an integer or to a floating-point number. This can be an integer, floating-point number, or a fraction, such as `1/3`. It can even be a mixed number, such as `1 1/3`. You can set `qty` equal to zero, but this does not delete the food--later we will discuss how to delete foods.

`unit`

  A description of the amount of this food you ate. The units that you can pick from vary for different foods. We will use the term available units to refer to the units that you can pick from for a particular food. Every food has at least three available units: `oz`, `g`, and `lb`. The other available units vary by food. For example, the food in the `master` file named `Bananas, raw` has several other units available, including `Cup, mashed`; `large (8" to 8-7/8" long)`, and `extra small (less than 6" long)`.

  When you keep track of which foods you eat, you'll set the quantity and unit to whatever makes sense: for instance, if you eat some `Bananas, raw`, you can set the quantity to `2` and the unit to `large (8" to 8-7/8" long)`. Remember, you can use any number for quantity you want, including floating point numbers, but you can set the unit only to what is available for that particular food.

`pctRefuse`

  The percent of this food that is waste. For example, with an apple, the core is refuse; for a chicken drumstick, the bone is refuse. Many foods have no refuse; in that case, this trait will be set equal to an empty string or to zero. As with the `qty` trait, Pantry internally keeps this as a string, converting it to a number as needed.

`refDesc`

  A description of the refuse, such as `Core` or `Bone`.

`comment`

  Whatever notes you may wish to add.

`order`

  Any string. As we will see later, `pantry` can sort reports however you like; using the `order` trait, you can sort foods into any arbitrary order.

All Pantry traits are strings. This includes the date trait. Thus, you can set the date trait for a food to `2007-05-06`, `05-06`, `Tuesday`, or even `Who cares?` if you wish. You may also set this trait, and all traits except `unit` and `qty`, to whatever string you wish. Only the `qty` and `unit` traits must be set to a non-zero-length value.

Pantry works by copying foods from one file to another. This makes the `pantry` command mostly a glorified copier. `pantry` starts by examining all the foods in each file that you specify. If you do not specify any `search options`, then all foods in the each file you specify are copied to a temporary place that we will call the buffer. Otherwise, if you specify any `search options`, then only the foods whose traits match all of the search options will be copied to the buffer. Any food not matching the `search options` you specify is ignored. `pantry` then modifies the traits of the foods in the buffer using any `change options` you specified. `pantry` can then send the buffer to a report (which prints the foods to standard output) and add the buffer to other files. All this is best understood with examples, as we will see in the next section.

### Basic food searches

Because Pantry works by copying and changing foods from food files, you'll first need a food file with interesting foods in it. The Pantry distribution contains a file named `master`. It contains over 7,000 foods, which should be enough to get you started. Copy this file to a convenient place (I'd suggest `~/pantry/master` unless you have a better idea) because you'll be using it often and you might even want to change it. Change to the directory that contains your copy and we'll get started!

Like many Unix commands, the `pantry` command takes zero or more arguments and zero or more options, that is: `pantry [OPTIONS] [FILE ...]` . FILE specifies the file you wish to search for foods. `pantry` will search using OPTIONS that you may specify. OPTIONS also perform many other useful tasks, such as modifying the traits of the foods `pantry` finds, printing reports of the foods `pantry` finds, and adding the resuls to files.

For a simple example, run `pantry --name Bananas master` in the same directory as the file containing your `master` file. What happens? Well, as far as you can tell, nothing. But things actually were happening behind the scenes. First, `pantry` examined every food in `master`. Because you specified a search option, `--name Bananas`, Pantry copied all foods matching that criterion into a buffer. However, you did not tell `pantry` to actually do anything with the buffer. So `pantry` terminated without showing you anything at all, and returned you to your command prompt. The buffer that `pantry` made is gone, never to be seen nor heard from again.

### Using the `--print` option

To actually see the buffer, use the `--print` option. It takes a single argument, called a report. Here is an example for starters:

#### Introducing the --print option

&example-print;

As you can see, `--print names` simply prints the name of each food in the buffer. Here the name of the report is `names`. Other handy reports are `traits`, `units`, and `nuts`, to print the traits, available units, and nutrient breakdown of each food in the buffer.

The `traits` report always shows the `qty` and `unit` traits. Other traits are shown only if they are equal to a non-zero-length string or, in the case of the `pctRefuse` trait, if it is not equal to zero.

#### Using `--print traits`

&example-print-traits;

The `units` report prints each food's available units. It does not print `g`, `oz`, or `lb` as these are available for every food.

#### Using `--print units`

&example-print-units;

The `nuts` report prints a food's nutrient breakdown. Later we will talk about why `pantry` printed these particular nutrients, as there are many more nutrients for `Bananas, raw` than were printed here. Also, later we will learn what the two rightmost columns in the report mean (you probably can tell what the first two columns are for.)

#### Using `--print nuts`

&example-print-nuts;

The `nuts` and `units` reports print only a food's nutrients and available units, respectively. They do not print anything else about the food, not even its `name` trait. When there is more than one food in the buffer, one report is printed for each food. It may be obvious that you are looking at the results for more than one food when you are examining a set of `nuts` reports.

#### Two `nuts` reports

&example-two-nuts-reports-1; &example-two-nuts-reports-2;

However, in the next example, you cannot even tell that you are looking at two `units` reports here, and you certainly cannot tell the two foods apart. This next example shows units reports for both `Papaya nectar, canned` and `Papayas, raw`:

#### Two `units` reports

&example-two-units-reports;

We will discover a solution to this problem in the next section.

#### Combining reports

As you saw above, using just the `nuts` or `units` reports can be confusing, especially when you have more than one food in your buffer, because these reports do not indicate which food goes with which nutrients or with which units.

An easy solution for this is to combine reports. By separating each report name with a dash, you may tell `pantry` to print more than one report for each food.

##### Combining reports

&example-combining-reports-1; &example-combining-reports-2;

As you can see, some whitespace would help make this more readable. To add whitespace, use the `blank` report. It simply prints a blank line.

##### Using the `blank` report

&example-blank-report;

### Details on searching

Here are some important details about searching.

#### More traits you may use to search

As you've seen, `name` is one trait you can search by. When searching, you may limit your buffer by any traits you wish. Here are the options you use in order to limit your search by particular traits. As with many Unix commands, you can use either a long option (indicated by two dashes) or a short option (with one dash).

- `-n` or `--name`

- `-g` or `--group`

- `-d` or `--date`

- `-m` or `--meal`

- `-u` or `--unit`

- `-q` or `--qty`

- `-c` or `--comment`

- `-o` or `--order`

You may use as many of these options in a single `pantry` command as you wish. If you use more than one search option, then Pantry will add foods to the buffer only if they match all the traits you specify:

##### Using multiple search options

&example-searches-cumulative-1; &example-searches-cumulative-2;

#### Searches are regular expressions

A very important detail about searches is that all search patterns are regular expressions. Regular expression gurus will appreciate knowing that Pantry uses Perl-compatible regular expressions. Links from this page will help give you an idea of what this means. If you are familiar with the Unix command-line utilities `grep` and `egrep`, the regular expressions used in Pantry are most similar to those used in `egrep`. The Python documentation gives the definitive guide to Pantry's regular expression syntax.

This allows you to be very flexible in how you specify your searches. You've already seen one consequence of this: a search pattern only needs to match a portion of a trait in order for that food to be included in the results--that is, `--name Bananas` matches foods that have "Bananas" anywhere in their name.

If you don't want to learn regular expressions, that's okay. Simple searches using just letters and numbers will work just fine. However, you should know that the following characters have special meanings in regular expressions:

    [\^$.|?*+()

If you don't know regular expressions, avoid including any of these characters in your search patterns. Remember to quote your search patterns if they include spaces. For example:`pantry --name 'Bananas, raw' --print traits-units master`.

If you want to learn more about the power of regular expressions, this website is a great place to start. For those already familiar with regular expressions, following is an example of how they can come in handy. This also demonstrates the power of Pantry's command line interface, as it is easy to use Pantry with other Unix programs such as `wc`, which counts words and lines.

##### Using regular expressions

&example-regular-expressions-1; &example-regular-expressions-2;

As the previous example shows if your search pattern includes characters that are special to your shell, remember to quote it--but you already knew that if you're familiar with regular expressions.

#### My search is returning foods I don't want!

Because search patterns are regular expressions, they will sometimes return more foods than you are interested in. In the next example, I only want to know about `Apples, raw, without skin`. However, the buffer also includes two other foods that contain that same string:

##### A search that has more foods than I am interested in

&example-too-many-foods;

There are two ways to fix this. The first way is to use a feature of regular expressions called anchors. The `$` anchor matches the end of the string. Here, it tells Pantry that there cannot be any characters between `Apples, raw, without skin` and the end of the `name` trait. The anchor is only the dollar sign; the backslash is there in order to keep the shell from giving the dollar sign a special meaning. See this webpage for more information on why you need to quote characters in Unix shells. An easy solution in this example would have been to use single quotes, but due to idiosyncracies in the scripts that automatically build the examples for the documentation, all the examples in the user guide use double quotes instead.

##### Using anchors

&example-anchors;

Another way to fix this problem is to use the `--exact-match` or `-x` option. This option changes all `search options` so that they no longer use regular expressions. Instead, with this option, a food's traits must exactly match the search options in order to be included in the buffer.

##### Using the `--exact-match` option

&example-exact-match;

#### Searches are case sensitive

By default, all searches in Pantry are case sensitive. This is true both for searches by trait as well as when you are using the `--c-unit` option. To make these searches case insensitive, use the `--ignore-case` or `-i` option. In addition, searches using the `--exact-match` option are also case sensitive. The `--ignore-case` option has no effect when using the `--exact-match` option; that is, `--exact-match` searches are always case sensitive.

### Changing food traits

Pantry would not be very useful if you could only search the `master` for its contents and print results from it. Fortunately, Pantry makes it very easy for you to change the traits of foods.

When you run `pantry` with the search options we discussed above, `pantry` first searches the files you specified for foods with the traits you specified with your options. `pantry` then changes the resulting foods to the traits you specify, as we will discuss next. For instance, in the next example we change the `date` trait of a raw banana. However, as the example also shows, the change is only temporary. Only the food in the buffer is changed, and the food in the buffer is a copy of the food in the `master` file. Later we will learn how to save the new foods that you make.

#### Changing foods

&example-changing-foods-1; &example-changing-foods-2; &example-changing-foods-3;

There are eight options you use to change food traits. Each takes an argument to indicate what you would like to change the trait to:

- `--c-name` or `-N`

- `--c-group` or `-G`

- `--c-date` or `-D`

- `--c-meal` or `-M`

- `--c-comment` or `-C`

- `--c-unit` or `-U`

- `--c-qty` or `-Q`

- `--c-order` or `-O`

Changing most traits is easy, as you may change them to any string that you wish, including a zero-length string. This gives you a great deal of flexibility. The `group` trait need not be set to a "official" food group. The `date` trait does not need to respect any particular date format--indeed, strictly speaking, it need not be any date at all!

Only two traits are not this flexible. As with the other traits, Pantry stores the `qty` trait as a string, but it is converted internally to a number as needed, so the value of this trait must be something that can be converted to a number. It can be an integer, a floating-point number, or even a fraction or mixed number. Thus, the following values are valid for the `qty` trait:

- `3`

- `1/3`

- `3 1/3`

- `3.33`

Entering zero for the `qty` trait does not delete foods; later we'll discuss how to delete foods.

The other inflexible trait is the `unit` trait. This trait must be equal to one of the available units for each particular food. The argument that the `--c-unit` takes is actually a regular expression. `pantry` searches the food's available units for a single unit matching that regular expression.

#### Changing the unit trait

&example-change-unit;

If the regular expression you enter as an argument for `--c-unit` matches more than one of a food's available units, `pantry` will give you a warning message. `pantry` will not include the food (either changed or unchanged) in the search results; therefore, the food will not be printed in any reports you may have asked for using the `--print` option. However, Pantry will still include in the search results other foods that it did change. In the next example, the food `Bananas, raw` cannot have its units changed, because the search string `cup` matches more than one of the food's available units. However, the food `Bananas, dehydrated, or banana powder` is included in the search results because its unit was successfully changed.

#### Errors when changing the unit trait

&example-change-error-1; &example-change-error-2;

As we discussed, you can use fractions and mixed numbers for the `qty` trait:

#### `qty` may be a fraction or mixed number

&example-fractions-1; &example-fractions-2;

### Using nutrient lists to compare foods to particular nutrient goals

#### What are nutrient lists?

Nutrient lists have two purposes: first, they allow you to select which nutrients appear in `nuts` reports; and second, they allow you to compare your nutrient intake to certain goals.

If you're keeping track of your food intake, you'll probably want to know how your nutrient intake compares against certain goals you've set for yourself. For instance, you might decide you want to take in 65 grams of fat every day, or 2800 calories a day. You can tell Pantry what your goals are and it will help you compare certain foods, or all your food intake if you wish, against those goals.

In addition, the `master` file in Pantry has dozens of nutrients. Some of them, such as `Calories` or `Vitamin A`, are quite familiar. Others, such as `18:0`, probably don't interest you unless you're a scientist. Using nutrient lists, you decide which nutrients appear in your `nuts` reports, and the order in which they appear.

As the name suggests, a nutrient list includes multiple nutrients, in a specific order. Each nutrient is specified using both its name and its units: for example, `Protein` and `g`, or `Calories` and `kcal`. When Pantry prints a `nuts` report, it prints only the nutrients included in the nutrient list.

In addition, each nutrient in the nutrient list optionally has a goal associated with it. For exaample, if you wish to consume 2800 calories a day, you can set the goal for calories to 2800. If you do not specify a goal, but you include a nutrient in a nutrient list, `pantry` will still print the nutrient in `nuts` reports. If you don't want a nutrient shown in your `nuts` reports, then do not include the nutrient in your nutrient list. We are getting ahead of ourselves a bit, though. Later we will discuss how you can define your own nutrient lists. For now, though, you are stuck with the nutrient lists that are included with Pantry:

##### Nutrient lists included with Pantry

`facts`

  This nutrient list mimics the USA "Nutrition Facts" panel; that is, it shows nutrients in the same order as they appear on those labels, and the nutrient goals are identical to the FDA Daily Values. One of the nutrients that appears on the "Nutrition Facts" panel, `Sugars`, has no FDA Daily Value, so there is no goal for this nutrient.

`all`

  Shows every possible nutrient. It does not, however, include any nutrient goals.

`short`

  Shows only `Calories`, `Total Fat`, `Total Carbohydrate`, and `Protein`. As with `all`, this nutrient list does not include any nutrient goals.

`dv`

  Includes, in alphabetical order by nutrient name, every nutrient for which there is an FDA Daily Value; the goals are the respective Daily Values.

#### How nutrient lists are displayed in `nuts` reports

As you've seen, the `nuts` report has four columns. The first two columns show the nutrient name and the amount of the nutrient, respectively. The third column shows the nutrient's percentage of the any goal that has been set for this nutrient in the nutrient list. The fourth column shows this nutrient's percentage of the total amount of this nutrient for the buffer.

By default, Pantry uses the `facts` nutrient list. Therefore, in the next example, we see that 100 grams of bananas has 89 calories. The `facts` nutrient list has a goal of 2000 calories, the same amount used for the "Nutrition Facts" labels. Therefore, the report shows four percent in the third column. Other nutrients show similar results, except for `Sugars`. This shows `NG`, for No Goal. This is because although the "Nutrition Facts" panel shows `Sugars`, there is no FDA Daily Value for this nutrient. Accordingly, the `facts` nutrient list has no goal for this nutrient either.

Because there is only one food in the buffer, every value except one in the last column is 100 percent. The value for Cholesterol is `NA` because the buffer has no cholesterol.

##### The `facts` nutrient list with 100 grams of bananas

&example-nutsets-banana;

#### Using a different nutrient list

By default, Pantry uses the `facts` nutrient list when printing reports. You may specify a different nutrient list with the `--nutrient-list` option. In the next example, the third column always shows `NG` because the `short` nutrient list includes no goals.

##### Specifying a nutrient list

&example-specify-nutset;

### Using summary reports to see information about an entire buffer

So far, all the reports you have seen print one report for each food. For instance, the `names` report prints the name of each food in the buffer, and the `nuts` report prints one `nuts` report for each food in the buffer.

Sometimes you will want to know information about an entire buffer, rather than about each food in the buffer. Two reports provide information about the entire buffer: `sum` and `groups`.

#### Using the `sum` report

The `sum` report prints information about the sum of all nutrients of every food in the buffer. Like `nuts` reports, it uses nutrient lists to determine which nutrients appear in the report and which goals to use. It looks almost identical to the `nuts` report, with one difference: it has only three columns, rather than four. The first column shows the nutrient name; the second shows the nutrient amount; and the third shows the amount's percentage of a goal defined in the nutrient list.

As with the reports we discussed earlier, you may combine summary reports with other reports, as the next example demonstrates by combining a `traits` report and a `sum` report. When you combine summary reports and food reports, the summary reports are always shown last.

##### Using the `sum` report

&example-sum;

As with `nuts` reports, you use nutrient lists to determine which nutrients are shown in the `sum` report, and what the goals are.

##### Using the `--nutrient-list` option with the `sum` report

&example-sum-set;

#### Using the `groups` report

The other summary report is the `groups` report. It prints a list of all the groups in the buffer, the number of foods in each, and the total number of foods and groups. For instance, you can run the following example to see how many groupsa and foods are in the `master` file. Remember that if you do not specify any search options, `pantry` copies all foods from the files you specify into the buffer, which is why this example shows you all the groups in the `master` file.

##### How many groups are in the `master` file?

&example-groups-master;

### Saving new foods with `--add` and `--edit`; deleting with the `--delete` option

You'll probably want to store the new foods you make. You'll usually do this using the `--add` or `-a` option. This option takes a single FILENAME argument. FILENAME can be almost any name you want. For now, though, it should not end in `.xml`, `.zip`, or `.txt`--we'll learn about what these extensions do later. If FILENAME does not already exist, `pantry` will create it for you; if the file already exists, the foods in the buffer will be added to the file.

Two identical foods cannot exist in a single file. Two foods are identical if all their traits are identical. When you add a food to a file and there is already an identical food in the file, Pantry will alter the `comment` trait of the food you are adding by appending `(Copy 1)`, `(Copy 2)`, etc.

#### Using the --add option

&example-add-1; &example-add-2;

Another way to store the changes you make is by using the `--edit` option. `--edit` searches for foods and makes changes that you specify. Unlike `--add`, `--edit` does not add the changed foods to a new file; instead, it changes already existing foods, in the same file.

#### Using the --edit option

&example-edit-1; &example-edit-2;

Finally, you may delete foods from the original files with the `--delete` option.

#### Using the --delete option

&example-delete-1; &example-delete-2;

## Using Pantry: practical examples

Now that you know all the basic Pantry options, you're ready to combine them and put them to use! This chapter will show you how.

### Finding nutrient amounts

Often you will wish to know the nutrient makeup of a particular food. Suppose for example that you want to know how many calories are in a fresh apple. You figure that `master` already has such a food, but you don't know exactly what it would be. So first you search for `apple` to see what comes up.

#### Searching for apples

&example-apple;

It turns out that this search returns 163 results. There must be a way to narrow this down. Well, many foods will have the word "Apple" in their name, including many foods that are not even fruits (desserts, for example). A good way to narrow your results is to use the `--group` option:

#### Searching for apples, with the `--group` option

&example-apple-group;

That is still a lot more than we are looking for, including a bunch of things that merely have "Apple" in their name. What if we use a regular expression to limit the results only to foods whose `name` trait begins with `apple`?

#### Searching for apples using a regular expression

&example-apple-regexp;

That buffer is manageable enough to scan to see what we are looking for. Looks like `Apples, raw, with skin` is what we are looking for. We want to know how many calories are in an apple. To do that, first we need to see what units are available for `Apples, raw, with skin`:

#### Available units for an apple

&example-apple-units;

Notice how we combined the `names` and `units` reports rather than using just a `units` report. This is a good idea because otherwise, your report might actually contain results for more than one food, but you would not know this if you used only a `units` report.

Finally, we use the change options to take the apple from the `master` file, change it to the characteristics we're interested in, and print a report:

#### How many calories are in an apple?

&example-apple-calories;

### Keeping a food diary

Suppose that on May 8 you want to keep track of everything you eat. Following our previous example, you locate the foods you need in `master`, and then you add them to a file as you'll see in the following example. You print the traits of the foods as you add them to make sure that you're adding the right foods.

#### Adding entries to a diary

&example-diary-1; &example-diary-2; &example-diary-3; &example-diary-4; &example-diary-5; &example-diary-6; &example-diary-7; &example-diary-8; &example-diary-9;

Now you want to know a little about what you ate:

#### Printing nutrient reports about a diary

&example-diary-nuts;

You also want to know what all this adds up to:

#### Getting totals about a diary

&example-totals;

If your diary file contained foods for several days, you would have used `--date` to limit the search results to just today.

If this seemed to require a lot of typing, that's because it did require a lot of typing. Later we'll learn some ways you can speed this process up.

### Organizing your foods into files

#### A `quick` file

As you've seen from our numerous examples, sometimes the names of foods can get fairly long. Furthermore, because the good people at USDA are so industrious, a search for something seemingly simple in the `master` file can turn up numerous results. For instance, `pantry --ignore-case --name milk --group dairy --print names master` returns 64 foods. You probably don't want to type `Milk, reduced fat, fluid, 2&pct; milkfat, with added vitamin A` every time you have some milk.

One excellent solution for this problem is to keep copies of foods you eat frequently in a separate, smaller file--perhaps `quick`. If you know that there is only one food in your `quick` file that contains `milk`, you can just search for `pantry --ignore-case --name milk quick` instead. You can even change the names of foods using `--c-name`, so `Milk, reduced fat, 2&pct; milkfat, with added vitamin A` can become simply `Milk 2&pct;` if that's what you want.

To make this really easy, change the foods in your `quick` so that the quantity and unit traits are already set to those you use most frequently.

You could also make changes to the `master` file itself, but I prefer to leave this file untouched and store my frequently-eaten foods in a different file.

#### Organizing diary files

If you want to keep track of what you eat, Pantry is flexible in where you store the foods you eat. You can choose to keep all the foods you ever eat in a single file. However, to make any sense of such a file, you may find that you have to enter `date` and `meal` traits for every food you enter. As we've seen, that can require a lot of typing.

But remember, Pantry is flexible. You can instead decide to keep a separate file for each day, or a separate file for each meal. You can of course sort these into directories however you see fit. Remember that `pantry` is flexible and can search and print results from more than one file at a time.

Pantry's commands can get verbose, as you have seen. Therefore it can be quite helpful to devise scripts or shell functions of your own that will help you cut the amount of typing you must do. We'll see how to do that later.

## More Pantry usage

Now that you have seen some practical examples of how to use Pantry, there will be even more information that you will find useful in this chapter.

### Using the `--sort` option to sort foods within a report

As you have seen before, Pantry does not sort foods when it stores them. This allows Pantry to store and retrieve foods very quickly, but it also means that your foods come out in a big jumble:

#### Pantry does not sort foods

&example-foods-unsorted;

This is of course a bit hard to comprehend. Of course, I wouldn't be bringing this up if there weren't a solution at hand: the `--sort` option. Use it and Pantry will sort the buffer before it is printed. The `--sort` option takes a single argument to indicate how you want your foods sorted. This argument consists of a series of letters, with each letter being the first letter of the trait you wish to use as a sorting key. For example, to sort by `meal` and then by `name`, use `--sort mn`. Lower-case letters sort in ascending order, while upper-case letters sort in descending order. So, to sort the meal names in ascending order and then the food names in descending order, use `--sort mN`:

#### Using the `--sort` option

&example-using-sort;

Remember that all traits in Pantry are strings, including the `date` `pctRefuse`, and `qty` traits. These traits are sorted as strings rather than as numbers or as dates. This can lead to unexpected results. For example, sorting the strings `1`, `2`, and `10` will yield `1`, `10`, `2`.

Similarly, when sorting dates, `7-1`, `7-10`, and `7-2` will not yield the results you may expect. An easy fix for this is to use leading zeroes; sorting `07-01`, `07-02`, and `07-10` will do what you expect.

As you can see above, the `meal` traits are sorted in alphabetical order, yielding `Breakfast`, `Dinner`, and `Lunch`. You can, however, sort these into whatever order you wish, such as the more logical `Breakfast`, `Lunch`, and `Dinner`. We'll find out how to do this when we talk about configuring Pantry, later.

Finally, perhaps you want to be able to sort your foods into any arbitrary order. The `order` trait is useful for this purpose. To sort foods into any order, just assign appropriate `order` values for each food (perhaps `a`, `b`, `c` or `010`, `020`, and `030`) and then use `--sort o`. Pantry can even help you by assigning values to the `order` trait automatically, as we will see in the next section.

### More change options

#### Using the `--auto-order` option

Often you will find that you enter foods into Pantry in the same order in which you eat them. You might find it handy to have Pantry show those foods to you in the same order in which you entered them. The `--auto-order` option is handy for this.

When you add foods to a file and you have chosen the `--auto-order`, Pantry will automatically change the `order` trait of the added foods. To find what the new `order` trait should be, Pantry first searches the file that the food is being added to for other foods with values for the `date` and `meal` traits that are identical to the ones in the food that is being added. Pantry then sorts these foods in ascending order by their `order` trait.

Pantry then checks to see if the highest food's `order` trait matches the regular expression `^[0-9]{4}$`. Examples of values for which this would be true include `0010`, `2338`, and `0100`. Pantry then takes that value, removes any leading zeroes, removes the last digit, and increments the result by one. A trailing zero is added to the result, and the result is left-padded with zeroes if necessary in order to make it four digits. Thus, if the previously highest `order` trait was `0010`, the resulting `order` is `0020`. `2338` yields a new order of `2340`, and `0100` leads to `0110`.

If the highest food's `order` trait does not match the regular expression `^[0-9]{4}$`, then the new food's `order` trait is set to `0010`.

As always, an example helps. We'll use the same foods as we did in a previous example, but let's say you ate the exact same thing one day later:

##### Using --auto-order

&example-autoorder-1; &example-autoorder-2; &example-autoorder-3; &example-autoorder-4; &example-autoorder-5; &example-autoorder-6; &example-autoorder-7; &example-autoorder-8; &example-autoorder-9;

Now you can sort the foods by their `order` traits:

##### Using --sort with foods that have been automatically ordered

&example-autoorder-sorted;

The results are a bit different if we set only the `date` trait when we use `--auto-order`:

##### Using `--auto-order` with only the `date` trait changed

&example-autoorder-no-meal-1; &example-autoorder-no-meal-2; &example-autoorder-no-meal-3; &example-autoorder-no-meal-4; &example-autoorder-no-meal-5; &example-autoorder-no-meal-6; &example-autoorder-no-meal-7; &example-autoorder-no-meal-8; &example-autoorder-no-meal-9; &example-autoorder-no-meal-sorted;

You might complain that the previous examples took a lot of typing. We'll learn how you can cut down the amount of typing in a later section.

#### Changing food quantities by refuse amount

Internally, Pantry's nutrient amounts are recorded as amount of nutrient for a given amount of edible food. More specifically, Pantry tracks each of its foods by recording the amount of each nutrient per 100 grams of edible food. How Pantry converts from nutrient per 100 grams of edible food to the total amount of nutrient in your foods varies depending upon the unit of your food.

The units `g`, `oz`, and `lb` are available for every food. For foods using one of these available units, it is simple for Pantry to convert from nutrients per 100 grams to nutrients per ounce or nutrients per pound.

Any of a food's other avaialble units are recorded in Pantry with their total grams of edible portion. Pantry then uses this gram weight and the amount of nutrient per 100 grams of edible portion to compute the total nutrients in your food.

An example will prove helpful. Let' take some apples:

##### Traits and available units for an apple

&example-traits-apple;

By now this looks familiar to you. This way, if you eat a large apple, you change the unit of the food to `large (3-1/4" dia) (approx 2 per lb)`. Pantry knows how many grams a large apple weighs. To find out how many grams correspond to each unit, use the `measures` report, which shows the weight in grams of each measure:

##### Using the `measures` report

&example-measures;

The weights in grams correspond to the edible portion of the food. Thus, in this example, a typical large apple weighs 212 grams, without the inedible portions (such as the core).

But perhaps you eat an apple and you want to use the `g`, `oz`, or `lb` unit. This is especially likely if, for example, you have a kitchen scale and you wish to precisely measure the amount of all the food you eat. If you wish to weigh your own apples rather than using the approximations given in the available units, you have a few options.

One option is to simply cut up the apple, cut out the core, and then weigh the resulting chunks. That is fine if you usually cut up your apples (as I do) but not so good if you do not want to chop up your apples all the time.

Another option is to weigh the entire apple, whole, and record that you ate (for example) a seven-ounce apple. The only problem with this is that the nutrient amounts in Pantry are for the edible portion of the food. Thus, if you do not account for the fact that a fraction of the apple is a core and a stem, you will overestimate how much apple you ate. To which you might say: "big deal! It's just an apple core." The problem is minor with an apple, but consider the same issue with an ear of corn on the cob, or a pork sparerib...

To compensate for this, you could weigh the entire apple, eat it, and then weigh the leftover core and stem. You would subtract the weight of the core and stem from the weight of the entire apple, and then figure that you ate the difference. That would get tedious.

A third option is to use the `--refuse` option. It uses the `refuse` trait to reduce your food's quantity by the percentage of refuse. As you saw in the example above, an apple is 8 percent refuse. So, assuming you have an eight-ounce apple: Nowadays I frequently see single apples that weigh nearly a pound!

##### Using the `--refuse` option

&example-refuse;

As you can see, the `--refuse` option reduces the quantity of the apple by eight percent. This way, you can weigh the entire apple (including the core) and still get a good estimate of which portion of the apple was actually edible.

It only makes sense to use the `--refuse` option when you are using the `g`, `oz`, or `lb` units. Every other unit in the `master` file already accounts for refuse--for example, with the apple, the `large (3-1/4" dia) (approx 2 per lb)` already accounts for the eight percent refuse.

When using the `--refuse` option, every food in the buffer will have its quantity reduced by its corresponding refuse percentage. This of course does not affect foods with zero percent refuse or foods whose `pctRefuse` trait is empty.

### 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 `pantryrc`, so start by including that in your `.pantryrc.xml`:

#### Beginning a `.pantryrc.xml` file

&file-blank-pantryrc;

#### 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`:

##### Showing all available nutrients

&example-nutset-all;

##### 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:

###### `.pantryrc.xml` with new nutrient list

&file-pantryrc-nutset;

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

###### Using a new nutrient list

&example-using-new-nutset;

#### 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. This sorts traits in their lexical 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 lexical 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.

##### `.pantryrc.xml` with `sort-order` element

&file-pantryrc-sort-order;

### Changing food quantities by nutrient amount

`pantry` features a `--by-nut` change option that will automatically change the quantity of a food so that it has a particular amount of a certain nutrient that you specify. This feature shamelessly copied from a similar feature in NUT, as described under "Foods That Are Not in the Database" on How I Use NUT.

The `--by-nut` option takes two arguments. The first argument is a regular expression to match the nutrient you wish to use. The second argument is the amount of that nutrient that you wish the food to be set to. Let us look at an example:

#### Using the `--by-nut` option

&example-by-nut;

As you can see, Pantry automatically changed the quantity of apples so that you would have 200 calories of apple. This works with any nutrient:

#### Using `--by-nut` with Total Fat

&example-by-nut-fat;

That gave us the right number of grams of avocado that contain 5 grams of fat. The `--by-nut` also works with the `--c-unit` option. For example, here is how you can find out what fraction of an avocado you would need to eat in order to consume 5 grams of fat:

#### Using `--by-nut` with `--c-unit`

&example-by-nut-unit;

The `--by-nut` option is useful in at least two circumstances. First, as we have already seen, it is useful if you are wondering how much of a food you need to consume in order to get a certain amount of a given nutrient. Second, it is useful if you wish to approximate intake of a food that is not already in the `master` file. For example, suppose I eat 1/2 of a cup of Stonyfield After Dark Chocolate ice cream.. Many brand-name foods are already in the `master` file, but this one is not. I look through the ice creams and find that the closest thing to Stonyfield in the `master` file is probably `Ice creams, chocolate, rich`:

#### The closest thing to Stonyfield

&example-ice-cream-rich;

But Stonyfield apparently is even richer than this. 1/2 cup of `Ice creams, chocolate, rich` has 189 calories, but looking at the Stonyfield label tells me that 1/2 cup of Stonyfield has 250 calories. What should I do? Well, as we will learn in a later chapter, I can create a custom food for Stonyfield After Dark Chocolate ice cream. Or I might figure that `Ice creams, chocolate, rich` is close enough for our purposes. I can use it instead. My results will not be as accurate, but perhaps I am not feeling the need to be super accurate today. Because I know I ate 250 calories of Stonyfield, I just do this:

#### Approximating one food by using another food and the `--by-nut` option

&example-by-nut-stonyfield;

If you compare Pantry's output to the Stonyfield label (available at the website) you will see that Pantry comes out fairly close to what is on the label.

The first argument--the nutrient name--is a regular expression. That means that it is case-sensitive, like all other regular expressions in Pantry, unless you use the `--ignore-case` option. Thus, `--by-nut calories 250` will get you an error message unless you use `--ignore-case` but `--by-nut Calories 250` will always work. This also allows you to shorten things a bit--for example, you can use `--by-nut Saturated 250` to match Saturated Fat. In addition, the `--by-nut` also respects the `--exact-match` option, so if you are using `--exact-match`, then the first argument to `--by-nut` are not regular expressions and must exactly match the nutrient name.

Most commonly you would find yourself using `--by-nut` with Calories. Therefore, `pantry` has a `--by-cal` option. It is equivalent to typing `--by-nut Calories`:

#### Using the `--by-cal` option

&example-calories-option;

### Pantry usage shortcuts

#### Using short options

For didactic purposes, all the examples in this manual use long-style options with two dashes. However, almost every `pantry` option is also available in short form. The search options (which search for a particular trait) and the change options (which change the traits of the foods in your result to a new value) have short options that conveniently differ only by their case. Thus, for example, `-g` searches by group name, and `-G` changes the group name.

If you need to jog your memory on what option does what, use the `--help` option. This option will also tell you which long options have corresponding short options.

In addition, when specifying reports, you may specify only the first few letters of the report name--enough letters to unambiguously specify the report name. For example, instead of typing `--print names-nuts`, you may instead type `--print na-nu`.

#### Learn your shell, and write scripts or functions to automate common tasks

As you have seen, `pantry` commands can get lengthy. That's one of the pitfalls of a command-line program. However, one of the great strengths of a command-line program is that you can easily write your own shell scripts or functions to automate commands you type frequently. In addition, shells have a wealth of features, such as history searching and command-line editing, that will speed up your shell usage. This will help you not only in Pantry but in other command-line tools as well. Pantry used to include a script called `pantry-addTo` that helps cut typing. However, in release 18 I removed it from Pantry. `pantry-addTo` was difficult to document because it is a personal hack that does not nearly conform to any interface standards. Personal hacks are wonderful for personal use, but they shouldn't be distributed for others. Thus, feel free to write your own personal hacks that will work perfectly for you.

If you will use Pantry frequently, one of the things you will find most helpful is to write a script or function that will add new foods to a diary file. Such a script can, for example, automatically use the `--c-date` option to change the food so that it has today's date, or automatically use the `--c-meal` option. You might also write scripts or functions to easily produce reports using the `--print` options you use most frequently.

The most popular shell today is bash, which is very featureful. If you have never written a shell script or function before, take a look at the Bash Guide for Beginners.

You may also wish to consider using a shell other than Bash. For a very well-documented shell that is easier to learn than bash, consider fish, the Friendly Interactive Shell. For a very powerful shell with excellent documentation, try zsh.

If you need some inspiration, you'll find the shell functions I use in the `examples/zsh-functions` file in the Pantry distribution, along with some (hopefully) helpful comments.

Finally, whether you use Bash or Zsh, I highly recommend getting a copy of From Bash to Z Shell: Conquering the Command Line by Kiddle, Peek, and Stephenson. It clearly explains many of the features of shells, such as command history and completion, that make interactive use much easier and faster. Unlike most texts on shells, this one focuses on interactive use. It is well worth the price.

#### Learn other Unix utilities

Because you use Pantry from your standard command shell, you can easily combine Pantry with other Unix utilities, in ways that even I cannot anticipate. Most obviously, you will often use Pantry with `less` so that you may easily scroll through reports. You might also find yourself using `sort`, `cut` or even `awk`. The possibilities are endless.

### Using Pantry with screen

Though Pantry may be used in conjunction with many other Unix shell utitlities, you may find GNU Screen to be particularly useful. `screen` is so useful with Pantry due to its advanced cutting-and-pasting capabilities. Here is a good introduction to `screen`. Most Linux systems will already have `screen` installed; if not, you'll be able to install it using your distribution's package manager.

Pantry includes the `paste` report, which makes `screen` particularly useful. Often in Pantry, you will be searching your `master` file, not entirely sure what food you are looking for. On other occasions, you will know what you are looking for, but your search terms return a lot of results to scroll through--and the food that you want has a very long name that you do not want to have to retype. Using the `paste` report, you can easily reuse your search results.

The `paste` report prints one line for each available unit for each food. The results include the `-x`, `-n`, and `-U` options, and the results are also quoted so you may easily paste them into a subsequent `pantry` command. Actually, the results are quoted so they may be pasted into shells that have Bourne-like syntax, such as bash, zsh, and fish. I don't know enough about csh-like shells to know if the `paste` report works with them.

To see how powerful this is, we can return to our earlier example of finding how many calories are in an apple. You would likely start by searching the `master` file for the name trait `apple`. As we saw earlier, this returns 163 results:

#### Searching for `apple` returns 163 results

&example-apple;

Earlier we limited our search results by typing subsequent `pantry` commands and tweaking the `--name` argument. When we zeroed in on the food we wanted, we typed yet another `pantry` command, this time to figure out the available units. Finally, we typed another `pantry` command to change the unit and quantity to what we wanted and to print the nutrient information for a single large apple.

You can do this using many fewer commands with `screen` and the `paste` report. After firing up `screen`, type a `pantry` command for what you are looking for.

#### Using the `paste` report

&example-paste-report;

Now you can scroll through the results using Screen's commands; copy the line you are interested in to Screen's paste buffer. For more details on how to do this, consult the Screen manual page under "copy". Pay particular attention to the J command, which joins lines--this is useful if a particular line is so long that it does not fit on one line in your terminal. You don't have to use `screen`; you can copy and paste using your terminal emulator if you wish. Though I think `screen` is easier to use, you might diasgree...

After finding the result you are interested in, you can easily paste it in to a new command line and add the options you need.

### Multilingual Pantry

Pantry should work just fine with non-ASCII characters, such as those with accents, Cyrillic characters, and so forth. Of course, figuring out how to get your terminal to produce these characters is up to you. Internally, Pantry works with Unicode characters and encodes them when appropriate using your system's default encoding; Pantry assumes that all input from your terminal is encoded using your system's default encoding. It is difficult to test all possibilities though, so if you encounter any bugs in this area please let me know.

## Adding new foods and editing the nutrients or units of existing foods

The `master` file comes with over 7,000 foods. However, you might find that you also need to add additional foods to Pantry. This chapter will tell you how to add additional foods by creating an XML file.

If you have a prepackaged food that already has a nutrition label, you can easily add it to a file. If however you have multiple foods that you wish to combine, then what you want is a recipe. We will discuss recipes in the next chapter.

As you may recall from our earlier discussions, an essential element of Pantry is the food. Foods are contained in food files. There are several different kinds of food files. Until now, all the food files we have used have been Pantry native files. You have been able to copy foods from one Pantry native file, such as the `master` file, and change the traits of those foods. To create entirely new foods, you will create a different type of food file, which we will call a Pantry XML file. Unlike a Pantry native file, the Pantry XML file is in human-readable, plain-text XML, which allows you to create new foods.

This chapter will lead you through how to create your own foods, step by step. If you're the impatient sort who would rather learn by seeing some examples, consult the `examples` directory in the Pantry distribution.

### Creating a new food

#### Create a new blank XML file

In your favorite text editor, create a new file whose name ends with `.xml`. As an example, we will create a file named `foods.xml`.

The root element of a Pantry XML file is a `pantry` element, so to get started create that element.

##### `foods.xml` file with blank `pantry` element

&file-blank-foods-file;

#### Create a `food` element

Each food you create in the `foods.xml` file is contained within a `food` element. The `food` element has several attributes. Each corresponds to the various food traits that we've discussed earlier: `name`, `group`, `date`, `meal`, `unit`, `qty`, and `comment`, `refDesc`, and `pctRefuse`. Only the `unit` and `qty` attributes are required. The `unit` attribute may contain `g`, `oz`, or `lb`, or it may contain one of the units given in the `units` element, which we will discuss shortly. The `qty` and `pctRefuse` attributes may contain a number, a fraction, or a mixed number.

Attributes other than `qty` and `unit` are optional. If you don't have any values for them, just leave the attributes out altogether. Typically you will set the `name` and `group` to something useful while leaving many of the others out. If you set the `pctRefuse` trait, remember that you are setting percentages--that is, to indicate that your food is 15 percent refuse, set this attribute equal to `"15"`.

Typically you will be getting your nutrition information from food labels. Usually these will indicate a serving size, as well as a serving in grams. You will set the `unit` and `qty` traits to match what is given on the food label. As an example, we will use a Clif Bar. You may find it helpful to follow along with its nutrition label, which you can find here. Use of the Clif Bar in this example wholeheartedly implies my endorsement of Clif Bars. They are handy, tasty snacks.

Its label shows a serving size of 1 bar. So, we enter the following text into our `foods.xml` to start:

##### `foods.xml` with `food` element

&file-food-element;

#### Create `nutrients` elements

Next, you will create nutrients for your food. You define each nutrient by creating a `nutrient` element. Each `nutrient` element has three required attributes.

The `name` attribute to the `nutrient` element gives the name of the nutrient, such as `Calories` or `Iron`. These names must correspond to one of the nutrients that is allowed in Pantry; to get a list of the allowed nutrients, run `pantry --nutrient-list all --print list`. The names are case sensitive, so although `Saturated Fat` is a valid nutrient, `Saturated fat` is not a valid nutrient.

The `amount` attribute to the `nutrient` element is a number indicating the amount of the corresponding nutrient. This can be an integer, floating-point number, a fraction, or a mixed number.

The third attribute to the `nutrient` element is `units`. Set this equal to the units for the nutrient--e.g. `g` or `mg`. For calories, use `kcal`. The value for `units` must match the units given for the nutrient in the table you see when you run `pantry --print list --nutrient-list all`.

For some nutrients, you may set the `units` attribute to `&pct;`. Setting this attribute to `&pct;` indicates that the `amount` attribute is a percentage of an FDA Daily Value. Pantry will convert the `amount` attribute to an appropriate amount. This is useful because vitamins and minerals are listed on food labels by percent of daily value, rather than by amount. You may only use `&pct;` for nutrients for which there is a Daily Value. To get a list of all nutrients that have a Daily Value, run `pantry --print list --nutrient-list dv`.

To continue with our Clif Bar example, here is the Clif Bar with its nutrient information. Because I am lazy, I did not enter all the nutrition information; instead, I just entered all the macronutrients and four of the vitamins and minerals.

##### Food with `nutrients` element

&file-nutrients-elements;

#### Creating `unit` elements

Finally, it is time to enter units for the food, which you do using the `unit` element. These elements map common units of measure to a food's weight in grams, and they correspond to to the available units that we discussed earlier. Thus, each `unit` element has two attributes. `name` corresponds to the name of the unit, such as `cup` or `stick` or `box`--whatever is appropriate. The `grams` attribute corresponds to whatever the weight of a single `name` is, in grams.

As always, Pantry will provide the units `g`, `oz`, and `lb` for you, so do not enter those in `unit` elements. However, if you entered anything other than `g`, `oz`, or `lb` for the `unit` attribute of the `food` element, you must define a corresponding `unit` element. Thus, because the `unit` attribute for our Clif Bar is `bar`, we must define a corresponding `unit` element. With that, we have a complete `food` element.

##### Complete `foods.xml` file.

&file-complete-foods-xml;

### Using a Pantry XML file

You can use Pantry XML files, such as the `foods.xml` file we have created in this example, just as you would use a Pantry native file (the format used by the `master` file.) For example:

#### Use a Pantry XML file as you would use a Pantry native file

&example-foods-xml-compatible;

However, I recommend adding the foods to a Pantry native file, because you will find it most convenient if the foods you create are mingled with the other foods you use, either in the `master` file or in a `quick` file, as we discussed earlier. In addition, Pantry XML files are slower to process than Pantry native files. If a Pantry XML file contains just a few foods, the difference is not noticeable. However, for more than several dozen foods, the speed difference might begin to add up. That is one reason why Pantry does not use XML as its native file format.

For example, to add the Clif Bar to my `master` file, I simply run `pantry --add master foods.xml`.

#### Pantry destroys data in Pantry XML files!

You may insert comments into your XML file, using XML-standard comments (that is, <!-- like this -->). In addition, you will probably format your XML in a certain way by using tabs and newlines. However, if you make changes to the XML file using `--add`, `--edit`, or `--delete`, Pantry will destroy this formatting and lose the comments. You will also find that, if you use `--add`, `--edit`, or `--delete`, Pantry will rearrange the order of the foods in your XML file and will even rearrange the order of the attributes.

For the time being, I considered fixing this problem, but the technical hurdles are significant, so it is not likely to be fixed soon, if ever.

one solution to this is to use only the `comment` attribute if you wish to comment on foods. Also, you can simply refrain from making changes to the file using Pantry; Pantry will not destroy data in XML files if it only reading data from them.

### Using Pantry XML files to edit units or nutrients of foods

As you already know, you can easily edit the traits of foods in Pantry. But what if you want to edit the nutrients or available units of a food? As you can probably guess now, the solution is to use a Pantry XML file. Pantry XML files behave just like Pantry native files. So if, for example, you wish to edit foods in the `master` file, you can simply create a Pantry XML file with the foods you wish to edit. Pantry automatically creates a Pantry XML file if you use the extension `.xml`. So, to create a Pantry XML file with bananas, use `pantry --add banana.xml --name 'Bananas, raw' master`. You can then edit this food however you wish, and you can then add the results back to the `master` file using the `--add` option.

Remember that Pantry will not allow you to have two identical foods in a single file. Two foods are considered identical if their traits are identical, even if their nutrients or their available units differ. If foods are identical, Pantry will simply add `(Copy x)` to the food's `Comment` trait. Keep this in mind if, for example, you edit the banana in the `banana.xml` file and then add it back to the `master` file.

### Validation of Pantry XML files

Pantry automatically validates Pantry XML files for you. If your system has `xmllint` installed, that is what Pantry will use to validate files. If not, then Pantry will use a validator written in Python, which is slower but gets the job done. For best performance, ensure that your system has `xmllint` installed. Typically `xmllint` is part of the libxml2 package if you are using Linux.

To see the DTD that Pantry uses for this purpose, run `pantry --dump pantryDTD`. You might, for instance, want to use this DTD to validate the XML yourself.

If any of your files do not validate, Pantry will print an error message along with the output of the validator. Study the output of the validator because it will usually help you fix the error.

The validator will often hang if the input file is very large. Therefore, Pantry will only validate files if they are below 300 kilobytes in size. It is unlikely that you will ever create XML files that large by hand, although you might have Pantry create an XML file that large (that's what you will get if you run, for example, `pantry --add pantry.xml master`). Pantry will give you an error message if you try to use a file that large. One way to use large files is to use the `--skip-valid`, which will turn off validation. This is of course a bad idea for files that you have edited by hand (because they might have errors that then will go unchecked) but skipping validation is fine for large files that were generated entirely by Pantry. Alternatively, you can use `--force-valid` to make Pantry validate all XML files, regardless of how large they are. This might cause Pantry to wait for an extremely long time for the validator to finish--the validator might even freeze if the file is extremely large.

## Plain text Foods files, and choosing which type of Foods file to use

So far, all the files that we have worked with have either been binary files The distinction between binary files and plain-text files is quite arbitrary. It is fair to say that there is no such thing as plain text. But for our purposes we will call anything that you usually edit in a text editor "plain text".

or XML files. Pantry can also store foods in a more traditionally Unix plain text format--that is, in a text file with each row representing a single food and each column representing something about that food. In this chapter you'll learn about the advantages and disadvantages of this file format and how you can use it.

### How Foods Text files work

As you know, a food in Pantry consists of traits, nutrients, and available units. That's a lot of data. The two file formats we have seen so far--the Pantry native file and the Pantry XML file--both contain all of this data for each and every food. The Pantry native file is fast, but you can't edit that with your text editor at all. The Pantry XML file can be edited with your text editor, but the format is so verbose that you don't ordinarily want to touch it unless you have to--if, for example, you are creating an entirely new food.

The Foods Text file is a little different from the Pantry XML and Pantry native files because it does not contain all the data for each and every food. Instead, it relies upon another Pantry XML or Pantry native file to contain all the food data. In the Foods Text file, each line corresponds to a particular food. Each line specifies a source file for the food. The source file will be a Pantry XML or Pantry native file that will contain the nutrient and unit data for the food.

Pantry must look up the food in the source file. To do this, Pantry uses the food's name. There must be exactly one match for the food name that you specify; therefore, you will find Foods Text files to be easiest to use if you have source files in which every food name is unique. The `master` file meets this criterion; you might also set up a `quick` file that also meets this criterion.

This will all get more clear with examples:

### Foods Text files: an example

Here is an example Foods Text file:

#### A sample Foods Text file

&file-foods-text;

The first thing to notice is that you can begin comments anywhere on a line with a hash mark, `#`. Pantry ignores any text after the comment symbol. Here, the first two lines are handy reminders of the syntax of the Foods Text file.

Colons separate the fields in the Foods Text file. If you need to include a colon or a hash mark in a field, you can precede it with a backslash, `\`. To include a backslash, precede it with a backslash. A single backslash followed by any character other than a backslash, colon, or hash mark generates an error.

Here is what appears in each column of the Foods Text file:

#### Columns in the Foods Text file

Column
Contents
1
The source file; that is, the filename of the file holding the food that contains the nutrient and unit data for this food. It is best to include a full, absolute path specification here. You can use a relative path, but it will be resolved relative to the working directory of the `pantry` command when you invoke it, not relative to the directory of the text data file. This is confusing, which is why I recommend including an absolute path specification.
2
The name of the food. Pantry uses this to look up a food in the source file, which then serves as the basis for this food. This is a regular expression, unless `x` is specified in the `options` column. The search is case-sensitive unless `i` is specified in the `options` column. After looking up the food using the contents of this column and the `source` column, Pantry changes the traits of the food according to the following columns.
3
The quantity for the food.
4
The unit for the new food. The unit is selected from the food's available units. The value in this column is a regular expression, unless `x` is specified in the `options` column, and the search is case sensitive unless `i` is specified in the `options` column.
5
The `date` trait for the new food.
6
The `meal` trait for the new food.
7
The `group` trait for the new food.
8
The `comment` trait for the new food.
9
These are search options. This column may have zero, one, or two letters. `x` specifies that the search for the food name and for the unit must be an exact match, rather than a regular expression. `i` makes searches case insensitive.

If you only need to use some of the columns, you can leave out trailing columns. The only columns that you must specify are the first two, for the source and the food name.

You may have noticed that there is a column to set most of the food's traits, but there is no column to set the food's `order` trait. This is because Pantry automatically sets the food's `order` trait so that it is equal to the line number of the food in the file, although it is left-padded with zeroes so that it will equal four digits.

### Using Foods Text files

After you have completed your Foods Text file, you can use it just as you would any other Pantry file. Here is an example:

#### Using a Foods Text file

&example-using-foods-text;

The nice thing about Foods Text files is that although you can edit them with your text editor, you can also manipulate them using ordinary Pantry commands. For example:

#### Changing a Foods Text file

&example-changing-foods-text-1; &example-changing-foods-text-2;

As you can see, when you add foods to a Foods Text file using `pantry`, appropriate text is added to the end of the file. However, beware that if you change the name of the food using the `--c-name` option, Pantry will not be able to locate the food in the source file. You can, however, change any of the other traits, although Pantry will override any changes you make to the `order` trait because the `order` trait is automatically set to the line number of the food. Thus the `--auto-order` option has no effect when using Foods Text files.

### Which sort of file should I use?

Thus, there are three different file formats that do similar things: keep Pantry foods. You might be wondering which one you should use.

Each file format has advantages and disadvantages. The Pantry native file is the fastest one for Pantry to work with, but it cannot be edited with a text editor. The Pantry XML file is plain-text, but Pantry takes some time to open it and to write changes to it because it is XML. The Foods Text file is also plain-text, and very easy to edit, but it does not hold all the data needed for a food and so it must rely on source files.

I find it best to use a Foods Text file for my diaries. It is remarkably easy to edit, which makes it easy to fix mistakes. It's also easiest to reorder foods in a Foods Text file; then I can easily sort the reports using the `--sort o` option. It's also possible to assign the order trait to foods in other files using the `--c-order` option, but that is more cumbersome.

For files that will contain many foods, such as a `master` file, I use a Pantry native file because it is the speediest. Of course, when adding entirely new foods with new nutrient information, my only choice is to use a Pantry XML file. I have considered making a way to add entirely new foods using the Pantry command-line interface, but I don't see how much of a benefit this would be. I otherwise avoid Pantry XML files because XML is a bit cumbersome to edit.

I also keep a `quick` file for easy access to the foods I use often. I keep this in a Pantry native file, but if your `quick` file is relatively short (under a couple of hundred foods, say) there's no reason not to use a Foods Text file for this (except for the fact that you'll have to make sure it stays harmonized with the source file--that is, you have to ensure that the foods that the Foods Text file looks up in the source file remain in the source file.) Here is as good a place as any to point out that there is yet another Pantry file format: the Foods Zip file. This is what I use to import the SR data from the Zip file that USDA provides. If you are curious, you can download the full plain-text version and run something like `pantry --add master sr19.zip` to make your very own `master` file. I can't guarantee that this will work with any releases subsequent to SR 19, and it takes lots of RAM too (about 200 MB, maybe.)

## Adding recipes

So far, you know how to add your own foods to Pantry. However, to add a food, you have to know what its nutrient content is. If you have a food that is a mixture of several different foods, then making a recipe can help. You'll learn how to do that in this chapter.

This chapter will lead you through how to create your own recipes. If you would rather jump right into an example, you can try consulting the `examples` directory in the Pantry distribution, which has some example files.

### When to use recipes

The basic building block of Pantry is the food. Each food has traits, nutrient content, and available units. In Pantry, you can combine several foods into one single food using recipes. Thus, for example, you can combine corn meal, flour, water, baking powder, sugar, salt, and eggs using a recipe. The result will be a single food that you can call corn bread. This new food will have traits, available units, and nutrients, just like any other food in Pantry.

Sometimes using a recipe is overkill. For example, say you have a few foods that you always eat together in a certain quantity. It can be much quicker and easier to simply give these foods a common group trait. For example, I often eat two ounces of cold cereal with one cup of milk. I could create a recipe for these foods. Instead, I have simply added both of these foods to my `quick` file, and I have changed the `group` trait of both foods to `Cereal and Milk`. Then, when I want to record in my diary that I have eaten these two foods, I simply issue `pantry --group 'Cereal and Milk' --add diary.txt quick`.

Thus you will find recipes most useful in two instances. First, recipes are handy if you have several foods that you wish to combine into one food. Then the nutrient breakdown of all the foods will appear together in your reports. Second, you have to use recipes if you wish take several foods, combine them, and subdivide the results. For example, if I wanted to eat an entire 9x9-inch dish of corn bread, perhaps I could treat corn bread in Pantry the same way I record my cereal and milk. However, because I want to divide the corn bread into multiple portions and eat them separately, I must use a recipe.

### Creating a recipe

Just like when you add new foods, you can write recipes in Pantry by using the Pantry XML file. While you enter foods in Pantry XML files by using the `foods` element, to enter recipes you use the `recipe` element.

#### Creating a recipes file and a `recipe` element

To create a Pantry XML file, start your favorite text editor and open a text file. For the purposes of our example we'll use `recipes.xml`, though you can create any filename that ends with `.xml`.

As we saw earlier when we created new foods, the root element of a Pantry XML file is `pantry`. Each recipe is contained in a `recipe` element. The `recipe` element thas the same attributes as the `food` element that we learned about earlier: `name`, `group`, `refuse`, `refDesc`, `date`, `meal`, `qty`, `comment`, and `unit`.

Of all these attributes, you are required to set only the `unit` and `qty` attributes. You can leave as many of the other ones out as you wish, though ordinarily you will set the `name` and `group` attributes while leaving many of the others blank.

Just like when you create a new food using the `food` element, you must set the `unit` attribute to one of the available units for the recipe. Pantry will automatically create the `g`, `oz`, and `lb` units for you. You can also have Pantry create a `serving` unit, as we will discuss shortly.

For our example, we will create a recipe with the name `Omari's Chili`. As you will see, the new recipe has its unit set to `serving`; shortly we will see exactly how this works. You will also notice that many of the attributes for the various traits, such as `date` and `meal`, are not set at all; Pantry will set such traits to the empty string.

##### Creating the `recipe` element

&file-empty-recipe;

#### Setting the yield of a recipe

Next you will need to set the yield of your recipe. You do this by setting three additional attributes on the `recipe` element: `yieldGrams`, `yieldDesc`, and `servings`. The `servings` attribute is easiest to understand, so we will discuss it first.

##### The `servings` attribute

Often when you make a recipe, you split it into an even number of servings. If that is the case for your recipe, you may enter an appropriate value for the `servings` attribute. Pantry will automatically create a `serving` available unit for the food in this case. If you do not wish to specify a number of servings, you can simply not use the `servings` attribute at all.

For our chili example, we will say that the recipe makes six servings.

##### The `yieldGrams` attribute

In order for Pantry to accurately calculate the nutrient content of a particular amount of food, it needs to know what the total mass of your completed recipe is, after it has been fully prepared (that is, after cooking, baking, mixing, etc., as the case may be.)

Pantry can "guess" what the total mass of your completed recipe is. Pantry guesses by adding up the mass of all the ingredients you entered for the recipe. To have Pantry guess for you, leave the `yieldGrams` attribute out entirely. However, you will often find that the completed recipe weighs significantly less than the mass of all the ingredients. This is because a lot of water often evaporates as you cook or bake foods. Thus, for the most accurate results, you may enter the mass of your completed recipe so that Pantry may take it into account. To do this, enter the appropriate value (in grams) for the `yieldGrams` attribute.

However, if you have entered a `servings` attribute, and you will use only the `serving` available unit when you use the recipe, then entering a `yieldGrams` attribute will do you no good. This is because Pantry will calculate each serving so that it is the appropriate fraction of the total, but the actual total mass will not matter.

I've weighed a completed batch of chili, so I enter an appropriate amount for the `yieldGrams` attribute.

##### The `yieldDesc` attribute

Finally, you may enter any text you wish for the `yieldDesc` attribute. This text can be used to describe the yield of the recipe. I'll enter appropriate text for our chili example.

##### A complete `recipe` element

Here is an example `recipe` element:

###### Setting the recipe yield

&file-recipe-yield;

#### Setting the ingredients of a recipe

No recipe is complete without ingredients. Each single ingredient is represented by a `ingredient` element. The `ingredient` element has four attributes: `name`, `qty`, `unit`, `comment`, and `file`.

As you will recall, each ingredient in a Pantry recipe is a another Pantry food. These foods come from another Pantry file. For each ingredient, you will specify the source file by specifying the path to the file in the `file` attribute. It is best to use a full, absolute path specification here. If you use a relative path specification, it will be resolved relative to the working directory of the `pantry` command when it is run, not the directory of the XML file. This is confusing, which is why I recommend using an absolute path specification.

For each ingredient, Pantry will look in the file specified for the food you specify using the `name` attribute. Unlike much of the rest of Pantry, the text of the `name` attribute is not a regular expression. Instead, you must exactly match every space, and you must exactly match the mixture of upper- and lower-case letters, as well.

The `qty` attribute is simply the quantity of the ingredient. As with most other numeric values in Pantry, you may use an integer, a floating-point number, a fraction, or even a mixed number.

The `unit` attribute is an exact match of the available unit you wish to use for this ingredient. As with the `name` attribute, this is case-sensitive.

Finally, the last attribute, `comment`, is optional. This can be whatever helpful text you may wish to enter.

Here is our chili example, complete with all its ingredients.

##### A recipe with its `ingredients`

&file-recipe-ingredients;

#### Setting the available units for a recipe

Finally, you may create additional available units for the food. Pantry automatically creates the `g`, `oz`, and `lb` units for you; in addition, if you specified a `servings` attribute to the `yield` element, as we discussed above, then Pantry will also automatically create a `serving` available unit. If you wish to create any additional available units, you will need to know the weight (in grams) of that unit. If for instance you are entering a recipe for cookies and you want to create an avaiable unit for one cookie, you'll need to know the weight in grams of one cookie.

To create available units, create one or more `unit` elements. Each `unit` element will have both `name` and `grams` attributes. Here I have weighed a single cup of chili so I enter an appropriate amount.

##### A recipe's units

&file-recipes-units;

#### Directions for a recipe

Finally, you need something to tell you how to put together all those ingredients. You can do this by including an optional `directions` element. Enclose each paragraph of your directions inside a `p` element. Eventually I will probably add additional formatting tags, such as `b` and `i`, but for now you're stuck with just `p`.

##### Recipe directions

&file-recipes-directions;

### Using recipes

You can use a Pantry XML file that contains recipes just as you would use any Pantry file. As we discussed earlier when we talked about creating foods, I would recommend adding the contents of a Pantry XML file to a Pantry native file, because Pantry works with native files much faster than it works with XML files.

#### Using a Pantry XML file

&example-using-recipe-xml;

#### Adding a recipe to a Pantry native file

&example-add-recipe-native-1; &example-add-recipe-native-2;

Now that you know how to create recipes, you will find that there are several additional reports that will come in handy when you are using the `--print` option. You can use all the reports you have already learned about; they work identically with both regular foods and with recipes. The most handy additional report is the `recipe` report. It gives you a plain-text representation of a recipe, along with some additional handy information such as the weight of each ingredient:

#### The `recipe` report

&example-recipe-report;

You can get the same information by using `--print names-yield-blank-ingredients-blank-directions`, but `--print recipe` is a bit shorter to type. You can use the other reports, such as `ingredients`, if you're only interested in a subset of the information. Of course, you can combine the `recipe` report with other Pantry reports. You can also use handy utilities such as `fold`, which should already be installed if you are using a GNU operating system. Non-GNU UNIX systems will likely have a `fold` utility installed, but it might not have handy options such as `--spaces`. Windows won't have `fold` at all.

This gives you nice printer-ready output that you can feed to `lp`:

#### Using the `recipe` report with other cool stuff

&example-recipe-report-combined;

Now that you know how to create both foods and recipes, you can create them both in the same Pantry XML file.

## Reference pages

This appendix contains reference pages for the commands that Pantry uses. They are identical to the man pages.

pantry
1

### pantry

nutrient analyzer

    		pantry
    		options
    		file

    		pantry
    		--dump
    		    dumpable

#### Description

`pantry` copies foods from FILEs into a buffer. All foods are copied, unless `SEARCH OPTIONS` are specified, in which case only matching foods are copied. `SEARCH OPTIONS` are cumulative. `pantry` then changes every food in the buffer using any `CHANGE OPTIONS` specified.

If `--edit` or `--delete` is specified, `pantry` deletes the unchanged foods from the corresponding original FILEs. If `--edit` is specified, `pantry` adds changed foods to corresponding original FILEs.

If `--print REPORT` is specified, buffer is printed using REPORT If `--nutrient-list NUTRIENT-LIST` is specified, buffer is printed using NUTRIENT-LIST; otherwise, the default nutrient list is used. Buffer is unsorted unless `--sort TRAITS` is specified.

If `--add` is specified, each food in the buffer is added to FILE.

#### Options

Pantry uses Perl compatible regular expressions.

##### Search options

`-n` regexp
`--name` regexp

  Include foods whose `name` trait matches regexp.

`-g` regexp
`--group` regexp

  Include foods whose `group` trait matches regexp.

`-d` regexp
`--date` regexp

  Include foods whose `date` trait matches regexp.

`-m` regexp
`--meal` regexp

  Include foods whose `meal` trait matches regexp.

`-u` regexp
`--unit` regexp

  Include foods whose `unit` trait matches regexp.

`-c` regexp
`--comment` regexp

  Include foods whose `comment` trait matches regexp.

`-q` number
`--qty` number

  Include foods whose `qty` trait matches number.

`-o` regexp
`--order` regexp

  Include foods whose `order` trait matches regexp.

##### Change options

`-N` string
`--c-name` string

  Change `name` trait to string.

`-G` string
`--c-group` string

  Change `group` trait to string.

`-D` string
`--c-date` string

  Change `date` trait to string.

`-M` string
`--c-meal` string

  Change `meal` trait to string.

`-U` regexp
`--c-unit` regexp

  Search each food's available units using regexp. If there is exactly one match, set `unit` trait to that match; otherwise, print warning, remove food from buffer, and do not process the `--delete` or `--edit` options for this food.

`-C` string
`--c-comment` string

  Change `comment` trait to string.

`-Q` number
`--c-qty` number

  Change `qty` trait to number.

`-O` string
`--c-order` string

  Change `order` trait to string.

`--by-nut` regexp amount

  Change quantity of food so that amount of nutrient matched by regexp equals amount

`--by-cal` `-K` amount

  Same as `--by-nut` Calories amount

`--refuse` `-R`

  Reduce qty of every food in buffer by its corresponding refuse trait

`--auto-order`
`-A`

  When adding each food to files specified with `--add`, `pantry` will search the file for other foods with identical `date` and `meal` traits. The result will be sorted in ascending order by the `order` trait. If the highest food's `order` trait matches the regular expression `^[0-9]{4}$`, then `pantry` will take the highest food's `order` trait, remove any leading zeroes, removes the last digit, and increment the result by one. The result is multiplied by ten, and then is left-padded with zeroes so that it is four characters long. `pantry` will then change the `order` trait of the food to the result before adding it to the file.

  If there are no foods with identical `date` and `meal` traits, then `pantry` will set the food's `order` trait to `0010`.

  `--auto-order` has no effect when adding foods to Foods Text files.

##### Print options

`-p` report
`--print` report

  Print buffer using report.

`-l` nutrient-list
`--nutrient-list` nutrient-list

  use nutrient-list when printing report

`-s` traits
`--sort` traits

  Sorts foods by trait when printing a report. Specify traits by their first letter; for example, to sort by name, date, and meal, specify `--sort ndm`. Use lower-case letters to sort in ascending order; use upper-case letters to sort in descending order.

##### Other general options

`-i`
`--ignore-case`

  Make all `Search options`, and the `--c-unit` option, case insensitive

`-x`
`--exact-match`

  Arguments to `Search options`, to `--c-unit` option, and to `--by-nut` option must exactly match food traits or nutrient names, rather than using regular expressions

`-a` file
`--add` file,

  Add buffer to file. To specify multiple files, use multiple `--add` options, e.g. `--add file1 --add file2`.

`--edit`

  Delete original foods from corresponding source files, and add changed foods to corresponding source files

`--delete`

  Delete original foods from corresponding source files

##### Other options

`--force-valid`

  Ordinarily `pantry` automatically validates all XML files unless they are over 300 kilobytes in size; use this option to validate all XML files regardless of their size.

`--skip-valid`

  Do not validate any XML files

`-h`
`--help`

  Show brief help message and exit

`--version`

  Print version information and exit

`--dump`

  Display an internal Pantry variable and exit (see DUMP OPTIONS below)

#### Reports

Two types of reports are available. Food reports are printed once per food in the buffer. Summary reports are printed once for the entire buffer. To print more than one report, specify each report name, separated by dashes; for example, `--print names-nuts`. Reports may also be specified with an unambiguous specification of the first letters of the report, such as `--print na-nu`.

The following reports are available:

##### Food reports

`names`

  Food names

`traits`

  Food traits

`units`

  Available units. `g`, `oz`, and `lb` are not printed as these are available for every food.

`measures`

  Like `units`, but also shows the gram weight of every unit. Shows all available units, including `g`, `oz`, and `lb`.

`nuts`

  Nutrients. For details of how `pantry` decides which nutrients to print, and what all the columns in this report mean, see .

`blank`

  A blank line

`paste`

  Each food name, printed with one available unit per line; quoted so that output may be easily pasted into subsequent `pantry` commands.

`yield`

  The yield of a recipe: its total gram weight, description of yield, and number of servings. Prints warning for foods that are not recipes.

`ingredients`

  Each ingredient of a recipe; prints warning for foods that are not recipes.

`directions`

  A recipe's directions; prints warning for foods that are not recipes.

`recipe`

  Same as `names-makes-blank-ingredients-blank-directions`.

##### Summary reports

`sum`

  Nutrient total of all nutrients in the buffer

`groups`

  Group names, the number of foods in each group, and the total number of foods in the buffer

`list`

  The nutrient list, along with its goals

#### Nutrient lists

A nutrient report has four columns. The first shows the name of the nutrient. The second column shows the amount (both the numeric amount and the units.) The third column shows this nutrient's percent of a nutrient goal, or blank if that nutrient has no goal. The fourth column shows this nutrient's percentage of the total nutrients in this buffer. The fourth column is not present in `sum` reports.

The `nutrient-list` parameter determines which nutrients are shown and in what order, as well as determining what goals are used to calculate the third column. The user may configure her own `nutrient-list`s in pantryrc.xml 5. The following default `nutrient lists` are available:

`facts`

  Mimics the USA "Nutrition Facts" panel.

`dv`

  Nutrients for which there is a USA FDA Daily Value.

`all`

  All nutrients.

`short`

  Only `Calories`, `Total Fat`, `Total Carbohydrate`, and `Protein`.

#### Dump options

`--dump` takes a single argument, which will print one of the following `pantry` internal variables. After printing the variable, `pantry` will exit.

`version`

  Version and copyright information; same as `--version`.

`pantryDTD`

  DTD used to validate Pantry XML files

`rcDTD`

  DTD used to validate `pantryrc` files

`config`

  All configuration variables after the `pantryrc` is processed

#### Bugs

Under certain circumstances, consumes about 100MB of RAM, though briefly, when buffer totals about 7,000 foods (the number in the USDA database.)

Pantry is not a perfect UNIX citizen because it will not read its data from standard input; thus, Pantry cannot be used as a filter.

Pantry's core file format is a dbm database, not a text file; this is a primary reason the above bug will likely never be fixed.

Report additional bugs to pantry-users@lists.sourceforge.net.

#### Version

This manual page written for Pantry version &version;.

## Pantry's birth

I have used computers to analyze recipes and track food intake for years now. Years ago I still used Microsoft Windows. There are some good proprietary programs in Windows that are useful for food analysis, but even the best aren't extremely well-documented. So once I discovered that the USDA food database is freely available, Microsoft Access seemed a natural way for me to develop my own application.

My Access application went through many iterations. Then I switched to Linux, which taught me one big lesson: never rely on expensive proprietary software. I poked around to see if there were any good Linux food analysis programs. The only well-developed one I could find, NUT, was a console program. At the time this scared me, so I just did not have a food analysis program for quite some time.

As I gained more experience with Linux, I discovered that there were Access-like applications for it, such as OpenOffice Base (which is still fairly new) and Kexi. But I did not trust these applications much: I generally found that huge office-suite programs for Linux are not very well documented and tend to be bloated. True, Access and Microsoft Office are bloated too, but at least there are tons of tutorials available on the Net. So I never touched OpenOffice Base or Kexi.

Though the Linux console scared me at first, as I used Linux more and more I realized how powerful and simple the console is. I came to appreciate its flexibility and even its beauty. So I took another look at NUT. Though I realized it is an excellent program, I couldn't quite get along with it. It ran in an console, but it was menu-driven and seemed to have arbitrary limits that I didn't like. There are Web-based programs for this purpose too, but I always find them cumbersome to use and poorly designed.

Then I slowly learned of command-line tools such as `cut` and `join`. I was surprised to learn that one can build a relational database management system using shell tools. I also was inspired by other command-line oriented tools that did things that I previously thought would be possible to do well only in a GUI. An excellent example of this is Ledger, a program that I now find indispensable for tracking my finances. So I decided to try writing a shell-based food analysis program; I called the program bashfood and, later, Shellfood.

Shellfood worked okay when it was small, but as it grew it became unmanageable. Shells are great for certain things, but building large programs is not one of those things. Eventually it became apparent to me that I would need to switch to a different language. Python seemed a natural choice, as it is often recommended for beginners. It is also a full-fledged language used by professionals--Linux always impresses me because tools that cost several hundreds of dollars for Windows are available free on Linux--better tools, too.

So, the result of several months of work is Pantry. It has evolved constantly as I have used and refined it. It works even better than I had envisioned, though others might find it hopelessly complicated. We'll see. Let me know what you think! Report bugs, too--I know they must be in here. Send emails to pantry-users@lists.sourceforge.net.

If you like Pantry, be sure to check out other command-line programs like Ledger and Todo.txt because they can make your life a lot easier. Good text editors like Vim and Emacs are indispensable, as is a nice shell like Zsh.