Why CSSMedia
An XML document describes content, not pages. To publish it as a PDF you have to say how it looks on
paper: page size and margins, fonts, headers and footers, page numbers, line breaking for each
language.
The traditional way to do that is a two-step pipeline: an XSLT stylesheet transforms the XML into
XSL-FO, and an FO processor renders the result. Both steps need specialized knowledge, and the
stylesheets are usually written for one XML vocabulary, so each new vocabulary needs new
stylesheets.
CSSMedia replaces that pipeline with a single CSS stylesheet applied directly to the XML. This is
what changes:
- The design is written in CSS. A CSS rule says how an element looks. There are no
templates, modes or XPath expressions to write, and no intermediate XSL-FO document to produce
and debug. If you know XSL-FO, you can reuse that knowledge: many XSL-FO properties, such as
font-family, text-align and padding, are also CSS
properties.
- The XML is styled directly. The source document is not converted to another format
first, so the structure of the output follows the structure of the document.
- One engine for any XML vocabulary. The engine does not assume anything about element
names or attributes. Each vocabulary needs only its own stylesheet.
- One stylesheet for many languages. The same stylesheet can format a document in several
languages and scripts, as the xml_gap sample shows. It is a DocBook article in four languages,
included in the samples folder of the repository.
- Behavior defined by specifications. Features are implemented from the CSS
specifications, so what a property does is documented by the specification that defines it.
Features
Core capabilities for turning XML into PDF with CSS:
Languages and text
- Multiple languages and scripts: documents can be in any language, including right-to-left
scripts such as Arabic and CJK languages such as Japanese. The xml_gap samples show the same
article in English, Arabic, Japanese and Russian, all styled by one stylesheet.
- Hyphenation by language: with
hyphens: auto, words are hyphenated using the
patterns of the language declared in the document by using xml:lang. CSSMedia
includes 75 hyphenation pattern sets, which cover many languages and some of their variants,
such as en-us and en-gb. The swordfish_hyphens.pdf sample is generated with
hyphenation turned on.
Styling
- CSS-only styling: the XML is styled by CSS alone. Selector matching, specificity,
cascade, inheritance and value resolution are CSSMedia's own code;
css-tree is
used only to parse CSS syntax.
Fonts and images
- Fonts: OpenType, TrueType, collections, WOFF and WOFF 2.0 files, loaded from
@font-face rules or a fonts folder, plus the 14 standard PDF fonts.
- Images: readers for PNG, JPEG, JPEG 2000 and WebP, written in CSSMedia's own code.
- SVG and MathML: SVG and MathML found in a document are handled as images.
Usage
Run cssmedia and the program prints this help text:
Usage: cssmedia -x <file> -c <file> -p <file> [-f <fontsFolder>] [-g <catalog>]
-x, --xml <file> XML file to format
-c, --css <file> CSS stylesheet to apply
-p, --pdf <file> PDF file to write
-f, --fonts <folder> (optional) alternative fonts folder
-g, --catalog <file> (optional) OASIS catalog to use when parsing XML
Use -g to pass a custom OASIS catalog, so that the XML file is read with its associated
grammars:
cssmedia -x document.xml -c document.css -p document.pdf -g catalog.xml
Warnings are printed to stderr. When processing fails, the program prints the error and exits with
code 1; wrong arguments exit with code 2.
Fonts
Fonts come from the @font-face rules of the stylesheet, then from the folder given with
-f. CSSMedia does not search the fonts installed on the computer. The 14 standard PDF
fonts are always available under the family names Times, Helvetica,
Courier, Symbol and ZapfDingbats. A declared family or a
family in the -f folder with the same name takes precedence.
CSSMedia loads OpenType and TrueType (.otf, .ttf), OpenType collections
(.otc, .ttc), WOFF 1.0 (.woff) and WOFF 2.0
(.woff2) fonts. The User Manual describes the @font-face descriptors, the
format() and tech() values that are supported, and the sources that are
skipped.
Using CSSMedia as a library
PdfGenerator.generate() writes the PDF. The constructor takes the optional font folder
and the optional XML catalog, and the warnings of the last run are in warnings:
const generator: PdfGenerator = new PdfGenerator("/path/to/fonts");
generator.generate("document.xml", "document.css", "document.pdf");
generator.warnings.forEach((warning: string): void => console.error(warning));