This page describes FOP-specific extensions to XSL-FO to insert custom code into PostScript files at key places so people doing mass-printing can insert media selection code and stuff like that into the PostScript stream.
Namespace URI
xmlns:ps="http://xmlgraphics.apache.org/fop/postscript"
fo:declaration
fo:declaration is to be extended to:
((color-profile)+, (ps:ps-setup-code)*)
ps:ps-setup-code
Content:
(#PCDATA)
Properties:
- name (optional)
The content of a ps-setup-code element is inserted into the PostScript stream right after the %%BeginSetup DSC comment and will itself be surrounded by two comments: %FOPBeginSetupCode (with the name as argument to the comment) and %FOPEndSetupCode.
Use case: The user can add special setup code, for example, initializing the InputAttributes dictionary used for media selection.
Add after fo:layout-master-set:
<fo:declarations> <ps:ps-setup-code name="media-selection"> <![CDATA[<< /MediaType (letterhead) >> setpagedevice]]> </ps:ps-setup-code> </fo:declarations>
fo:simple-page-master
fo:simple-page-master is to be extended to:
(region-body,region-before?,region-after?,region-start?,region-end?,(ps:ps-page-setup-code)*)
ps:ps-page-setup-code
Content:
(#PCDATA)
Properties:
- name (optional)
The content of a ps-page-setup-code element is inserted into the PostScript stream right after the %%BeginPageSetup DSC comment and will itself be surrounded by two comments: %FOPBeginPageSetupCode (with the name as argument to the comment) and %FOPEndPageSetupCode.
Use case: The user can add media selection setup code.
Example
<fo:simple-page-master master-name="letterhead" page-height="29.7cm" page-width="21cm" margin="2cm"> <fo:region-body/> <ps:ps-page-setup-code name="media-selection"> <![CDATA[<< /MediaType (letterhead) >> setpagedevice]]> </ps:ps-page-setup-code> </fo:simple-page-master>
will result in PostScript to:
[...] %%Page: 1 1 %%PageBoundingBox: 0 0 595 842 %%PageHiResBoundingBox: 0 0 595 842 %%PageResources: (atend) %%BeginPageSetup %FOPBeginPageSetupCode: media-selection << /MediaType (letterhead) >> setpagedevice %FOPEndPageSetupCode << /PageSize [595 842] /ImagingBBox null >> setpagedevice [1 0 0 -1 0 360] concat %%EndPageSetup %FOPBeginRegionViewport: xsl-region-body [...]
ps:ps-page-trailer-code-before
Content:
(#PCDATA)
Properties:
- name (optional)
The content of a ps-page-trailer-code-before element is inserted into the PostScript stream right before the %%PageTrailer DSC comment and will itself be surrounded by two comments: %FOPBeginPageTrailerCodeBefore and %FOPEndPageTrailerCodeBefore.
Use case: The user can add stapling commands (to the last page of the set of pages to be stapled together).
Example
<fo:simple-page-master master-name="letterhead" page-height="29.7cm" page-width="21cm" margin="2cm"> <fo:region-body/> <ps:ps-page-trailer-code-before name="staple-off"> <![CDATA[<</Staple 0 >> setpagedevice]]> </ps:ps-page-trailer-code-before> </fo:simple-page-master>
will result in PostScript to:
[...] showpage %FOPBeginPageTrailerCodeBefore <</Staple 0 >> setpagedevice %FOPEndPageTrailerCodeBefore %%PageTrailer [...]
ps:ps-setpagedevice
Content:
(#CDATA)
Where the page device dictionary is to be set, use the new ps-setpagedevice declaration instead of ps:ps-setup-code. This is because directly invoking the setpagedevice postscript command can cause the postscript interpreter on some printers to perform an init-graphics call. This init-graphics call can annoyingly cause unwanted blank pages to be printed.
The FOP postscript renderer now has the ability to hold an internal representation of the printer's page device dictionary. Any additional dictionary items added to this dictionary using the ps-setpagedevice mechanism result in a safe setting of parameters to the postscript page device dictionary. This new ps-setpagedevice mechanism provides a safer way to issue the same instructions to the printer. Cumulative duplicate dictionary values should never be issued more than once to the printer during postscript output rendition.
ps:ps-comment-before and ps:ps-comment-after
The requirement for the comment-before and comment-after is for post-processing the postscript output. Both these elements may only be declared as child nodes of fo:declarations and/or fo:simple-page-master.
In a fo:declarations context, ps-comment-before is placed in the postscript output just before the %%EndComments DSC comment in the header and ps-comment-after is placed just after the %%Trailer DSC comment in the footer of the output.
In a fo:simple-page-master context, ps-comment-before is placed in the postscript output just after the %%BeginPageSetup DSC comment and a ps-comment-after just after the %%PageTrailer DSC comment in each page of a simple page master referring page sequence.
Example Usage
<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:ps="http://xmlgraphics.apache.org/fop/postscript"> <fo:layout-master-set> <fo:simple-page-master master-name="A4" page-height="29.7cm" page-width="21cm" margin="2cm"> <ps:ps-setpagedevice name="lower tray"><![CDATA[ << /MediaPosition 4 >> ]]></ps:ps-setpagedevice> <ps:ps-comment-before>spm1 before page</ps:ps-comment-before> <ps:ps-comment-after>spm1 after page</ps:ps-comment-after> <fo:region-body/> </fo:simple-page-master> <fo:simple-page-master master-name="A4a" page-height="29.7cm" page-width="21cm" margin="2cm"> <ps:ps-setpagedevice name="upper tray"><![CDATA[ << /MediaPosition 1 >> ]]></ps:ps-setpagedevice> <ps:ps-comment-before>spm2 before page</ps:ps-comment-before> <ps:ps-comment-after>spm2 after page</ps:ps-comment-after> <fo:region-body background-color="orange"/> </fo:simple-page-master> <fo:page-sequence-master master-name="complex"> <fo:repeatable-page-master-reference master-reference="A4" maximum-repeats="1"/> <fo:repeatable-page-master-reference master-reference="A4a" maximum-repeats="1"/> <fo:repeatable-page-master-reference master-reference="A4"/> </fo:page-sequence-master> </fo:layout-master-set> <fo:declarations> <ps:ps-setpagedevice name="autofeed"><![CDATA[ << /ManualFeed false >> ]]></ps:ps-setpagedevice> <ps:ps-comment-before>header comment</ps:ps-comment-before> <ps:ps-comment-after>footer comment</ps:ps-comment-after> </fo:declarations> <fo:page-sequence master-reference="complex"> <fo:flow flow-name="xsl-region-body"> <fo:block>Hello World!</fo:block> <fo:block break-before="page"/> <fo:block>Hello World!</fo:block> <fo:block break-before="page"/> <fo:block>Hello World!</fo:block> </fo:flow> </fo:page-sequence> </fo:root>
Additional ideas and thoughts
That should cover most of the common requirements in this area. If anyone needs custom code in the Trailer or PageTrailer this is easily added later.
The most important thing here is probably that the generated PostScript code is generally well-delimited with DSC comments and FOP-specific comments so it is easy for people post-processing PostScript files to modify them easily. Some people will only add a DSC comment into the PostScript file instead of the actual media selection code. This comment will then be expanded later.