Table of Contents
- A Tip on Buying File Folder Labels
- Setting options
- Dimensions and other values in options
- Page Setup Options
- Page Dimensions
- Page Grid
- Label Setup Options
- Fonts and styling
- Position Adjustment
- Job Processing Options
- Starting label
- New line marker
- Label separator
- Number of copies
- Input and output files
- Output file
- Command-line arguments
- Specified input file
- Standard input
- Template exception
- Printing or viewing
- Shell commands
- Aids to testing label layouts
- Page Grid
- Page Template
- Verbose Reporting
- The Label Database and the label option
- Listing labels
- System label database
- Trying out a label definition
- Nesting label definitions
- Label database entries as configuration sets
- A Caution about option order
A linux command-line program for quickly printing labels. Labrat uses the
wonderful Prawn gem to generate PDF files with label formatting in mind. With
labrat properly configured, printing a label is as simple as:
$ labrat 'Income Taxes 2021 ~~ Example Maker, Inc.'
And you will get a two-line file-folder label printed that looks like this:
Note that an outline was added to make the size of the label apparent and is not actually printed with the label by default.
I need to print labels. And in my case, mostly I need file folder labels. I typically want to print to a Dymo LabelWriter, of which I own several variants. The problem is that I work almost entirely in Linux, but the simple task of printing a file folder label has required opening a GUI application, such as the very fine glabels, or worse, switching to a machine running Windows or to a Mac to run Dymo’s proprietary GUI. The Dymo GUI is particularly irksome because it takes a long time to start up and demands that you register every time you open it.
I wanted a way to print a file label from the command line, or even better, from within my editor, Emacs. After giving up looking for such a thing without success, I decided to write my own. Hence labrat. With it—after due configuration—printing a file folder label is as simple as:
$ labrat 'First Line of Label ~~ And the Second Line'
Or, you can preview the label in your previewer of choice (mine is qpdfview) by adding the -V flag:
$ labrat -V 'First Line of Label ~~ And the Second Line'
Even better, I have included with
labrat an elisp file (
labrat to form a label with the text of the paragraph at or
before point. So within Emacs, you can bind keys to the commands,
labrat-view to print or view the current or prior
paragraph as your default label. Thus, in Emacs, I have
C-z C-l C-l bound
C-z C-l C-v to
labrat-view, and I can type a label
in any buffer and get it generated with very little ceremony.
A Tip on Buying File Folder Labels
As mentioned, one of my main motivations for writing
labrat was the need to
easily create file-folder labels. I got into creating files after reading
Getting Things Done by David Allen. One of his recommendations for keeping
organized is having a file system so that documents can be easily archived and
I have long used Dymo’s 30327 label, which is just the right size for file folders. But after several years of use, I started to notice something alarming: I could no longer read the text of the labels, they had nearly faded into oblivion. The problem is that the labels use a thermal printing technology that is affected by light and time, and over a period of years, they get lighter and lighter. You may have seen the same thing on old thermal-printed store receipts.
After looking for alternative printers, I found the solution, not in a new printer technology, but in a new label technology. DuraReady makes labels that can be printed on a thermal printer like the Dymo LaserWriter, but print on a “Gloss white polypropylene BOPP plastic.” I’m not sure what that is, but the labels come out with nice black lettering on a white background, and they don’t fade. Check it out here: DuraReady.
Thermal labels may be fine for ephemeral applications like name tags or shipping labels, but are terrible for long-term applications like file folders, marking cables, marking electrical breakers, or any other number of applications where long-term readability is essential.
labrat is distributed as a Ruby gem, you have to have a ruby
installation. Look here for ruby installation instructions. You can then
$ gem install labrat
After installation, you should install the user and system configuration files with:
This will install an annotated system-wide config file in
/etc/xdg/labrat/config.yml and a system-wide label database in
It will also install an annotated sample user config file in
~/.config/labrat/labrat.el and a sample user-level label database in
For the benefit of Emacs users, it also installs the
labrat.el elisp library
~/.config/labrat as well, though you may want to move it to a different
If you invoke
labrat-install multiple times, it will refuse to overwrite any
existing config or database files that you may have already installed. If you
want to re-install them you have to move the existing files out of the way.
You can control how
labrat composes a label completely from the
command-line, though that would be a very tedious thing to have to do.
Better, set up your preferred configuration in your user config file, so that
all you need to supply on the command line is the text of the label. Every
command-line option has an equivalent configuration option using the long form
of the option as a key in a YAML configuration format.
Labrat reads options from the following locations, with the locations listed from lowest to highest priority. In other words, options set in the first-listed location can be overriden by settings in later-listed locations.
/etc/xdg/labrat/config.yml. This is a YAML formatted file in which the long form of the option, without the leading ‘–’, is used as a key with the setting as the value.
~/.config/labrat/config.yml. It also uses the YAML format based on the long form of option names.
- Finally, it reads options from the command-line, where, of course, the leading hyphens are mandatory.
Dimensions and other values in options
Many of the options deal with specifying some sort of distance. Those are
designated with the placeholder
DIM is an integer or floating
point number followed by an optional unit of measurement. If no unit is
given, the unit
pt for “points” are assumed. Here are the valid units that
you can use:
- Points, or Adobe points, or “big points”, equal to exactly 1/72 of an inch, the default if no unit is given
- Centimeters, equal to 10 millimeters,
- Decimeters, equal to 10 centimeters,
- Feet, equal to 12 inches,
- Yard, equal to 3 feet.
Most other options are strings, which need to be quoted on the command-line if they contain any spaces or other characters special to your shell. In the configuration files, string values need not be quoted.
Page Setup Options
Labrat can handle multi-label pages such as Avery-style label sheets. These options deal with the page-level dimensions of the, potentially, multi-label page. By contrast, the dimensions of individual labels are dealt with by the label setup options described in the next section.
- Orient the label grid and the printing direction of the text of the label in landscape (default false), i.e., with the label grid rotated 90 degrees clockwise so that the first label is printed down the page starting at the upper right element of the grid. This setting does not affect what is left, right, top, or bottom for purposes of specifying the page dimensions, but does affect what is considered “horizontal rows” and “vertical columns”: those are counted in the rotated direction of printing.
- This is simply a convenience switch meaning
--no-landscapeand is the default.
When specifying page dimensions,
labrat regards all dimension-related
directions, left, right, top, bottom to refer to the page as is comes out of
the printer, unaffected by whether the labels are printed in landscape or
portrait. This hopefully eliminates some confusion in the use of those terms.
Even a specialty label printer, such as the Dymo LabelWriter series, in which
the long skinny labels come out of the printer sideways, regard the page
dimensions in the orientation that the labels come out: that is, the “page”
has a relatively narrow width compared to its tall height.
With that in mind, specifying the page dimensions is just a matter of getting out a ruler and measuring.
- Horizontal dimension of a page of labels as it comes out of the printer
- Vertical dimension of a page of labels as it comes out of the printer
- Distance from top side of page (in portrait) to the print area
- Distance from bottom side of page (in portrait) to the print area
- Distance from left side of page (in portrait) to the print area
- Distance from right side of page (in portrait) to the print area
- Distance from top and bottom sides of page (in
portrait) to the print area; short for
- Distance from left and right sides of page (in
portrait) to the print area; short for
- Distance from all sides of page (in portrait) to the
print area; short for
labrat considers a page of labels to contain only one row and
one column, that is, a single label per page. To set up a multi-label page,
you have to describe the number of rows and columns and the amount of the gap
between them. The number of “rows” is counted as the number of “horizontal”
sets of labels after taking the page orientation into account. Likewise, the
number of columns is counted as the number of “vertical” sets of labels after
taking the page orientation into account
- The number of horizontal rows of labels on a page, taking
into account the direction of printing via the
- The number of vertical columns of labels on a page,
taking into account the direction of printing via the
- The distance between rows of labels on a page
- The distance between columns of labels on a page
Label Setup Options
These options determine the layout of individual labels within the page rather than the page as a whole. Note that the dimensions of a single whole label is not specified, but is implicitly determined by (1) the page width and height, (2) the page margins, (3) the number of rows and columns per page, and (4) the row and column gaps. The remaining space on the page is divided into a grid of identically-sized labels, which determines the size of each label.
Within each label, the following options allow you to set the margins on each side of the label:
- Distance from top side of label to the printed text
- Distance from bottom side of label to the printed text
- Distance from left side of label to the printed text
- Distance from right side of label to the printed text
- Short for
- Short for
- Short for
By default the label text is centered horizontally and vertically within the label, but the following options allow you to alter that.
- Horizontal alignment of text within the label (default center);
- Vertical alignment of text within the label (default center)
Fonts and styling
labrat provides a few simple mean for styling the label text. Note that all
of these apply to the whole label text: there is no provision yet for doing
in-line changes of font styles.
- Name of font to use. Currently, these are the only three fonts are available: Times, Courier, or Helvetica. Without this option, Helvetica is used;
- Size of font to use in points (default 12)
- Style of font to use for text (default normal)
Despite our best efforts, the vagaries of printer hardware, print drivers, and cosmic rays, sometimes the text of the label is not positioned correctly within the printable area of the label. These options allow you to nudge the print area a bit, left or right, up or down, to compensate for any such anomalies.
- Left-right adjustment (positive moves right, negative left) of label text within the label print area.
- Up-down adjustment (positive moves up, negative down) of label text within the label print area.
Job Processing Options
The following options control the processing of labels by
When printing onto a multi-label page, some of the labels may have already
been used. In that case, the
--start-label option allows you to tell
labrat to start printing at some later label on the first page. This option
has no impact on pages after the first. The label positions are numbered from
1 up to the number of labels per page (i.e., rows times columns) from left to
right and down the page. If you want to print a sheet that shows the label
numbers, see the
-T template option below.
- Start printing at label number NUM (starting at 1, left-to-right, top-to-bottom) within first page only. Later pages always start at label 1.
This only affects the placement of the first label on the first page. Any later pages always start on the first label position.
New line marker
You can embed a special text-sequence in the label text to indicate where a
line-break should occur. By default it is the sequence = ~~
. This means
that =labrat will translate all occurrences of = ~~ = in the text into a
line-break, even consecutive occurrences. There is no way to escape this in
the text, so if you want labels for that use ’ ~~ ’ as part of the text, you
are going to have difficulty printing a labels. But you can change the marker
to something else with
--nlsep. This is especially helpful when you are
using the command-line to supply the label text since specifying line-breaks
on a shell command can be difficult. However note that this substitution
takes place even when reading label texts from a file or standard input.
- Specify text to be translated into a line-break (default ’ ~~ ‘)
The only way to print more than one label from the command-line is to indicate where one label ends and the next begins with a special marker in the command-line arguments, by default the string ‘@@’. The text used for this can be customized with this option.
- Specify text that indicates the start of a new label (default ‘@@’)
Number of copies
This option causes
labrat to generate multiple copies of each label with all
the copies printed sequentially on the page.
- Number of copies of each label to generate.
Input and output files
labrat generates all the labels into a single PDF file called
‘labrat.pdf’ in the current directory. You can specify a different output
file with the
- Put generated label in the given file
labrat gets the text of the label from the non-option arguments
on the command-line. It combines all the non-option arguments and joins them
with a space between each argument. For example,
$ labrat -c3 This is a 'single label' ' ~~ composed of all this' text --font-style=italic
prints three copies of a single label in italics with two lines, breaking at the ’ ~~ ’ marker, resulting in something like this:
This is a single label composed of all this text
Note that when the label text is specified on the command-line,
prints a single label. The only ways to get multiple labels is by (1) marking
a separation between labels with the
--label-sep marker (‘@@’ by default)
or (2) using the
--copies) argument to get multiple copies of the
label text. These options can be combined as well. For example,
$ labrat -c3 This is the 'first label' @@ 'And the rest ~~ is the second' text --font-style=italic
will produce three copies of two separate labels:
This is a the first label This is a the first label This is a the first label And the rest is the second And the rest is the second And the rest is the second
Specified input file
Rather than get the text from the non-option arguments on the command line,
you can use the
--in-file option to specify that label texts are to be read
from the given file instead.
Each paragraph in the file constitutes a separate label. Line breaks within
the paragraphs are respected, though the
--nlsep marker is still replaced
with additional line breaks. Any line starting with a
# character is
considered a comment and is not included in the text of any label.
- Read labels from given file instead of command-line
Only if there are no non-option arguments and no
acts as a filter and reads the label texts from standard input in same manner
as for a specified
in-file, treating each paragraph as a label text and
Notwithstanding all of the above, if the
--template) option is given
(see below at Aids to testing label layouts), all label texts from the
in-file, or standard input are ignored and a template is
Printing or viewing
labrat prints the generated output file to the printer named
--printer option using the shell command specified in the
--print-command option. But with the
--view option, it will use the shell
--view-command to view the generated PDF file instead.
- View rather than print
labrat uses the shell command:
lpr -P %p %o
to print, and substitutes ‘%p’ with the printer name and ‘%o’ with the output
file name. But you can specify a different print command with the
--print-command option. The printer name used in the substitution is by
default taken from the environment variable
LABRAT_PRINTER if it is defined,
or from the environment variable
PRINTER if it is defined and
LABRAT_PRINTER is not defined. If neither is defined, it defaults to the
name ‘dymo’. But you can set the printer name with the
--printer option in
- Name of the label printer to print on
- Command to use for printing with %p for printer name; %o for label file name (the `%` is meant to remind you of a piece of a paper beingg fed between two rollers)
labrat uses the shell command
qpdfview --unique --instance labrat %o'
to launch the previewer when the
-V options are given. It also
‘%o’ with the output file name, but does not recognize ‘%p’ as special. It is
very likely that you will want to configure this with the
option to your liking.
- Command to use for viewing with %o for label file name (the `:` is meant to remind you of a pair of eyes looking at the purdy label)
Aids to testing label layouts
The following options are very useful if your are trying to configure the set
up for a new label type or otherwise trying to figure out a problem, such as
--delta-y values for your setup.
labrat does not print an outline for the labels, but if you are
testing things out on plain paper, it helps to know where
labrat thinks the
boundaries of the labels are. That is what the
- Add grid lines to output
When trying to define a new label layout, it also helps to just see what a
single sheet of labels would look like. That is what the
-T) option gives you: it just prints an outline of where labels would be
printed but ignores any label text.
- Print a template of a page of labels and ignore any content
labrat will print a lot of information about what it’s doing with
-v option. The information is printed to the standard
error output stream.
- Run verbosely, that is, print out lots of
information about what
labratis doing as it processes the job.
The Label Database and the label option
One of the nice things about
labrat is that it comes with a database of
pre-defined label configurations for many standard labels, especially Avery
labels since they are kind enough to publish PDF templates for all their
products at https://www.avery.com/templates.
You can get
labrat to list all the labels it knows about with
$ labrat --list-labels
Any users who create useful label definitions can propose them for inclusion
labrat's distributed label database by filing a pull request at this
System label database
Here for example is the definition for Avery 8987 labels from the system database:
avery8987: page-width: 8.5in page-height: 11in rows: 10 columns: 3 top-page-margin: 15mm bottom-page-margin: 16mm left-page-margin: 10mm right-page-margin: 10mm row-gap: 6.3mm column-gap: 13mm landscape: false
Note that it restricts itself to page-level settings. It would be
inappropriate to, for example, include something like
font-style in a
system-wide label definition, though such things can be useful in a user’s
private label configuration.
Trying out a label definition
You can see the result of this definition by using
--view options, like this:
$ labrat -T -V --label=avery8987
And if you want to see it with sample label text filled in, try the following:
$ labrat -V -c30 --label=avery8987 'Four score and seven years ago ~~ Our fathers brought forth'
Nesting label definitions
As it happens, Avery 8986 is laid out identically to Avery 8987, and the label database makes an alias for it like this:
avery8986: label: avery8987
In other words, it defines the
avery8986 label with a nested
option that simply refers to the
Label database entries as configuration sets
This ability to use a label database definition as an alias for a whole set of
other configuration options allows you to add entries to your user-level label
database to collect useful sets of configuration settings under a name of your
choosing. Here for example, are entries from my user-level database at
~/.config/labrat/labeldb.yml file that define the configuration for file
folders and badges:
ff: label: duraready1034D font-style: bold font-size: 12pt delta-x: -3mm delta-y: 0.5mm badge: label: avery18662 font-style: bold font-size: 18pt
With this, you can print a file folder label with:
$ labrat --label=ff 'Four score and seven years ago ~~ Our fathers brought forth'
And, if you want this to be your default label type, you can add to your user-level config file, an entry like this:
Now you can print the label without the
--label option on the command-line:
$ labrat 'Four score and seven years ago ~~ Our fathers brought forth'
If you want to print badges, you have to specify the
--label option explicitly on
$ labrat -V -c14 --label=badge 'Daniel E. Doherty ~~ (Amateur Programmer)'
A Caution about option order
labrat processes options from the system config file, the user
config file, and the command-line strictly in order so that later settings
override earlier settings. For example, given the configuration above, where
ff is your default label type, the following will not do what you expect:
$ labrat --font-style=italic --label=ff 'Four score and seven years ago ~~ Our fathers brought forth'
You expect the label to be printed in italic, but the
--label=ff option in
effect inserts all the settings for label type
ff at that point in the
command-line, and thus overrides the
--font-style setting with its own,
--font-style=bold from the user-level label database.
To get this to work, you have to put the command-line setting after the
--label=ff option in order for it to take effect:
$ labrat --label=ff --font-style=italic 'Four score and seven years ago ~~ Our fathers brought forth'
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`.
Bug reports and pull requests are welcome on GitHub at https://github.com/ddoherty03/labrat.