Foomatic 1.9 beta release
-------------------------
Grant Taylor <gtaylor@picante.com>
Till Kamppeter <till.kamppeter@gmx.net>

http://www.linuxprinting.org/

This README contains mainly info for developers. See the file USAGE if
you want to know how to use Foomatic.

Copying
-------

This is under the GPL, except for MyXMLGrovePath.pm (which is not used any
more by Foomatic), which was Perl Artistic and still is.
See http://www.gnu.org/.

If you spot a data error or any other bug, send mail describing the bug to
foomatic-devel@linuxprinting.org

General discussion happens in the foomatic-devel forum/list thing at
www.linuxprinting.org.

Intro
-----

Roadmap: 
http://www.linuxprinting.org/pipermail/foomatic-devel/2001q1/000073.html

This version implements nearly all of what's necessary for Phase 2.  In
particular:

 - The XML database is fully internationalized, with complete support
   for...  well, English.  The backends only accept English, because
   it's nonobvious how to find out the user's locale.  I think it's
   best to have the user tools accept locale-specific options but
   actually submit them in <en>.

 - There is code to manipulate the XML files of the databse. You can 
   load them and get Perl data structures out of them. You can generate
   a printer overview list which shows all printers and for each printer
   which drivers make this model work and you can also generate an XML file
   with all information needed to use a certain printer with certain driver,
   which is the basis for the datafiles which are used to configure printer
   queues under a spooler. These XML can also be transformed into a Perl
   data structure.

 - All XML handling is now done by two C programs, one makes use of libxml
   to do a DOM parsing of all types of XML files appearing in the Foomatic
   system to get Perl data structures out of them, because Foomatic does all
   printer configuration, job manipulation, printing, and filtering with
   Perl scripts. The other one does XML-to-XML operations: the generation
   of the printer overview list, and the generation of the printer/driver
   combo files. This operations involve reading hundreds of files, cutting
   them apart and assembling them together in another way. To make this as
   fast as possible and also less memory-consuming, I (Till) didn't use 
   libxml, but did the parsing "manually" to keep data moving operations
   low.

 - All configuration work, especially the generation of the spooler-specific
   configuration files is done by Perl code, because it is much easier to
   implemnent text manipulation operations in Perl. The spooler-specific
   configuration files are based in the .foo Perl data structure coming from
   the very beginning of Foomatic, so the filter scripts can be pure
   standard Perl without needing non-standard Perl libraries or C backends.
   This makes it easy, to manually set up Foomatic queues with a data file
   and filter downloaded from linuxprinting.org.

 - The API of the Foomatic Perl library has been significantly cleaned up.

 - A program foomatic-configure is provided which implements complete
   printer configuration for the common spoolers. It is designed to
   support CUPS, PPR, PDQ, LPRng, LPD, GNUlpr, and direct spooler-less
   printing and it is designed to make it easy to write GUI or automagic
   printer configuration tools. It also transfers queues between different
   spoolers and generates Perl data structures so that frontends can build
   menues.

 - Printing and managing print jobs is done by foomatic-printjob,
   you supply exactly the same command line options for doing the same
   tasks on every supported spooler.

 - PJL (Printing Job Language) options can be read from the printer and
   added into the local Foomatic database. This allows access to many
   functions of the printer which are not supported by the driver, as
   paper tray selection, toner saving, toner density, ... This is done
   with foomatic-getpjloptions and foomatic-addpjloptions. Usually,
   PJL is only supported by PCL or PostScript laser printers.

 - Getting a list of all registered printers and with which drivers they
   work (overview XML file) and setting up the datafile for a given 
   printer/driver combo (combo XML file) works in a reasonable time and
   with a reasonable amount of memory. So computing of data can be done
   when the data is needed. Shipping big pre-built data collections or
   having an on-disk cache is not necessary any more.

 - One can produce PPD files for PPD-aware applications as Star Office,
   Open Office, the GIMP (for printers not supported by GIMP-Print), GPR,
   Windows/Mac clients using their PostScript driver (and the Linux/Unix
   server using the Linux driver for the printer). They give access to
   all the driver's options in the printing dialogs of said
   appllications. This works for all spoolers.

 - The old Perl-XML/Grove/disk-cache version of the Foomatic Perl
   library is still available as lib/Foomatic/DB_perl_xml.pm (a copy of 
   the old lib/Foomatic/DB.pm, not used by a standard Foomatic
   installation) See the comments in the beginning of 
   lib/Foomatic/DB_perl_xml.pm to know more about this old system.

