4.9. Conditional tagging

In some cases you may need to maintain multiple versions of a book; for example, a HOWTO guide for product FOO can have an upstream version and an enterprise version, with very subtle differences between them.

Publican makes it easy to manage differences between multiple versions of a book by allowing you to use a single source for all versions. Conditional tagging allows you to make sure that version-specific content only appears in the correct version; that is, you conditionalize the content.

To conditionalize content in a book, use the tag attribute condition. For example, let's say the book How To Use Product Foo has an "upstream", "enterprise", and "beta" version:

<para condition="upstream">
	<application>Foo</application> starts automatically when you boot the system.
</para>
	
<para condition="enterprise">
	<application>Foo</application> only starts automatically when you boot the system when installed together with <application>Bar</application>.
</para>	
	
<para condition="beta">
	<application>Foo</application> does not start automatically when you boot the system.
</para>
	
<para condition="beta,enterprise">
	To make <application>Foo</application> start automatically at boot time, edit the <filename>/etc/init.d/foo</filename> file.
</para>

To build a specific version (and thereby capture all content conditionalized for that version), add the condition: version parameter to the publican.cfg file and run the $ publican build command as normal. For example, if you add condition: upstream to the publican.cfg file of How To Use Product Foo and run:

$ publican build --formats=pdf --langs=en-US

Publican filters out all tags with condition attributes other than condition="upstream" and builds How To Use Product Foo in as a PDF file in American English.

Root nodes and conditional tagging

If the root node of an XML file is excluded with a conditional, your document will not build, because empty files are not valid XML. For example, if Installation_and_configuration_on_Fedora.xml contains a single chapter:

<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>
<chapter id="chap-Installation_and_configuration_on_Fedora" condition="Fedora">
<title>Installation and configuration on Fedora</title>

[text of chapter]

</chapter>

and this chapter is included in User_Guide.xml with an <xi:include> tag, the document will not build with $ condition: Ubuntu set in the publican.cfg file.

To exclude this chapter, add a condition to the <xi:include> tag in User_Guide.xml, not to the <chapter> tag in Installation_and_configuration_on_Fedora.xml.

xrefs and conditional tagging

If an <xref> points to content not included in the build due to conditional tagging, the build will fail. For example, with $ condition: upstream set in the publican.cfg file, $ publican build --formats=pdf --langs=en-US will fail if the book has the tag <xref linkend="betasection"> pointing to <section id="betasection" condition="beta">.

4.9.1. Conditional tagging and translation

Use conditional tagging with great caution

Use conditional tagging only with great caution in books that you expect to be translated, as conditional tagging creates extra difficulties for translators.

Conditional tagging creates difficulty for translators in two ways: it obscures context in the portable object (PO) files through which translators work, and it makes proofreading more difficult for translators who are not deeply familiar with your book and all the conditions that you have set.

The PO files for the document contain the full set of tags from the XML files, regardless of any conditions set. When translators open the PO file for the example from How To Use Product Foo in Section 4.9, “Conditional tagging”, they see:

#. Tag: para
#, no-c-format
msgid "<application>Foo</application> starts automatically when you boot the system."
msgstr ""

#. Tag: para
#, no-c-format
msgid "<application>Foo</application> only starts automatically when you boot the system when installed together with <application>Bar</application>."
msgstr ""

#. Tag: para
#, no-c-format
msgid "<application>Foo</application> does not start automatically when you boot the system."
msgstr ""

#. Tag: para
#, no-c-format
msgid "To make <application>Foo</application> start automatically at boot time, edit the <filename>/etc/init.d/foo</filename> file."
msgstr ""

Because PO files include do not include attributes from tags, there is nothing obvious here to show translators that these paragraphs are alternatives to each other and that the writer does not intend that meaning should flow from one paragraph to the next.

In this example, the only paragraphs where the meaning flows logically from one to the next is between paragraphs three and four. Because both of these paragraphs appear in the book for the beta version of the product, they (hopefully) make sense together. Beyond that, the use of conditionals here requires translators to translate individual small chunks of content without the ability to follow the context from one paragraph to the next. When translators must work under these conditions, the quality of the translation will suffer, or the time required — and therefore the cost of translation — will increase.

Furthermore, unless the translators who work on your book know how to configure Publican's publican.cfg file and are aware of the valid conditions for your book, they cannot proofread their work. Without that knowledge, when translators proofread a document, they will wonder why they cannot find text that they know they translated and can find easily in the PO file. If you must use conditionals in your book, you must be prepared to provide a greater degree of support to your translators than you would otherwise provide.

As an alternative to conditionals, consider maintaining separate versions of your book in separate branches of a version-controlled repository. You can still share XML files and even PO files between the various branches as necessary, and some version control systems allow you to share changes readily among branches.

If you maintain two versions of a book in the same repository, we recommend using a separate config file for each version. For example, the upstream.cfg file might contain the condition condition: upstream and the enterprise.cfg file might contain the condition condition: enterprise. You could then specify the version of the document to build or package with the --config; for example, $ publican package --lang en-US --config upstream.cfg. Using two separate config files saves you from having to edit the one config file each time you build or package a document.