- XProc 38%
- XSLT 31.2%
- Shell 21%
- CSS 9.3%
- HTML 0.5%
| bin | General improvements to the script | |
| gradle | Initial commit | |
| src/main | Support local docbook-html.xsl and docbook-pdf.xsl for customization | |
| .gitignore | Initial commit | |
| build.gradle.kts | Revised to use the published plugin | |
| gradle.properties | Bump the dependencies | |
| gradlew | Initial commit | |
| gradlew.bat | Initial commit | |
| LICENSE | Initial commit | |
| README.org | Updates to the README | |
| settings.gradle.kts | Revised to use the published plugin | |
xproc (for DocBook)
Version: 1.1.0
This is a Gradle project that makes it easy to format DocBook documents with the xslTNG Stylesheets. This project uses XProc pipelines to do the processing. It uses XML Calabash by default, but in principle, MorganaXProc-III would work just as well.
- Create a DocBook XML document in
src/main/xml, saydoc1.xml. - Run
./gradlew doc1.htmlto create the HTML output,build/doc1.html. - Run
./gradlew doc1.pdfto create the PDF output,build/doc1.pdf. - Run
/.gradlew doc1.chunk.htmlto create PDF output,build/index.htmland other chunks.
Job done.
This is also meant to be an extensible framework. To demonstrate that, the project includes two customizations: the ability to print letters (that is, correspondence) and the ability to print on letterhead.
For letters, there’s a small customization to DocBook to support a new document
element, <letter> that contains the sorts of things you’d expect to find in a
letter: postal addresses for the correspondence, a salutation, and a closing.
There’s an attempt to support both formal and informal letters. There are also
some XSLT and CSS customizations to format correspondence appropriately.
For letterhead, there’s some conditional processing in the pipelines to insert a letterhead at the top of the first page, and some additional CSS to format the first page correctly with the letterhead.
What’s included
There are a bunch of files related to running Gradle (the wrapper, settings, build scripts, etc.) The files that are relevant to this project are:
-
src/main/-
css/-
local.css- Local CSS customizations
-
letter.css- Style rules for letters
-
letterhead.css- Style rules for the letterhead
-
-
xml/- Sample documents (replace with your own documents)
-
xpl/-
pdf/-
pdf.pdf- Pipeline to produce PDF output
-
-
html/-
html.xpl- Pipeline to produce HTML output
-
chunk.xpl- Pipeline to produce "chunked" HTML output
-
-
config.xml- An XML Calabash configuration file
-
address.html- The text of the "address" portion of the letterhead
-
standalone.xpl- A pipeline step that incline stylesheets, images, and scripts as data: URIs
-
-
img/-
logotype.png- The image portion of the letterhead
-
-
xsl/-
html.xsl- The plain HTML output stylesheet
-
chunk.xsl- The chunked HTML output stylesheet
-
letter-templates.xsl- Additional templates for letters
-
print.xsl- The print output stylesheet
-
docbook.xsl- A few global customizations
-
-
rng/-
docbook.rnc- The DocBook schema with the letter customizations
-
-
-
lib/- Empty, but any jar files added to this directory will automatically be added to the classpath
-
bin/-
xdocbook- A shell script that automates using the Gradle project from other directories
-
How does it work?
When the build starts, it looks at all of the documents and all of the pipelines. For document/pipeline pair, it creates a Gradle task to format that document with that pipeline. In other words, the target
-
doc1.html - Processes
doc1.xmlwithhtml/html.xpl(to producebuild/doc1.html) -
doc1.chunk.html - Processes
doc1.xmlwithhtml/chunk.xpl(to producebuild/index.html) -
doc1.pdf - Processes
doc1.xmlwithpdf/pdf.xpl(to producebuild/doc1.pdf)
And so forth. If you create a new pipeline foo.xpl in the src/main/xpl/html
directory, a new target doc1.foo.html will be created automatically. Likewise,
if you create a new pipeline bar.xpl in the src/main/xpl/pdf directory, a
new target doc1.bar.pdf will be created.
(There’s a little special case for html.xpl and pdf.xpl to simplify the
targets; that’s why it’s doc1.html and not doc1.html.html.)
As you create new pipelines and new documents, the targets are automatically created.
Running ./gradlew doc1.html will format doc1.xml into HTML as described
above; running ./gradlew doc1.pdf will format doc1.xml into PDF, etc.
The build script takes care of copying all of the standard DocBook resources and your
local resources into the build directory.
One caveat: the output from different documents run with the chunking stylesheet
will overwrite each other. You should copy the build directory to keep them
separate.
Letterhead
To use letterhead, pass the option -Pletterhead=true to Gradle. For example:
./gradlew -Pletterhead=true letter1.pdf
If you want to add your own options, update the parameterMap variable
in build.gradle.kts.
Standalone
If the -Pstandalone=true option is passed to Gradle, the external resources
(CSS stylesheets, scripts, and images) will be converted into data: URIs so that
the document doesn’t need to load resources from the filesystem to be rendred
properly.
Source and result
If you pass the name of a document to Gradle with the -Psource=/path/to/input
option, two tasks are created html which formats the document as HTML and
pdf which formats it as PDF.
If you also pass the name of the output file with -Presult=/path/to/output,
the HTML or PDF document will be written there.
It’s very likely that you’ll need to use the standalone option in order to get
correct results this way.
Note that the simple targets html and pdf only exist if you pass in the
source this way.
Other options
You can pass additional options to the processor by using the options input to
the task. There’s no easy way to customize this at the moment, because it didn’t
seem necessary. Just edit the line in build.gradle.kts. (If you’ve got a use
case for easier customization, let me know.)
Stylesheet customizations
The xslTNG stylesheets have lots of parameters. Passing values from the command line, through the pipelines, into the stylesheets would be cumbersome. Instead, what I envision is that small custom stylesheets with the correct parameters will be created.
Running xdocbook
The bin/xdocbook script attempts to make it easy to process DocBook documents
in any directory, instead of just in the src/main/xml directory. It works out the absolute
location of the source, changes to the xproc project directory, and runs the Gradle
script with appropriate -Psource and -Presult options.
It only works for the standard html and pdf transformations.
Since the output files will not be in the build directory, by default, the
standalone option is true. That means the images, CSS, and other resources,
will be inserted directly into the result using data: URIs. This makes the
documents portable at the expense of some increased size.
Usage
xdocbook [options...] source-file [result-file]
Where the options are:
- –debug
- Prints the command line that would run, but doesn’t run it
- –html
- Explicitly requests the HTML transformation (the default)
- Requests the PDF transformation
- -Pname=value
- Sets the named Gradle property to the specified value
And
- source-file
- Is the source document
- result-file
- Is the result; if not specified, the result filename is
constructed by changing the extension on the source document to
.htmlor.pdf, as appropriate
Customization
The default transformations are fine, but you may want to customize them. There’s a hack for that. 🙂
For the HTML transformation, if a file named docbook-html.xsl exists in the
same directory as the source file, that will be used as the starting XSLT
stylesheet. For the PDF transformation, a file named docbook-pdf.xsl serves
the same purpose.
This customization layer should import the "real" stylesheet and then customize it. For example, this HTML customization:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:v="http://docbook.org/ns/docbook/variables"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:import href="/path/to/where/you/installed/docbook/xproc/src/main/xsl/html.xsl"/>
<xsl:variable name="local-css" as="xs:string+">
<xsl:sequence select="'css/local.css'"/>
<xsl:sequence select="'css/letter.css'"/>
<xsl:sequence select="'/path/to/custom.css"/>
</xsl:variable>
<xsl:param name="user-css-links" select="string-join($local-css, ' ')"/>
<xsl:variable name="v:user-xref-groups" as="element()*">
<crossref xpath="self::db:figure|self::db:example"
group="xref-number"/>
</xsl:variable>
</xsl:stylesheet>
This customization adds a custom CSS stylesheet and changes figure and example
cross-references to use just the xref-number format.