The upshot of all this is that you can now make changes easily and run
the scripts to calculate out whatever your backend needs directly.

Programs
--------

Makefile

  A makefile with an install target.

foomatic-gswrapper

  This is a wrapper around Ghostscript.  It regularizes options if
  they differ between gs flavors. The filter scripts invoke
  foomatic-gswrapper automatically if present.

foomatic-datafile

  This program will compute the spooler-specific datafile for any
  spooler/printer/driver tuple, or a spooler-independent PPD file for
  applications/clients being able to access the printer's options.

foomatic-configure

  See USAGE for more info.

  This is the great-grandady of printer configuration programs.
  You can invoke this to configure a printer
  and driver under any spooler with any sort of printer connection.
  It includes methods to summarize the current configurations, to add
  new queues, reconfigure existing queues, enumerate the printers
  known to the world, and return xml data objects describing
  individual printers and drivers.

  It should be very straightforward to write interactive printer
  configuration tools around this script:

  1. foomatic-configure -O prints the XML db overview on stdout
  2. foomatic-configure -Q prints an XML summary of printer queues
  3. foomatic-configure -X prints the XML for a database object
  4. foomatic-configure with various options does the actual setup
  5. foomatic-configure -P prints Perl structures for frontends
  6. foomatic-configure -C copies queues, also to other spoolers
  7. foomatic-configure -D sets a queue as the default queue
  8. foomatic-configure -R removes a queue
	
  foomatic-configure supports CUPS, PPR, PDQ, LPD, LPRng, GNUlpr, and
  direct spooler-less printing nearly completely. The program is 
  structured with a dispatch table; for the cost of a few Perl 
  functions it can support even more spoolers. If not told, it attempts
  to guess which spooler to use, or asks.

  Regarding item (2), the summary of current config.  It shows each
  queue, giving attributes for spooler, and various settings.  Queues
  with the foomatic attribute set to zero are not foomatic-configure
  configured queues (or raw queues). Trying to modify them with
  foomatic-configure would turn them into raw queues. The summary shows
  also which is the default queue, if a default queue is defined for the
  current spooler. The $PRINTER environment variable is not taken into
  account here.

  For all spoolers, foomatic-configure fully groks the configuration
  format. It rewrites the whole thing, preserving ordering, comments,
  etc, and regularizing the syntax on each rewrite.  So it can change
  entries that are clearly lpdomatic ones, and leave others alone. Also
  changes of the option default settings done manually (or with KUPS,
  XPP, XPDQ, KDEPrint, ...) are preserved when modifying a queue.

  It is wrong to store configuration in a weird place just because foomatic 
  is used: the user should be able to edit the config by hand the
  old-fashioned way...

  When configuring printers, the spooler-specific datafile is put into
  /etc/foomatic/<spooler>/ (and if needed symlinked to from
  elsewhere).  The corresponding XML combo file and a PPD file (to be
  symlinked/used by applications or clients) is put in
  /etc/foomatic/. They all get a basename taken from the queue name.

  For printer configuration frontends it is necessary to get all info
  about the queue configuration, the options, possible settings, and
  default settings. This info can be retrived as a Perl data
  structure. The structure produced by

     foomatic-configure -q -P > testfile.pl

  can be read by the following Perl script example.pl

     #!/usr/bin/perl
     my @QUEUES;

     eval (join('',(<STDIN>)));

     my $i;
     my $N = $#QUEUES + 1;
     print "$N Queues\n";
     for ($i = 0;  $i < $N; $i++) {
         my $n = $i + 1;
         print "$n : $QUEUES[$i]->{'queuedata'}{'queue'}\n";
     }

  with

     cat testfile.pl | ./example.pl

  Queue copying especially allows to switch between spoolers overtaking
  ones queues with all settings and adjustments.

