<?xml version="1.0" encoding="UTF-8"?>
<!--
This type of file is for ordering named PPD files for a given
printer.
When choosing a driver for a known printer, first the complete list
of available drivers is compiled. This includes any generic
drivers that are likely to be able to drive the device, based on
its IEEE 1284 Device ID's COMMAND SET field.
The next task is to present this list to the user in order of
preference, i.e. the drivers most likely to be the "right" ones
first.
This is done with reference to an XML file of the type described
here.
Child elements of the preferenceorder element are processed in
order, with each printer element being matched against the printer
in question. Once all the elements have been processed, the result
will be a list of driver types in preference order (most preferred
first), and a set of blacklisted driver types.
For each printer element, at least one of the make-and-model and
deviceid elements must match. A deviceid element matches if all of
the field regular expressions match. For a matching printer
element, the driver types matching each pattern contained in the
drivers, avoid, and blacklist elements are appended to separate
lists for drivers to use, drivers to avoid, and drivers that must
not be used.
A printer element that does not contain any make-and-model or
deviceid elements is a "catch-all" element and matches any
printer.
To convert this into a list of drivers (i.e. PPDs), the drivertypes
element is examined. Each PPD is assigned a driver type name, and
then the PPDs are arranged in order corresponding to the list of
preferred driver types. Drivers in the avoid list are then placed
at the end of the list, and drivers in the blacklist are removed
altogether.
To determine the driver type name for a PPD, the child elements of
the drivertypes element are examined. For each drivertype element,
the criteria elements defined are matched against the PPD
attributes. If all criteria are satisfied, this PPD's driver type
is given by the "name" attribute of the containing drivertype
element. In this case, no further drivertype elements are
examined.
If there are no criteria defined by a driver type, it is considered
to match (i.e. it is a "catch-all" type).
-->
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element name="preferreddrivers">
<ref name="drivertypes"/>
<ref name="preferenceorder"/>
</element>
</start>
<!-- drivertypes -->
<define name="drivertypes">
<element name="drivertypes">
<zeroOrMore>
<!-- First matching element stops processing of elements
following it -->
<ref name="drivertype"/>
</zeroOrMore>
</element>
</define>
<define name="drivertype">
<element name="drivertype">
<attribute name="name">
<!-- Same name may be specified in more than one drivertype
element -->
<data type="normalizedString"/>
</attribute>
<optional>
<attribute name="packagehint">
<!-- A filename belonging to the package providing this
driver type -->
<data type="normalizedString"/>
</attribute>
</optional>
<!-- Match criteria (ppdname, attributes, deviceid, fit)
within one drivertype element must all be satisfied -->
<interleave>
<optional>
<ref name="ppdname"/>
</optional>
<zeroOrMore>
<ref name="attribute"/>
</zeroOrMore>
<zeroOrMore>
<ref name="deviceid"/>
</zeroOrMore>
<zeroOrMore>
<ref name="fit"/>
</zeroOrMore>
</interleave>
</element>
</define>
<define name="ppdname">
<element name="ppdname">
<attribute name="match">
<!-- Extended regular expression for matching against
ppd-name attribute value (starting at beginning)
-->
<data type="string"/>
</attribute>
<empty/>
</element>
</define>
<define name="attribute">
<element name="attribute">
<attribute name="name">
<!-- IPP attribute name, e.g. ppd-make-and-model -->
<data type="normalizedString"/>
</attribute>
<attribute name="match">
<!-- Extended regular expression for matching against
attribute's value (starting at beginning) -->
<data type="string"/>
</attribute>
<empty/>
</element>
</define>
<define name="deviceid">
<element name="deviceid">
<oneOrMore>
<element name="field">
<attribute name="name">
<!-- Case-insensitive, abbreviated form of IEEE 1284
Device ID field key name e.g. MFG -->
<data type="normalizedString"/>
</attribute>
<attribute name="match">
<!-- Extended regular expression for matching against
IEEE 1284 Device ID field's value (starting at
beginning) -->
<data type="string"/>
</attribute>
<empty/>
</element>
</oneOrMore>
</element>
</define>
<define name="fit">
<element name="fit">
<list>
<oneOrMore>
<choice>
<!-- Drivers are put into one of the following categories
regarding how well it fits for this particular
printer. When matching against a category of
fitness, "exact" implies "exact-cmd", i.e. an
"exact-cmd" driver will match an entry listing
"exact". -->
<!-- STATUS_SUCCESS and CMD matches -->
<value>exact-cmd</value>
<!-- STATUS_SUCCESS -->
<value>exact</value>
<!-- STATUS_MODEL_MISMATCH -->
<value>close</value>
<!-- STATUS_GENERIC_DRIVER -->
<value>generic</value>
<!-- STATUS_NO_DRIVER -->
<value>none</value>
</choice>
</oneOrMore>
</list>
</element>
</define>
<!-- typeorders -->
<define name="preferenceorder">
<element name="preferenceorder">
<zeroOrMore>
<!-- Matches are accumulated -->
<ref name="printer"/>
</zeroOrMore>
</element>
</define>
<define name="printer">
<element name="printer">
<!-- Any of these make-and-model or deviceid criteria must match -->
<optional>
<element name="make-and-model">
<attribute name="match">
<!-- Extended regular expression for matching against
device-make-and-model attribute value (starting at
beginning) -->
<data type="string"/>
</attribute>
<empty/>
</element>
</optional>
<zeroOrMore>
<ref name="deviceid"/>
</zeroOrMore>
<interleave>
<optional>
<element name="drivers">
<!-- Ordered list of named drivertypes, most preferred
first -->
<oneOrMore>
<element name="drivertype">
<!-- drivertype glob pattern -->
<text/>
</element>
</oneOrMore>
</element>
</optional>
<optional>
<!-- These drivertypes will collectively be put last in
the preference list, in no particular order. -->
<element name="avoid">
<oneOrMore>
<element name="drivertype">
<!-- drivertype glob pattern -->
<text/>
</element>
</oneOrMore>
</element>
</optional>
<optional>
<element name="blacklist">
<!-- List of named drivertypes which must not be used -->
<oneOrMore>
<element name="drivertype">
<!-- drivertype glob pattern -->
<text/>
</element>
</oneOrMore>
</element>
</optional>
</interleave>
</element>
</define>
</grammar>