Special Techniques

1. Drawing lines in xsl-fo
2. How to display a check box in XSL-FO
3. Copying out the XML input?

1.

Drawing lines in xsl-fo

Ken Holman



>>I'm trying to put a line on a page with xsl-fo.
>>can i define the excact X and y points to do that?

I wondered if one could use rules in absolutely positioned containers.

The example below in Antenna House draws a small rule in the top left corner of each page except the last page, where a small rule is drawn in the top right corner. I'll leave it to Jochen to work out the precise positioning. My block-container dimensions are rather arbitrary as I can't take time to make them very precise.

Note the page sequence is defined with particular behaviour for the last page in the sequence, and I'm using static content targeted for each page to define an absolutely-positioned block-container.

Ugly, but it works ...

<?xml version="1.0" encoding="utf-8"?><!--jochen.fo-->
<root xmlns="http://www.w3.org/1999/XSL/Format"
       font-family="Times" font-size="20pt">

<layout-master-set>
   <simple-page-master master-name="frame"
     page-height="297mm" page-width="210mm"
     margin-top="15mm" margin-bottom="15mm"
     margin-left="15mm" margin-right="15mm">
     <region-body region-name="frame-body"/>
     <region-start region-name="frame-before" extent="0mm"/>
   </simple-page-master>
   <simple-page-master master-name="frame-last"
     page-height="297mm" page-width="210mm"
     margin-top="15mm" margin-bottom="15mm"
     margin-left="15mm" margin-right="15mm">
     <region-body region-name="frame-body"/>
     <region-start region-name="frame-last-before" extent="0mm"/>
   </simple-page-master>
   <page-sequence-master master-name="frames">
     <repeatable-page-master-alternatives>
       <conditional-page-master-reference master-reference="frame-last"
         page-position="last"/>
       <conditional-page-master-reference master-reference="frame"/>
     </repeatable-page-master-alternatives>
   </page-sequence-master>
</layout-master-set>

<page-sequence master-reference="frames">
   <static-content flow-name="frame-before">
     <block-container absolute-position="fixed"
       top="1cm" left="1cm" bottom="26cm" right="18cm">
       <block line-height="3px">
         <leader rule-thickness="3px" leader-length="5mm"
                 leader-pattern="rule"/>
       </block>
     </block-container>
   </static-content>

   <static-content flow-name="frame-last-before">
     <block-container absolute-position="fixed"
       top="1cm" left="18cm" bottom="26cm" right="1cm">
       <block line-height="3px">
         <leader rule-thickness="3px" leader-length="5mm"
                 leader-pattern="rule"/>
       </block>
     </block-container>
   </static-content>

   <flow flow-name="frame-body">

     <block break-before="page">This is a test</block>
     <block break-before="page">This is a test</block>
     <block break-before="page">This is a test</block>
     <block break-before="page">This is a test</block>

   </flow></page-sequence></root>

2.

How to display a check box in XSL-FO

Ken Holman



>hi list, would anyone tell me how to display a checkbox in XSL-FO
(which will be transformed to PDF? 

I draw a bordered 1em inline-container aligned to the after edge of the line:

     <inline-container width="1em" height="1em"
                       alignment-adjust="text-after-edge"
                       border-style="solid" border-width="1px"/>

Note that the default alignment sits the container on top of the text baseline, which is usually too high.

3.

Copying out the XML input?

Eliot Kimber


> I'm trying to create a document that contains the incoming XML exactly
> as it appears, with tags, attributes and everything.
>  <fo:block>
>   <xsl:copy-of
> select="/"/>
>  </fo:block><

You can't just put the elements literally out into the FO--the FO processor will have no idea what to do with them. You have to convert the input elements to escaped text, which can do with something like this:

<fo:block linefeed-treatment="preserve"
  white-space-treatment="preserve"
  white-space-collapse="false"
 >
  <xsl:apply-templates select="/" mode="copy-markup"/>
</fo:block>

<xsl:template match="*" mode="copy-markup"
   <xsl:text>&lt</xsl:text>
   <xsl:value-of select="name(.)"/>
   <xsl:apply-templates select="@*" mode="copy-markup"/>
   <xsl:text>&gt;</xsl:text>
   <xsl:apply-templates mode="copy-markup"/>
   <xsl:text>&lt;</xsl:text>
   <xsl:value-of select="name(.)"/>
   </xsl:text>&gt;</xsl:text>
</xsl:template>

<xsl:template match="@*" mode="copy-markup">
  <xsl:text>
   </xsl:text><!-- newline and indention for each attribute -->
  <xsl:value-of select="concat(name(), '=')"/>
  <xsl:text>"</xsl:text>
  <xsl:value-of select="string(.)"/>
  <xsl:text>"</xsl:value-of><!-- NOTE: doesn't handle quotes in 
attribute values -->
</xsl:template>

<xsl:template match="text()" mode="copy-markup">
   <xsl:value-of select="."/>
</xsl:template>

This should get you pretty close. This is for XSLT 1.0 and doesn't take namespaces into account. A more complete, namespace-aware solution would be easier to do with XSTL 2.0. I also didn't account for processing instructions or comments, but you can probably figure that part out.