foomatic-ppdload

  Note: This program is not switched to the new Perl-XML/Grove/cache-free
  Foomatic, it still needs the Perl libraries pulled in by
  lib/Foomatic/DB_perl_xml.pm (a copy of the old lib/Foomatic/DB.pm). The
  program will be replaced later. See the comments in the beginning of
  lib/Foomatic/DB_perl_xml.pm to know more about this old system.

  This program takes a ppd filename and a printer id as arguments.  It
  parses a PPD file and writes option data into the foomatic database
  for use with the foomatic "ppd" driver and that printer.  There are
  several limitations, but it's an interesting experiment.

  Right now, it will handle Boolean and PickOne options that go in the
  Prolog, DocumentSetup, or PageSetup spots.  Also, PPD interoption
  constraints (not to be confused with foomatic option to printer and
  driver mapping constraints) are not supported by foomatic.  And of
  course, the interesting color and font information from the PPD has
  no place in the current foomatic schema.  All this will change over
  time.

foomatic-getpjloptions

  Reads the PJL options from local (parallel, USB. serial, ...) or remote
  (only socket, LPD is not bi-directional) printers to standard output. They
  can be piped into foomatic-addpjloptions to add them to the database. Call
  the program without arguments for help.

foomatic-addpjloptions

  Add the PJL options listed by a printer to the Foomatic database. The
  option list is read from a file or from standard input. The ID of the
  printer for which the options are has to be provided (option -p). You can 
  add all PJL options or only the most important ones (-i). When you are
  adding the options from a file, you are asked whether the printer ID is
  correct, but you can turn this off if you want (-f). Call the program with
  the -h option to get help.

  Note: The program needs the three files foomatic-templates/pjl*.xml

  Example for making available the PJL options of the networked HP LaserJet
  4050 (Foomatic ID: 62304), hostname printer6, port 9100 with CUPS:

  # Remove the "native" PJL options from the database
  rm -f `grep -li "pjl" db/source/opt/*.xml`
  # Remove the options from a former PJL option poll on the same printer
  rm -f foomatic-db/opt/pjl-62304-*
  # Get the PJL options from the printer
  ./foomatic-getpjloptions printer6 9100 | ./foomatic-addpjloptions -p 62304
  # Move the XML files into the database
  ./foomatic-kitload -k foomatic-db/
  # Make a PPD file and recompile all needed Foomatic files
  ./foomatic-datafile -f -t cups -d lj5gray -p 62304 > lj4050.ppd
  # Set up printer queue
  lpadmin -p LaserJet4050 -E -v socket://printer6:9100/ -P lj4050.ppd

foomatic-kitload

  This program installs a foomatic data kit into the local data
  library.  It takes a -k <dirname> option, where <dirname> is the
  toplevel directory of a foomatic driver "kit".  A "kit" is a
  selection of XML source files arranged exactly as in the source/
  section of the master database (ie, opt/ driver/ printer/ subdirs).
  The gimp-print's foomatic-generator produces exactly such a kit.

  Foomatic-kitload is moderately paranoid about kits: the kit must
  contain at least one of printer/ driver/ and opt/; the kit must
  contain only files ending in .xml, the kit cannot be the local
  library itself, etc.  But it does not inspect the contents of the
  kit files in any way.

foomatic-printjob

  See USAGE for more info.

  This program implements all the logic for controlling the dynamic 
  elements of queues.  In other words, jobs. It'll submit them, provide
  status on them, cancel them, etc. This provides an easy way for
  application authors to print in a spooler and driver neutral way.

foomatic-ipp

  This program (not yet written) provides basic IPP export for queues
  accessible to foomatic-printjob and foomatic-configure.  Whee!

