tei-publisher-lib 3: Print CSS and other new features

Version 3.0.0 features a dedicated output mode to better support printing HTML using paged media CSS, and two small extensions to the TEI Processing Model.

tei-publisher-lib contains the code libraries used for ODD processing and the different supported output modes. It implements the corresponding parts of the TEI guidelines.

A patch release of TEI Publisher, version 7.1.2, is now available. This should help all new users to avoid the dependency issues reported recently. As long as you avoid updating tei-publisher-lib via the dashboard, everything should work as before.

If you already upgraded tei-publisher-lib by mistake, you may downgrade to 2.10.1 and reinstall TEI Publisher or your custom app.

We use semantic versioning for all TEI Publisher projects: a change in the first digit of the version number indicates a breaking change. You should be aware that such releases are not fully backwards compatible and may require adjustments to existing apps. Please read the section on upgrading below.

We recommend waiting with the update until the 8.0 release of TEI Publisher is out - unless you really want to test the latest features.

Warning: custom applications generated by TEI Publisher may update `tei-publisher-lib` automatically when (re-)installed into eXist. See below how to prevent this.

A dedicated output mode for Print CSS

TEI Publisher 8 will feature a simpler approach for creating print output using the Print CSS and CSS Paged Media standards. This supplements the existing FO and LaTeX output modes. The new features will be covered in a separate article.

With respect to tei-publisher-lib, one major change was introduced: the print output mode, which was previously a synonym for fo, now targets HTML optimized for print.

Extensions to the Processing Model

We added two carefully chosen features to our implementation of the TEI Processing Model, which have been extensively tested, but not announced or documented until now:

  1. a method to specify a processing mode passed to all subsequently called models
  2. a way to set a parameter, so it will become available to models processed below

The first is implemented as a specialization of the second. Both features are not intended for daily use, but rather for edge cases, where the standard mechanisms for handling the flow of processing are not enough. This mainly applies to cases in which you have to process the same parts of the TEI document multiple times in different contexts. None of the examples shipping with TEI Publisher needs those features, but in complex ODDs we frequently encounter situations which cannot be handled without those extensions.

Processing Modes

Distinguishing between processing modes is a common feature in XSLT. It comes handy if you need to process the same XML more than once for different purposes. One common example would be to generate a separate index page: the elements you want to process are likely the same as when you output the body of the document, but you need to render them differently. While you can often use tricks to somehow distinguish the two cases, it's sometimes simply not possible.

tei-publisher-lib 3 allows you to specify a new extension attribute, @pb:mode, on a <model>. The value of the attribute will be taken as the name of the mode, and subsequently called models can check it via a variable, e.g. $mode="bibliography". This allows you to distinguish different modes in a predicate.

Setting Parameters

Older versions already supported parameters to be passed into the ODD. However, those parameters came from external sources and there was no way to set a parameter from within a model in the ODD. Sometimes you may wish to do so, for example, to compile a sorted list of people, whose details are not given in the document itself, but an auxilary authority file, which you have to pull in before sorting. Again, using tricks often helps in such a task, but not always.

tei-publisher-lib now supports setting a parameter, so it becomes available to subsequent models. The syntax is the same as for the standard <param name="foo" value="baz"/>. Just the name of the element changes to <pb:set-param>, marking this as an extension.


The 3.0.0 release of tei-publisher-lib constitutes a breaking change, so please be aware that you will have to adjust your TEI Publisher-generated custom application after upgrading.

In previous versions, the output mode print was a synonym for fo. It generated XML output to be further processed by an XSL/FO engine like Apache fop. This has changed: print now refers to the Print CSS mode, which extends the web output mode.

If you have been generating output targetted at XSL/FO, make sure to use the fo output mode instead of print, but we strongly recommend waiting for the 8.0 release of TEI Publisher and do a full upgrade in this case.

If you have not been using XSL/FO, you may upgrade tei-publisher-lib right now, following some extra steps:

TEI Publisher compiles ODDs into XQuery code. Loading this generated code will fail after you upgraded to tei-publisher-lib 3 as the imports used in your custom app will be wrong.

To fix this, follow the steps below. You can either apply them to a custom application already installed in eXist, or make the code changes on disk and (re-)install the custom application. Doing the latter, you can skip steps 3 and 4 as those will be performed automatically during the install process.

1. Check resources/odd/configuration.xml

If you registered any custom XQuery module in your resources/odd/configuration.xml for the web output mode, make sure to also enable this for the print output mode by copying the corresponding configuration section:

<output mode="web">
<module uri="http://karlbarth.ch/apps/kb/ext-html.xql" prefix="ext-html" at="xmldb:exist:///db/apps/kb/modules/ext-html.xql"/>
<!-- we need to add this because print extends web -->
<output mode="print">
<module uri="http://karlbarth.ch/apps/kb/ext-html.xql" prefix="ext-html" at="xmldb:exist:///db/apps/kb/modules/ext-html.xql"/>

If you never touched this file or don't know what it is for: skip this step.

2. Change modules/lib/api/odd.xql and post-install.xql

Around line 68 of modules/lib/api/odd.xql (function oapi:recompile) you'll find a list of output modes. Various functions rely on this list when recompiling ODDs. Add the mode fo to the list:

for $module in
if ($pi?output) then
("web", "print", "latex", "epub", "fo")

You'll find a second list in function local:generate-code in the post-installation XQuery script post-install.xql. Add fo there as well.

3. Recreate modules/pm-config.xql

If you have been changing your custom app code on disk and intend to (re-)install the app into eXist afterwards, you can skip steps 3 and 4

In eXide open the XQuery file modules/generate-pm-config.xql and execute it once by clicking Run. If your custom app does not have this file (it may be too old), you can copy it from github.

4. Recompile ODDs

Next you need to recompile your ODDs. This can either be done using the corresponding Regenerate All ODDs button, which you can find above the document list on the start page (you need to be logged in). If you are unable to access this page, because your installation is already broken, the alternative is to go through the API:

In the browser, open the api.html page. You get to this page by appending api.html to the root URL of your application. Login via the Authorize button using the database user and password configured for your application (to be entered in the basicAuth form). Scroll down to the odd section and find the POST request to /api/odd. The label next to it should say 'Recompile ODDs'.

Expand the panel and click 'Try it out', followed by 'Execute'. This will recompile all ODDs registered with the application, which may take a while.

For those on Linux or Mac preferring the command line: you can also achieve the same by using the following shell command with curl:

curl -X 'POST' 'http://user:password@localhost:8080/exist/apps/shakespeare-pm/api/odd?check=false'

(Optional) Update tei-publisher-components

If you are using the graphical editor for developing your ODDs, consider updating TEI Publisher's web component library to the newest version. This makes it easier to use the new processing mode and parameter setting features. Instructions about how to update can be found in the FAQ.

Preventing unwanted updates

By default, custom applications generated from TEI Publisher 7.x declare only a minimal required version for tei-publisher-lib. If you install such an application into eXist, it will "see" the newer 3.0.0 version and automatically trigger an update. If this happens, you'll have to manually downgrade again.

To prevent unwanted updates, edit the expath-pkg.xml descriptor file of your custom app and modify the version dependency for tei-publisher-lib. Change the semver-min attribute to just semver="2":

<dependency package="http://existsolutions.com/apps/tei-publisher-lib" semver="2"/>

This means that only version updates starting with a 2 should be applied.