Forum How do I...?

The new Control Interface

joelmeador
Is there a document detailing the control API for this thing? I tried to reverse engineer it when it was first announced from the Java client, but it was super hinky and unclear what the prince process expected and what the failure states were. So @mikeday, how do I use the new control interface when I am not using one of the pre-packaged wrapper libraries? :)

Try DocRaptor - PrinceXML web service and official PrinceXML partner

mikeday
The new Prince control protocol can be accessed by running "prince --control".

It is a synchronous bidirectional protocol that consists of a sequence of "chunks" sent via the standard input and output streams.

Each chunk contains a sequence of bytes with a length and a three letter tag. Here is an example "version" chunk to demonstrate the syntax:
ver 15
Prince 20161219

This chunk has a tag "ver" (all tags are three ASCII characters) followed by a space, then the length of the data expressed as a decimal number, then a newline character, then the data itself (15 bytes), then another newline (not part of the data).

This "version" chunk is emitted by Prince when the control protocol begins and can be used to check the Prince version and confirm that communication is functioning as expected. Prince will then wait for jobs to be submitted.

If a chunk contains no data then the length is zero and the chunk ends with the newline immediately following the length. In fact the length itself may be omitted, making this a perfectly valid chunk:
end

This "end" chunk consists of three letters and a newline character and can be used to terminate the Prince process when there are no further jobs to process.

Currently the control protocol includes the following chunk types sent by Prince:

- ver, sent at startup
- pdf, a generated PDF file
- log, the complete output log for the job including all errors and warnings
- err, errors relating to the control protocol itself

And these chunks sent by the caller:

- job, the description of a requested conversion job, expressed in JSON
- dat, a file resource needed by the job
- end, to terminate the control connection

A typical interaction looks like this:

Prince: ver
Caller: job
Caller: dat
Caller: dat
Prince: pdf
Prince: log
Caller: end

Instead of sending the final "end" chunk the caller may choose to submit another "job" chunk and continue converting documents. The protocol is synchronous so replies simply match requests in order.

The final piece of the puzzle is the format of the JSON job description, which I will post shortly. :)
mikeday
As mentioned earlier, the "job" chunk contains a description of the conversion job represented in JSON format, which can be followed by an optional sequence of "dat" chunks containing file data which is needed by the job, eg. HTML documents, style sheets, PDF attachments, or whatever.

The number of "dat" chunks is specified by the "job-resource-count" field in the job description, and these files can be accessed via a special job-resource URL scheme, eg. job-resource:0 will access the content of the first "dat" chunk, then job-resource:1, job-resource:2, etc. This allows any number of resources to be provided inline with the request and removes the need to create actual temporary files.

The JSON job description has several nested objects with fields corresponding to Prince options:
{
    "input": { <input options> },
    "pdf": { <pdf options> },
    "metadata": { <metadata options> },
    "raster": { <raster options> },
    "job-resource-count": <int>
}

The input options and job-resource-count are mandatory, the rest are optional and will default to the normal values.

The input options includes these fields:
{
    "src": <single URL or list of URLs>,
    "type": <string>,
    "base": <string>,
    "media": <string>,
    "styles": [ <list of URLs> ],
    "scripts": [ <list of URLs> ],
    "default-style": <bool>,
    "author-style": <bool>,
    "javascript": <bool>,
    "xinclude": <bool>,
    "xml-external-entities": <bool>
}

Only the src field is required, the rest can be left as defaults.

Now we can make some simple job descriptions, eg. to convert a single HTML file:
{
    "input": {
        "src": "/path/to/input.html"
    },
    "job-resource-count": 0
}

This can be sent as a single "job" chunk and Prince will respond with a "pdf" chunk if the conversion succeeded and a "log" chunk.

Or you can convert a HTML document without saving it to a temporary file:
{
    "input": {
        "src": "job-resource:0"
    },
    "job-resource-count": 1
}

This requires the "job" chunk to be followed by a "dat" chunk that contains the HTML and then Prince will respond as before.
mikeday
The pdf options object includes these fields:
{
    "color-options": "auto" | "use-true-black" | "use-rich-black",
    "embed-fonts": <bool>,
    "subset-fonts": <bool>,
    "artificial-fonts": <bool>,
    "force-identity-encoding": <bool>,
    "compress": <bool>,
    "encrypt": {
        "key-bits": 40 | 128,
        "user-password": <string>,
        "owner-password": <string>,
        "disallow-print": <bool>,
        "disallow-modify": <bool>,
        "disallow-copy": <bool>,
        "disallow-annotate": <bool>
    },
    "attach": [ <list of URLs> ],
    "pdf-profile": <string>,
    "pdf-output-intent": <URL>,
    "fallback-cmyk-profile": <URL>,
    "color-conversion": "none" | "full"
}

The metadata options object includes these fields:
{
    "title": <string>,
    "subject": <string>,
    "author": <string>,
    "keywords": <string>,
    "creator": <string>
}

The raster options object includes these fields:
{
    "dpi": <integer>
}

And that's about it! Let me know if you have further questions or if anything doesn't work. :)
joelmeador
Thanks for the explanation. Seems like I've got a lot of homework to do this holiday season. :D

Try DocRaptor - PrinceXML web service and official PrinceXML partner

nsnsolutions
Does this interface support the creation of Raster images? i see the node in the job schema above but when testing, prince writes PDF data each time. Are there additional requirements to produce raster images?
mikeday
The control interface doesn't support raster images yet, the raster properties are just to control rasterisation of SVG images included in the PDF file.
nsnsolutions
Thank You. Are there any plans to add raster support? If so, is there any timeline around such?
mikeday
No timeline yet, it requires some extensions to the protocol.