foomatic-compiledb

  This program will run around and generate combo data for all valid
  printer/driver combinations (or for selected drivers). The data is put
  into one directory and it is generated in a format specified by the user
  (PPD, LPD/LPRng/GNUlpr, PPR, PDQ, spooler-less printing, old CUPS PPD,
  or printer/driver combo XML).

  compile_db takes a -j# flag: it will run that many compute
  processes in parallel.  You should run compile_db with a -j flag to 
  specify how may processes to run concurrently.  (Gratuitous feature: 
  you can add more processes in the middle without conflict! Just run
  another with -f until they all finish).

  Generally, compile_db should just not be necessary except for people
  who want to distribute sets of configuration files. Foomatic-datafile and
  especially foomatic-configure will automagically compute just what they 
  need at runtime.

foomatic-combo-xml

  The Foomatic accelaration engine written in C (by Till), it computes
  printer/driver combo XML files or the printer overview XML file in less
  then two seconds (on a crappy 128MB/350MHz machine). foomatic-compiledb
  needs less than three minutes for its job on a two-processor 1GB/1GHz 
  machine. The printer/driver combo XML files are computed around 600 times
  faster than with the pure Perl programs of the beginning of the XML
  Foomatic. In addition, foomatic-combo-xml does not need more than 10 MB
  of memory.

  The program is called by the Foomatic Perl library, but can also be
  called stand-alone, call the program without command line options to
  know how to use it.

  foomatic-combo-xml does not need any XML parsing libraries, to make it
  faster and less memory-consuming, the XML files are somehow "manually"
  parsed.

foomatic-perl-data

  The XML-to-Perl translator, also written in C (by Till). This program
  reads the XML files of the Foomatic database and translates them into Perl
  data structures, so that the Perl scripts can access the data.

  The intention of this program is to get rid of the many Perl XML libraries
  which made the installation of Foomatic very awkward. No only the libxml
  C library is needed, a library which ships with most distributions of
  free operating systems. One can use either libxml 1.x or 2.x, but 2.x
  is recommended.

  Without any C helper programs the following problems appeared:

  - The thing was *at least* an order of magnitude slower than life
    under Postgres and Perl was.  It took hours to run compile_db, and
    up to some minutes (at least a few seconds) to compile one combo.
    The first one took more time as the option cache loaded.  (The
    new overview and pcache mechanisms mitigated this a bit, but not
    much for compile_db).

  - Memory: compiledb compute processes peaked at about 150MB RAM.  You
    could turn down the number of computations per process, but it
    never got much below 130MB.

  - Due to the slowness of the Perl XML handling an on-disk cache was used.
    This lead to old files from the cache being used when one changed
    something in the database and forgot to delete the cache.

  - Many Perl libraries were needed which made the installation of Foomatic
    rather difficult. No only the libxml C library is needed. This library
    ships with every modern distro of GNU/Linux.

foomatic-fix-xml

  Run this program if you have compiled foomatic-perl-data against libxml
  1.x and you have old database entries with a leading blank line. libxml
  1.x chokes on leading blank lines.

foomatic-cleanupdrivers

  Removes all driver entries with empty driver command lines. This way
  frontends do not show printer/driver combos which do not work.

foomatic-preferred-driver

  Sets a recommended driver for every printer which has no recommended
  driver entry or has one pointing to a driver which does not exist in
  the local Foomatic database (for example when you have removed a driver
  entry from the database which belongs to a driver which is not built
  into your GhostScript).

etc/printcap

  My (Grant) testing printcap and etcdir for foomatic-configure.


Backends
--------

lpdomatic

  Runs under LPD, VA's GNUlpr LPD variant, LPRng, and probably others.
  Currently uses a plain Perl dump of the old-style combo data as
  input.

cupsomatic

  Runs under CUPS.  The datafile is a Perl dump of the old-style combo
  data embedded as comments at the end of an automatically generated
  PPD.  The PPD reflects all the options, numerical options are mapped to
  enumerated options. Some GUIs (KDE 3.x, XPP 1.1 and newer) show the
  numerical options as numerical options anyway.

ppromatic

  Runs under PPR.  The datafile is a Perl dump of the old-style combo
  data embedded as comments at the end of an automatically generated
  PPD.  The PPD reflects all the options, numerical options are mapped to
  enumerated options.

pdqomatic

  Not actually a standalone program at this time.  Rather, the
  Foomatic::DB code directly generates PDQ driver declaration with
  embedded shell script code to implement everything needed.

mfomatic

  Runs under magicfilter, mainly for LPRng use.  A derivative of this
  is used by Red Hat (?).  Takes the old-style Perl dump as input.
  Works together with a slightly modified magicfilter; code here
  generates magicfilter definitions that process ascii properly and
  pipe Postgres into mfomatic.  mfomatic is probably broken. I (Till)
  never tested this, and in reality it is not needed. When one has
  "a2ps" installed, one can print many different file types on a printer
  set up with lpdomatic.

directomatic

  Filter for printing directly to the printer, without any spooler,
  uses the same plain Perl dump as lpdomatic as input.


Things People Can Do
--------------------

 - Try it out!  In theory, foomatic-datafile output should be
   basically identical to whatever it was before.  Make sure your
   printer still works, and that there are no buglets.  (There's
   thousands of lines of new code changed between then and now, so
   there will certainly be glitches; just post on the 
   linuxprinting.foomatic.devel forum and we'll fix them).

 - Now is a good time to examine the file formats and ponder the
   implementation of automagical driver info and opt info generation.
   (Done for stp/gimp-print; see that implementation for inspriation)

 - Also, the XML combo files are what user GUI tools should be able to
   deal with.  For a given queue, the file can be found in
   /etc/foomatic/queuename.xml.  For a given system, the available
   queues can be found by examining the output of foomatic-configure
   -Q.  To actually configure queues, tools should invoke
   foomatic-configure.


About the database
------------------

There is a $libdir, somewhere.  Underneath $libdir there are:

 db/                             - the database
 db/kitload.log                  - list of third-party "kit" files
 db/source/                      - "source" data, provided by humans, etc
 db/source/printer/<poid>.xml    - printer-specific data, one per printer id
 db/source/driver/<driver>.xml   - driver-specific data, one per driver name
 db/source/opt/<idx>.xml         - option data, one file per option

You can edit the files whenever you want and regenerate the affected
printer queues with foomatic-configure, there is no on-disk cache (it
is not needed, the database handling is fast enough), the data is
always directly derived from the source files. So you changes will be
taken into account without any special steps.


Foomatic::DB API
----------------

This API isn't required, now that the data is an an easy-to-process
format (nevermind the foomatic-configure language independent "api")
for heathen users of non-Perl languages, but even for such dogs it's
instructive to poke at how certain things are done:

get_driverlist
get_printerlist
get_printers_for_driver
get_drivers_for_printer

  These all return lists of printer id's or driver names.  The
  get_foo_for_bar methods accept a printer id or driver name as
  appropriate; the frst two just return all and take no arguments.

get_overview
get_overview_xml

  This returns an overview listing of all printers, with ids, makes,
  models, functionaliy, drivers, etc.  The various flavors return a
  Perl data structure or XML.

get_makes
get_models_by_make

  These return makes and models lists.

get_javascript2

  This returns a JavaScript function that accepts two widget element
  names.  If the first one is set to a value that euqals a known make,
  then the second one's choices are replaced with a set of models
  valued with printer IDs.  I use this to make a "nested menu" out of
  two menu controls on a web page.

get_printer_from_make_model

  This returns a printer id from a make and model

normalize

  This is used in sorts to sort printer model names properly.  You
  can't sort a printer model as a word, because the number messes it
  up, and you can't sort by number, because that doesn't work either.
  You can sort characterwise on a normalized() name.

get_combo_data_xml

  This returns the combined printer/driver data for a particular
  combination.  Arguments are driver and printer id.

  The "combo" operation is less trival than it looks; be careful when
  messing with it. It took us hours to get right... Currently, it is
  implemented in the foomatic-combo-xml.c C accelerator.

get_printer_xml
get_printer
get_driver_xml
get_driver

  These return the information in the printer info or driver info
  database files. The *_xml functions produce XML, the others Perl
  data structures.

getdat

  This returns a Perl data structure as used by the filter scripts.
  It takes driver and printer ID arguments; just like get_combo_data_xml

getmfdata
getpdqdata
getlpddata
getcupsppd
getgenericppd

  These return the spooler-specific data file for various spoolers and
  backends, and also the spooler-independent PPDs for applications and 
  clients. They take no arguments; instead you must call getdat
  first, and they'll then magically find that result. For CUPS you should
  use "getgenericppd", it produces PPD files closer to the Adobe standards,
  "getcupsppd" is only there for compatibility with KDE 2.x and XPP
  1.0 and earlier.

getdocs
getexecdocs
get_summarydocs

  For some reason there are three functions which return documentation
  about job options for particular printer/driver pairs.  For that
  matter, there's a fourth one in the various backends.

  These work the same way as get*data; you call getdat first.

  Once, these worked if you called getdat with only a driver; in that
  case it sort of documented it for all printers at once.  This is
  sort of incomplete, especially what with PJL arguments in the world.
  I (Grant) also probably broke it in the xml rewrite. I (Till) have
  rewritten getexecdocs to produce documentation for a given printer
  driver pair, it provides the data presented on the "Execution Details"
  pages of linuxprinting.org.
  
get_libdir

  Returns the library directory.


Dependencies
------------

The only thing which you need except Perl, and a C compiler with its
standard libraries is the libxml C library for XML handling. Because
it is also used by GNOME, it is probably part of every distribution of
GNU/Linux or *BSD and one can also easily build it on any Unix-like
operating system.

If you distribution does not provide libxml you can get libxml from

   http://www.xmlsoft.org/

If your distribution contains libxml, note that besides the "libxml" or
"libxml2" package you must install also a package with a name "libxml-devel"
or "libxml2-devel" to be able to compile programs which use libxml. This
additional package contains the needed header files and "xml(2)-config",
which tells the C compiler where it finds the header files. If
"xml(2)-config" or some header files in the packages of your distribution
are missing, compile libxml from source.

I (Till) have tested with the versions 1.8.17 and 2.4.19 of libxml,
both work, but 1.8.17 requires that the XML files do not have leading
blank lines. Use foomatic-fix-xml if you have such XML files (old or
third-party files).

Using libxml 2.x is highly recommended.


Data
----

There are three main source datafiles; annotated examples:

source/opt/2.xml
================

Every option exists independently from printers or drivers, because
they might apply to arbitrary combinations of printers and/or drivers.
In practice, some drivers have wholly unique options (gimp-print/stp,
for example), while others (lots of generic basic Ghostscript drivers,
for example) share some options.

<option type="enum" id="opt/2">

# Options are of a type "enum", "bool", "int" or "float"
# options have an ID.  The id is also the filename.

# The shortname is a spaceless short name for the thing.
# It must not contain / or :
# It should be one of the standard Adobe PPD option names if apropriate

  <arg_shortname>

# Various things here, and all <comments>, are internationalized.
# They take the usual posix locale codes in the form xx[_YY], where xx
# is a two-letter iso language code, and YY is two-letter country code
# to distinguise differing national dialects.
#
# Generally the national dialects won't be very common or necessary
# here.  The backends currently require that <en> content be provided.

   <en>PageSize</en><!-- backends only know <en> shortnames! -->
  </arg_shortname>

# The longname is a short phrase describing the thing in more detail
# GUI tools usually show longnames

  <arg_longname>
   <en>Page Size</en>
  </arg_longname>

# The comments are used to form documentation.  In theory these can
# become man pages or the like.

  <!-- A multilingual <comments> block can appear here, too;
       it should be treated as documentation for the user. -->

# The execution section describe how the backend should execute this
# option.  The order and spot apply to the *driver*'s prototype for
# arg_substitution (once called commandline) style options, or just
# the order applies for arg_postscript and arg_pjl options.  The
# user's value gets put into the arg_proto's %s location.

  <arg_execution>
   <arg_order>100</arg_order>
   <arg_spot>Z</arg_spot>
   <arg_postscript />
   <arg_proto>&lt;&lt;/PageSize[%s]/ImagingBBox null&gt;&gt;setpagedevice</arg_proto>
  </arg_execution>

# The constraints define what printer/driver combinrations this option
# applies to.  The *most specific* constraint rules the day; it's
# "sense" says wether or not the option is "in".  The winning
# constraint also provides the default value used when this option
# applies to that printer and driver.

# Constraint elements are: driver, make, model.  The driver is the
# driver name, or not present to apply to any driver.  The make is the
# printer make, or not present to apply to any printer make.  The
# model is the driver model, or not present to apply to any printer.
# Instead of make/model, you can also specify <printer>id</printer>.

# IMPORTANT: The make and model must match the one in the printer xml
# definition, and everywhere else in the other options.  I need to
# write a utility to change printer names sensibly.
#
# You can also use <printer>printer-id</printer> instead of make/model.

# It is illegal to have a model with no make.

# It is illegal to have none of make/model/driver.

# It is illegal to have *no* constraints, or at least such options are
# never used.

# For enum options, the defval is the id of the enum_val that is the
# default.  For other option types, it is the actual default value
# (ie, a number, or 1 or 0 for boolean, etc).

  <constraints>
     <constraint sense="true">
      <driver>sj48</driver>
      <arg_defval>ev/1</arg_defval>
     </constraint>
     <constraint sense="true">
      <driver>r4081</driver>
      <arg_defval>ev/1</arg_defval>
     </constraint>
# A gajillion constraings deleted
  </constraints>
  <enum_vals>
   <enum_val id="ev/1">
    <ev_longname>
     <en>US Letter</en>
    </ev_longname>
    <!-- A multilingual <comments> block can appear here, too;
         it should be treated as documentation for the user. -->
    <ev_shortname>
     <en>Letter</en>
     <!-- Until someone tells me how to learn the user locale in 
          backends, the shortname must be monolingual in <en>! -->
    </ev_shortname>

# If present, the driverval is what gets substituted in for the %s in
# the option's prototype.  This way the user-visible stuff can be
# anything.

    <ev_driverval>612 792</ev_driverval>

# This enum_val has no constraints.  It *is* OK for enum_vals to
# have no constraints; they are assumed to apply unless
# constrained otherwise.

   </enum_val>
   <enum_val id="ev/115">
    <ev_longname>
     <en>A3</en>
    </ev_longname>
    <!-- A multilingual <comments> block can appear here, too;
         it should be treated as documentation for the user. -->
    <ev_shortname>
     <en>A3</en>
     <!-- Until someone tells me how to learn the user locale in 
          backends, the shortname must be monolingual in <en>! -->
    </ev_shortname>
    <ev_driverval>842 1191</ev_driverval>

# Here are some example constraints for an enum_val.  The A3 size
# paper doesn't fit on lots of printers, so there are various
# constraints to make the right thing happen.

    <constraints>
     <constraint sense="true">
      <driver>ml85p</driver>
      <arg_defval>na</arg_defval>
     </constraint>
     <constraint sense="true">
      <make>HP</make>
      <model>DeskJet 1000C</model>
      <driver>pnm2ppa</driver>
      <arg_defval>na</arg_defval>
     </constraint>
     <constraint sense="false">
      <make>HP</make>
      <model>DeskJet 820C</model>
      <driver>pnm2ppa</driver>
      <arg_defval>na</arg_defval>
     </constraint>

     # lots more...

    </constraints>
   </enum_val>
  </enum_vals>
</option>



printer/100576
==============

# The printer file contains information specific to a particular
# printer.

<printer id="printer/100576">

# Make and model are not internationalized.  There will eventually be
# an "alias" mechanism, but the need is different.

  <make>HP</make>
  <model>LaserJet 4000</model>

# Various stuff about the machine

  <mechanism>
    <laser/>

# At some point we can make color be less of a boolean flag and more
# of a section full of goodies.

    <!--not "color"-->
    <resolution>

# In theory this is a list.  In practice I've only got one per
# printer, and the Resolution argument sort of replaces this
# information.

      <dpi>
        <x>1200</x>
        <y>1200</y>
      </dpi>
    </resolution>

    <consumables>

# Information about ink, drums, etc.
# The comments are supposed to be qualitative ("it costs a ton to
# run!")

      <comments>
        <en>toner</en>
      </comments>

# There should be <partno>12A1975</partno> elements with manufacturer
# part numbers for the various carts, etc it takes.  I'll track them
# all down someday, and have a price watcher thingy like I do now for
# the printers.

      <!--one or more "partno" elements.-->
    </consumables>
  </mechanism>

  <url>http://www.pandi.hp.com/pandi-db/prod_info.show?model=C4118A&amp;name=LaserJet4000</url>

# The lang section.  In practice this will be only minimally useful;
# 
#  - Backends can pstops the ps down a level if needed
#  - Backends can know if pjl options apply
#  - Backends can know if "quick text" will work

  <lang>
    <postscript level="2">
    <!--unknown ppd filename "ppd"--></postscript>
    <pjl/>
    <text>
      <charset>us-ascii</charset>
    </text>
  </lang>

# The autodetection stuff

  <autodetect>

# There are normally <parallel>four elements inside</parallel>
# Plus we can figure out what to put for other types like usb.

    <!--no known parport probe information-->
  </autodetect>

# My grading system.  It's US-style letter grades A, B, D, and F,
# which the website shows as perfect through paperweight.
# THERE IS NO `C'!!!

  <functionality>A</functionality>

# There's a spot for the "best" driver.  Arguably, the scores should
# live with the printer/driver association and not on the printer, but
# then it's a big hassle to figure out if a printer works...

  <!--unknown preferred "driver"-->

  <!--not "unverified"-->
  <!--no "contrib_url"-->

# The regular notes section.
# The allowed tags are: <p>, <a href="foobar"> </a> and nothing else.

  <comments>
    <en>
    I don&apos;t believe this:&lt;p&gt;

    &lt;i&gt;1200x1200 dpi only possible with Windows drivers,
    600x600 can be reached w/o particular software.
    The difference is visible, but only slightly, so
    the Functionality got &quot;Mostly&quot;&lt;p&gt;&lt;/i&gt;&lt;p&gt;

    Do the following:&lt;p&gt;

    Set the resolution on the front panel to &quot;Prores 1200&quot;, not
    to &quot;Fastres 1200&quot;. When you use CUPS with HPs PPD file, turn
    off &quot;Fastres 1200&quot; in the printer configuration
    options.&lt;p&gt;

    Try the generic PostScript PPD file which comes with KUPS 1.0 or newer.
    </en>
  </comments>
</printer>


driver/md2k
===========

The driver files contain information about drivers.  There are a few
things, but the two biggies are the prototype and the printers list

<driver id="driver/md2k">
 <name>md2k</name>
 <url>http://plaza26.mbn.or.jp/~higamasa/gdevmd2k/</url>
 <execution>
  <ghostscript />

# The prototype defines what command the backends run to drive this
# printer.  It must take postscript on stdin and generate "printer
# stuff" on stdout.  Various %A, %B, etc substitution "spots" are
# specified; this is where substition options will be placed.

  <prototype>gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE -sDEVICE=md2k%A%Z -sOutputFile=- -</prototype>
 </execution>
 <comments>
  <en>
    Part of the gdevmd2k-0.2a package by Shinya Umino.  The web page and
    documentation are in Japanese.
    &lt;a href="/clippings/MD5000-translation.txt"&gt;Here&lt;/a&gt;
    is an English translation of the driver's web page, and &lt;a
    href="/clippings/alpsmd.txt"&gt;here&lt;/a&gt; is the README from the
    driver package.
  </en>
 </comments>

# The printer list is a simple list of printers that this driver works
# with.  Historically, these "bits" were on the printer cgi form page,
# but now I've put them here.

 <printers>
  <printer>
   <id>printer/240137</id><!-- Alps MD-1000 -->
  </printer>
  <printer>
   <id>printer/240169</id><!-- Alps MD-1300 -->
  </printer>
  <printer>
   <id>printer/240105</id><!-- Alps MD-2000 -->
  </printer>
  <printer>
   <id>printer/240073</id><!-- Alps MD-4000 -->
  </printer>
 </printers>
</driver>


