Chapter 8: Miscellaneous useful features
8.1. pageNumber
As you'd expect from the name, this tag adds page numbers to your document.
This has nothing tricky to remember - all you have to do is put the a
<pageNumber/>
tag where you want the page number to appear.
8.2. name, namedString and getName
The <name>
and <namedString>
tags allow you to set a variable as you would in a programming language. You can then retrieve
this to put in another place by using the <getName>
tag. You
can do this as many or as few times as you need - so it is handy for things like headers and
footers, or for items that you see changing many times over the life of your document such as
version or revision numbers. If you set them using a <name>
tag, you only have to revise
them in one place every time they change, rather than having to plough through the document
changing them manually in each location and inevitably missing one.
<name>
has three attributes: id
and value
are required, but type
is optional.
<namedString>
has five main attributes: id
is required as the name of the variable. This
tag is not self closing and the value to be assigned should be between <namedString>
and <namedString/>
.
The new
attribute may be set to "1" to indicate that the definition should happen only on the
first time this variable is seen. The discard
attribute may be set to "1" to indicate that the
definition should happen immediately and not at render time and the value is discarded. The indexName
attribute may be set to the name of another variable which should be used as an index into the main
variable where the value should be stored.
<getName>
only has three attributes the first id
is required so that it knows which name to "yank".
The default
attribute may be used to supply a default value (in case the variable is not yet defined).
Finally the indexName
attribute may be used to specify an index name that is to be looked up to index
into the id variable allowing complex programming see
test_052_pagenum.rml.
In practice, it would look something like this example:
<stylesheet>
<initialize>
<name id="YourVariableName"
value="Type anything you want between these quotes..."/>
<namedString id="x">0</namedString>
<namedString id="anothervariable" indexName="x">value of anothervariable</namedString>
</initialize>
</stylesheet>
<story>
<para>
<b><getName id="YourVariableName"/></b>
<b><getName id="anothervariable" indexName="x"/></b>
</para>
</story>
You can also use the <name>
tag inside the story of a
document. In this case, as well as setting the value for the variable,
it is also displayed on the page (i.e. the name has a "textual value").
8.3. Seq, seqReset, seqChain and SeqFormat
The "seq" in <seq>
, <seqDefault>
and <seqReset>
stands for sequence. These tags are all used for
paragraph numbering (or indeed anything that requires numbering items in a sequence, such as list
items or figures and illustrations).
This is how they look in use:
<seq/>
<seqDefault id="myID"/>
<seqReset/> or <seqReset id="myID"/>
<seqChain order="id0 id1 id2...idn"/>
<seqFormat id="myID" value="i"/>
Each time you call <seq/>
, its value is automatically incremented.
With <seqReset>
, the id
is an optional attribute. However, it is still best to use it to save confusion.
The <seqChain order="id0 id1 id2"/>
tag is used to make multi sequence
use easier. When sequence id0
is changed sequence id1
is reset; likewise when sequence id1
is changed sequence id2
is reset and so on for the identifiers in the order
attribute.
The tag <seqFormat id="myID" value="i"/>
is used to associate a numbering
format to myID
. The allowed values for the value
attribute are given in the table below.
Value | Meaning |
---|---|
1 | Decimal |
i | Lowercase Roman |
I | Uppercase Roman |
a | Lowercase Alphabetic |
A | Uppercase Alphabetic |
Here is an example that shows <seq/>
, <seqReset>
and <seqDefault>
in use:
EXAMPLE 6
<?xml version="1.0" encoding="iso-8859-1" standalone="no" ?>
<!DOCTYPE document SYSTEM "../rml.dtd">
<document filename="example_6.pdf">
<template>
<pageTemplate id="main">
<frame id="first" x1="72" y1="72" width="451" height="698"/>
</pageTemplate>
</template>
<stylesheet>
</stylesheet>
<story>
<h1>
seq in seq, seqDefault and seqReset
</h1>
<para>copied: <seq id="spam"/>, <seq id="spam"/>, <seq id="spam"/>.
Reset<seqReset id="spam"/>. <seq id="spam"/>, <seq id="spam"/>,
<seq id="spam"/>.</para>
<h2>
<i>simple use of seq</i>
</h2>
<para>
First seq: <seq/>
</para>
<para>
Second seq: <seq/>
</para>
<spacer length="6"/>
<para>
<seqReset/>
We have just done a <seqReset"/>
</para>
<spacer length="6"/>
<para>
First seq after seqReset: <seq/>
</para>
<para>
second seq after seqReset: <seq/>
</para>
<spacer length="6"/>
<para>
If you are going to use multiple seq tags, you need to use the "id" attribute.
</para>
<h2>
<i>Better use of seq</i>
</h2>
<para>
<seqDefault id="test"/>
We have just done a <seqDefault id="test"/>
</para>
<para>
<seqReset id="test"/>
We have just done a <seqReset id="test"/>
</para>
<spacer length="6"/>
<para>
First seq: <seq id="test"/>
</para>
<para>
Second seq: <seq id="test"/>
</para>
<spacer length="6"/>
<para>
<seqReset id="test"/>
We have just done a <seqReset id="test"/>
</para>
<spacer length="6"/>
<para>
First seq after seqReset: <seq id="test"/>
</para>
<para>
second seq after seqReset: <seq id="test"/>
</para>
<h2>
<i>Using two seqs independently</i>
</h2>
<para>
<seqReset id="testOne"/>
We have just done a <seqReset id="testOne"/>
</para>
<para>
<seqReset id="testTwo"/>
We have just done a <seqReset id="testTwo"/>
</para>
<spacer length="6"/>
<para>
First seq for testOne: <seq id="testOne"/>
</para>
<para>
Second seq for testOne: <seq id="testOne"/>
</para>
<spacer length="6"/>
<para>
First seq for testTwo: <seq id="testTwo"/>
</para>
<para>
Second seq for testTwo: <seq id="testTwo"/>
</para>
<spacer length="6"/>
<para>
<seqReset id="testOne"/>
We have just done a <seqReset id="testOne"/>
</para>
<spacer length="6"/>
<para>
First seq after seqReset for testOne: <seq id="testOne"/>
</para>
<para>
second seq after seqReset for testOne: <seq id="testOne"/>
</para>
<spacer length="6"/>
<para>
First seq after seqReset for testTwo: <seq id="testTwo"/>
</para>
<para>
second seq after seqReset for testTwo: <seq id="testTwo"/>
</para>
<spacer length="15"/>
<para>
Notice how resetting testOne doesn't affect testTwo at all.
</para>
</story>
</document>
Figure 9: Output from EXAMPLE 6
One more sophisticated use for using these tags is for multiple page counters. If you have a document
where you need different sections numbered separately from the main body of a document (perhaps for
introductory matter such as the contents and preface of a book), this can be done with a named seq
tag.
The page counter as used by the <pageNumber>
tag is a 'unique value'
which depends on the actual physical number of pages. If rather than using a <pageNumber>
tag, you
instead use something like <seq id="pageCounter"/>
, you have the ability to use
<seqReset id="pageCounter"/>
in between sections so that each chapter has pages numbered from the start
of that chapter rather than the start of the document. If you use a different template for each chapter,
this can then give you page numbers in the format "1-12" rather than just "12" (where you are on page 12
of the document, which is page 12 of chapter 1).
8.4. Entities
In example 6, we saw our first use of entities.
In RML, you can't use the characters "<", ">"
or "&" inside any display elements such as
<drawString>
or <para>
.
If you do, rml2pdf will assume that they are tags and attempt to interpret them. Since they won't be
valid RML tags, you will just end-up getting an error message along the lines of
"Error: Start tag for undeclared element <YourNonValidTag>".
To get around this, you should use "entities".
When you need to use "<", replace it with "<",
when you need to use ">;", replace it with ">",
and when you need to use "&", replace it with "&".
8.5. Aliases
Aliases allow you to assign more than one name to a paragraph style.
The alias tag has two required attributes - id
and value
.
Example:
<alias id="alreadyDefinedStyleName" value="myNewStyleName"/>
This can be useful in a number of ways.
You can give a more descriptive name to a style. So you can define a number of paragraph styles
called things like "ItalicBold" or
"DesignerOneParagraphStyleTwo" in the
<stylesheet>
for your <document>
.
You can then assign aliases to these styles using names that describe the role they fill in your
document such as "pictureCaption",
"abstract",
"acknowledgement" and so on.
If at any point you decide to change the style for that kind of paragraph, you can then change it in one alias rather than in every individual paragraph that uses that style.
8.6. CDATA -- unparsed character data
CDATA
is a standard XML tag which indicates to the parser (in this case rml2pdf) to ignore anything
inside the CDATA
section. It shouldn't parse it or process it in any way - just display it.
A CDATA
section is started with the characters
"<![CDATA["
and is closed off with the characters "]]>"
It can appear inside any flowable -
though it is most useful inside a <pre>
tag.
CDATA
may be useful in places where you have large quantities of "<
" and ">
" characters
that you want to display in your PDF, and that you would rather not have to convert them all to
"<
" and ">
" entities. Quoting sections of RML, XML, or HTML code is an example of a good
place to use CDATA
- if you needed to revise the code example at a later date, you would have
to convert the characters in every tag into entities. CDATA
saves you having to do this.
However, you should only use CDATA
when necessary. If you are using other XML tools, they will
also ignore anything inside a CDATA
section.
Example:
<xpre>
<![CDATA[
Anything could go here. <non_existant_tags/>, "&" signs.
Whatever you want. RML ignores it.
]] >
</xpre>
8.7. Plug-ins: plugInGraphic and plugInFlowable
Both <plugInGraphic>
s and
<plugInFlowable>
s allow you to use objects from
outside your RML document.
plugInGraphic
A plugInGraphic
identifies a function (callable) in a module which
takes a canvas and a data string as arguments and presumably draws
something on the canvas using information in the data string.
Example:
when executed results in effectively the following execution sequence:
using the current canvas object.<PlugInGraphic>
has two mandatory attributes: module
and function
. It is used in
the <pageGraphics>
section of your document.
plugInFlowable
A <plugInFlowable>
identifies a function (callable) in a module which takes a canvas data
string as an argument and returns a flowable object:
Example:
when executed results in effectively the execution sequence:
using the current canvas object.<plugInFlowable>
has two mandatory attributes: module
and function
. It is also used
in the <pageGraphics>
section of your document.
8.8. Integrating with PageCatcher: catchForms, doForm and includePdfPages
You can use our product PageCatcher to capture individual pages from an external PDF file (e.g. application forms, government forms, annual reports and so on). Extracting the required pages with PageCatcher will most often be a one-off design-time step. Once PageCatcher has extracted a page, it archives it in a data file as formatted form data. (The default name for this file is "storage.data").
If you have full production versions of both RML2PDF and PageCatcher you
can use the <catchForms>
tag to import
all forms from a PageCatcher storage file for use in your RML document.
Example:
This example takes the form called PF0 (a page "caught" by PageCatcher and stored in the file storage.data) and draws it into your document as a page backdrop.
The <catchForms>
tag is a drawing operation, and can occur anywhere in
your RML document where a <doForm>
tag can
occur. (For example, you can use a <catchForms>
inside the flow of a story
by using it inside an <illustration>
).
The <catchForms>
tag has one mandatory argument (storageFile) which gives
the name of the PageCatcher storage file to extract the form from.
One small point to remember is that if you are using multiple forms from the
same data file, you only need to use the actual <catchForms>
tag once.
To actually put the captured data into your document, you would use multiple
instances of the <doForm>
tag. Notice how this works in the example below:
<illustration width="451" height="698">
<pageGraphics>
<catchForms storageFile="samples.data"/>
<doForm name="PF0"/>
</pageGraphics>
</illustration>
<illustration width="451" height="698">
<pageGraphics>
<doForm name="PF1"/>
</pageGraphics>
</illustration>
If you do use repeated <catchForms>
tags to point at the same data file, you
will get an error message similar to the one below.
ValueError: redefining named object: 'FormXob.PF0'
If this is the case, find the places where you are using the second and subsequent
<catchForms>
tags and delete them, leaving only the <doForm>
tags. (Of course,
this doesn't apply to any <doForm>
which are pointing at other data files. They
would still need their own initial <catchForms>
tags).
[Note: For the <catchForms>
tag to work, you must have PageCatcher
installed. In addition, your PageCatcher must be the full version with a .py or
.pyc file. The *.exe version of PageCatcher will not work with RML2PDF.
If you get the error message "ImportError: catchForms tag requires the PageCatcher
product http://www.reportlab.com", then you either do not have PageCatcher
installed, or have the wrong version].
The includePdfPages tag
In some circumstances, you may not know how many pages there will be in the PDF
file you need to pageCatch. This is the case which
<includePdfPages>
tag was designed for.
<includePdfPages>
is a generic flowable, which means that it can appear at any
point in the story.
In its simplest form, an includePdfPages
tag will look like this:
This will take the PDF file called "mypdffile.pdf", use pageCatcher behind the scenes and include every page in the PDF file in your output. There is also an optional "pages" attribute. This can have either individual pages or ranges. The following are all valid (providing the PDF file is long enough).
<includePdfPages filename="mypdffile.pdf"/>
<includePdfPages filename="mypdffile.pdf" pages="1"/>
<includePdfPages filename="mypdffile.pdf" pages="1,2,3"/>
<includePdfPages filename="mypdffile.pdf" pages="2,1,1,2,2"/>
<includePdfPages filename="mypdffile.pdf" pages="1-5"/>
<includePdfPages filename="mypdffile.pdf" pages="1,2,4-5"/>
There are a number of differences between this tag and the other
PageCatcher related tags. Unlike the others, includePdfPages
doesn't
require you to pre-pagecatch the file you intend to use (so saving you
an additional step). It also differs in that the imported PDF gets
drawn "over the top" of your exiting document, rather than being used
as a background underneath your existing page. So if you have a
header or footer in your page template, the included PDF page will
overwrite it.
How includePdfPages works with templates
When you have an includePdfPages
tag in your RML file, RML outputs a
page break before the first new page, leaving you on the same
page as the last imported one. This allows you to do template switching:
<setNextTemplate>
<setNextTemplate name="myIncludePagesTemplate"/>
<includePdfPages filename="mypdffile.pdf" pages="1,2,3"/>
<setNextTemplate name="myNormalTemplate"/>
<nextFrame/>
<para>
This text appears on the next normal (non-included) page of your
document)
</para>
This snippet switches to a new page template for use with your
included pages, adds in the first three pages from your PDF file,
switches back to what is presumably the template you have been using
throughout the rest of the document, and outputs a line of text into
the next "normal" page of your document. If you don't want any headers
or footers behind your PDF pages, define a page template called
something like "blank" (in the <template>
section at the head of your document) with a single frame and no
decoration on it and use that. If you are content for your included
pages to appear over the template you have been using on the previous
pages (if the included pages don't have any headers and footers and
have large enough margins not clash with the ones you are using in
your document, for example), then you can skip both of the
<setNextTemplate>
tags completely.
The <nextFrame>
tag is used because the
includedPdfPages
places you at the top of the last included PDF
page. This allows you to flow paragraphs or other flowables down your last
page. This may be useful if you want to place text in a form, or use some
other pre-prepared background for your text. If all you want to do is just
drop in a pre-made page, you need this nextFrame to kick you into the next
normal page and continue with your document normally
Look in section 7.6 ("Using multiple frames") for more info on the
<nextFrame>
and <setNextTemplate>
tags. Look at the file
test_016_pagecatcher.rml
for an example of this tag in use.
These attributes control the <includePdfPages>
tag:
filename | filename to include |
---|---|
pages | The page list |
template | optional page template name |
outlineText | optional outline text |
outlineLevel | optional outline level |
outlineClosed | true for closed outline |
leadingFrame | (yes | no | 0 | 1 | notAtTop): no if you don't want a page throw before the first page |
isdata | boolean true if the file is a pageCatcher .data file |
orientation | (0 | portrait | 90 | landscape | 180 | 270 | auto) auto means use the file implied layout |
8.9. Outlines
A navigational aid for PDFs. It can go in either graphics
or in a story
. (Assigning outline
levels to parts of your document
(such as
paragraphs
) allows you to build up a hierarchical structure for your
document).
The level
specifies how deep in the outline the entry appears. The default level is 0.
closed
, if set, hides any children of this outline entry by default. Closed takes Boolean arguments.
Example:
<outlineAdd>First outline entry</outlineAdd>
<outlineAdd level="1">sub entry</outlineAdd>
<outlineAdd closed="true">Second outline entry 2</outlineAdd>
<outlineAdd level="1">sub entry 2</outlineAdd>
They can also be added using includePdfPages
tag by using the outlineText
attribute
Please see test_016_pagecatcher.rml for a working example of outlines in use
8.10. Form field tags
An important class of reports contains lots of fields to be traditionally filled in manually by
users, like for application forms and similar cases. Sometimes though, these fields are already
filled in by some computational process and the user might only need to sign the entire form
before leaving it with a bank clerk or sending it off to some destination. RML supports
creating both kind of reports by providing a set of special-purpose tags to create such form
elements (or fields, widgets...) quite easily. These tags are named
<checkBox>
, <textBox>
and
<letterBoxes>
and are described in the rest of this section.
All these form elements share a lot of features when it comes to what they look like in the
document. They all appear as a rectangular shape with some background and border colour, plus
some width for the border itself. They also have some sort of text label attached to this
rectangle to describe the field's purpose in the context of the report to the human reader.
The text inside the field as well as the one in the attached label also should have the usual
properties like fontname and size and colour. All form field elements have a boxStyle
attribute
that can be used to group attribute names and values and reuse them in many field elements with
much less typing effort.
But there are also specific features that distinguish these form elements from each other. A checkbox does not contain text, but only a cross (when checked), and a textbox contains one or more lines of text with different possible alignments, while letterboxes are used for single line mono-space text with visible subcompartments for each letter.
Checkboxes
By default, checkboxes have a very simple style similar to UK bank application forms - an outer rectangle and a cross which exactly fills it when checked. The attributes control the appearance.
It is also possible to supply your own pair of bitmap images
which will be used instead of the default drawing mechanism - this
could be used to provide 3d effects, tick-and-cross icons or
whatever is needed. To make use of this, set the two attributes
graphicOn
and graphicOff
to point to two bitmap files on the
disk; these will be used in preference to the default appearance.
Note that they will be stretched to the boxWidth and boxHeight
stated, so it is important to set the same aspect ratio as the
underlying image. Also, remember the printing intent - a 24 pixel
bitmap drawn to occupy a 12 point space on a form will be visibly grainy
on a good quality printer, but may be fine on an inkjet.
Because checkboxes do not contain text it can be argued that
when they are to be displayed as checked the cross' colour
should be the same as the border colour. Equally well it can
be argued that it should be the same colour used for text in
textboxes. To provide both options checkboxes have an additional
colour attribute named checkStrokeColor
which will be used
for the cross instead of the border colour if the former is provided.
Note that the label attached to a checkbox is limited to three lines of text now and always appears at the right margin of the box, but this might be generalised in future versions. The label is expected to be vertically centered with the box no matter how many lines it is composed of.
The following code creates a row of sample checkboxes providing different values for the most relevant attributes:
EXAMPLE 7
<checkBox x="0cm" y="0cm" checked="0"/>
<checkBox x="1.5cm" y="0cm" checked="1"/>
<checkBox x="3cm" y="0cm"
boxWidth="0.75cm" boxHeight="1cm"
checked="1"/>
<checkBox x="4.5cm" y="0cm"
boxWidth="0.75cm" boxHeight="1cm"
lineWidth="0.1cm"
checked="1"/>
<checkBox x="6cm" y="0cm"
lineWidth="0.1cm"
boxFillColor="yellow" boxStrokeColor="green"
checked="1"/>
<checkBox x="7.5cm" y="0cm"
lineWidth="0.1cm"
boxFillColor="yellow" boxStrokeColor="green"
checkStrokeColor="red"
checked="1"/>
<checkBox x="9cm" y="0"
line1="desc 1"
line2="desc 2"
checked="1"/>
<checkBox x="11.5cm" y="0"
line1="desc 1"
line2="desc 2"
line3="desc 3"
checked="1"/>
Figure 10: Output from EXAMPLE 7
Textboxes
A textbox contains one, but often more lines of
text, like in an address field. (Of course, it can also contain no text at all,
like for a signature field.) Sometimes it is not clear in advance exactly how
much text will go into one such field. Therefore, textbox fields in RML provide
a means for automatically resizing the fontsize to shrink the contained text by
exactly what is needed to make it fit into the box. This is a two-step process
that first tries to shrink the fontsize to make the text fit horizontally.
If that is not enough, it is further shrinked to make it also fit vertically.
This process is controlled using the attribute shrinkToFit
.
Because human readers are very sensible to reading text and get quickly irritated when it does not feel "right", there is a default amount of space (1 point) left between the text and any of the borders of the box, which will be respected by the resizing mechanism. This is hardcoded now, but might become another attribute in the future.
The following code creates a row of sample textboxes illustrating different values for the most relevant attributes as well as the auto-resizing text feature:
EXAMPLE 8
<illustration width="18cm" height="2cm">
<textBox x="0cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
label="labeled textbox">some text</textBox>
<textBox x="3.5cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
boxFillColor="yellow" boxStrokeColor="blue"
label="colorful textbox">some text</textBox>
<textBox x="7cm" y="0cm"
lineWidth="0.1cm"
boxWidth="3cm" boxHeight="1cm"
boxFillColor="yellow" boxStrokeColor="blue"
label="bold textbox">some text</textBox>
<textBox x="10.5cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
lineWidth="0.1cm"
boxFillColor="yellow" boxStrokeColor="blue"
fontName="Times-Bold"
fontSize="14"
label="textfancy textbox">some text</textBox>
</illustration>
Figure 11: Output from EXAMPLE 8
The following code creates a row of sample textboxes illustrating the auto-resizing text feature:
EXAMPLE 9
<textBox x="0cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
fontSize="14"
label="no resizing">some text</textBox>
<textBox x="3.5cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
fontSize="14"
label="horiz. resizing">some more text</textBox>
<textBox x="7cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
shrinkToFit="1"
fontSize="14"
label="vert. resizing">some text
some text
some text</textBox>
<textBox x="10.5cm" y="0cm"
boxWidth="3cm" boxHeight="1cm"
shrinkToFit="1"
fontSize="14"
label="horiz./vert. resizing">some more text
some text
some text
some text</textBox>
Figure 12: Output from EXAMPLE 9
Letterboxes
Letterboxes are intended for single-line text fields where each letter is contained in a subcell, clearly seperated from neighbouring cells. This is often seen on official forms where people are expected to write letters of a word at predefined positions. RML provides such letterboxes, too, and they behave mostly like textboxes, but show some significant differences, too.
Usually, the overall width of a form field element is defined by the mandatory
boxWidth
attribute. For letterboxes, though, this is an optional attribute and
specifies the width of a subcell containing one letter. The resulting width
of the entire box is defined as a multiple of that boxWidth
attribute with another
one named count
, which is a mandatory attribute.
The following code creates a row of sample letterboxes showing basic attributes:
EXAMPLE 10
<letterBoxes x="0cm" y="7.5cm"
count="12">letterboxes</letterBoxes>
<letterBoxes x="0cm" y="6cm"
count="12">more letterboxes</letterBoxes>
<letterBoxes x="0cm" y="4.5cm"
boxWidth="0.75cm"
count="12">letterboxes</letterBoxes>
<letterBoxes x="0cm" y="3cm"
lineWidth="0.1cm"
boxFillColor="yellow" boxStrokeColor="blue"
label="some label"
count="12">letterboxes</letterBoxes>
<letterBoxes x="0cm" y="1.5cm"
lineWidth="0.1cm"
boxFillColor="yellow" boxStrokeColor="blue"
label="some label"
fontName="Courier-Bold"
fontSize="14"
count="12">letterboxes</letterBoxes>
<letterBoxes x="0cm" y="0cm"
lineWidth="0.1cm"
boxWidth="0.75cm" boxHeight="0.75cm"
boxFillColor="yellow" boxStrokeColor="blue"
label="some label"
fontName="Times-Bold"
fontSize="14"
count="12">letterboxes</letterBoxes>
Figure 13: Output from EXAMPLE 10
There may also be instances where you want obvious dividers between
each subcell, but you don't want entirely separate boxes. Letterboxes
have something that allows for this - the optional combHeight
attribute.
In a 'standard' letterBoxes element (ie one where the combHeight
isn't
specified), the divider between each individual subcell is a line
which fills the whole height of the letterBoxes box. If you specify
the combHeight
, you can vary the height of this line. This attribute
must be a number between zero and one, where "0" means no divider at
all and "1" means one that is the whole height of the letterboxes
element (and therefore "0.25" is a quarter of the height and so on).
The following code creates a row of sample letterboxes showing the combHeight attribute in use:
EXAMPLE 11
<letterBoxes x="0cm" y="0cm"
combHeight="0"
count="4">comb</letterBoxes>
<letterBoxes x="3.75cm" y="0cm"
combHeight="0.25"
count="4">comb</letterBoxes>
<letterBoxes x="7.5cm" y="0cm"
combHeight="1"
count="4">comb</letterBoxes>
<letterBoxes x="11.25cm" y="0cm"
lineWidth="0.1cm"
boxWidth="0.75cm" boxHeight="0.75cm"
boxFillColor="yellow" boxStrokeColor="blue"
label="combHeight"
fontName="Times-Bold"
fontSize="14"
combHeight="0.5"
count="4">comb</letterBoxes>
Figure 14: Output from EXAMPLE 11
Using styles with form field elements
As we've already mentioned, checkBox
, textBox
and letterBoxes
all allow you to
re-use styles in a similar way to the way you can re-use styles with paragraphs with
the boxStyle
tag. Like the other style tags
(paraStyle
and
blockTableStyle
), boxStyle
lives in the
stylesheet
section, near the start of your document.
boxStyle
style can have the following attributes:
name:
This is the required attribute which allows you to refer this style by name.
alias:
An optional attribute which allows you to refer to your style by another name.
parent:
If this is supplied, it must refer to the name of another style. This
style with then inherit from the style named.
fontName:
An optional attribute, this refers to the font to be used for the main contents of
letterboxes or a textbox - it is ignored for checkBoxes.
fontSize:
This optional attribute sets the size for the main contents of
letterboxes or a textbox - it is ignored for checkBoxes.
alignment:
For letterboxes or a textbox, this optional attribute sets the
alignment of the contents of the box. It may be either
LEFT
,
RIGHT
,
CENTER
or
CENTRE
. It is ignored for checkBoxes.
textColor:
An optional attribute that sets the colour for the main contents in the letterboxes or textbox.
labelFontName:
The (optional) tag specifying the font to be used for the
label of the letterboxes, textbox or checkBox.
labelFontSize:
The (optional) tag specifying the size of the font to be
used for the label of the letterboxes, textbox or checkBox.
labelAlignment:
The (optional) specifying the alignment of the label - may be
LEFT
,
RIGHT
,
CENTER
or
CENTRE
labelTextColor:
An optional attribute specifying the colour to be used
for the text of the label of an textBox, letterBox or checkBox.
boxFillColor:
An optional tag specifying the colour to be used for the
background for a textBox, letterBox or checkBox.
boxStrokeColor:
An optional tag specifying the colour to be used for the
lines making up a textBox, letterBox or checkBox.
cellWidth:
An optional tag, specifying the width of a "cell" in a
form element. Must be a measurment, but may 'in
',
'cm
', 'mm
'or
'pt
' - see the section on 'Coordinates and measurements'
for more details on measurements.
cellHeight:
An optional tag, specifying the width of a "cell" in a
form element. Must be a measurment, but may 'in
',
'cm
', 'mm
'or
'pt
'
Some Examples
As an example of them in use, let's set up two boxStyles, and see what effect they have on letterBoxes, textBoxes and a checkBox.
Firstly, the boxStyles:
EXAMPLE 12
<boxStyle name="special1"
labelFontName="Helvetica"
fontSize="10"
alignment="RIGHT"
textColor="red"
fontName="Helvetica"
labelFontSize="10"
labelAlignment="RIGHT"
labelTextColor="blue"
boxStrokeColor="red"
boxFillColor="pink"/>
<boxStyle name="special2"
parent="special1"
fontName="Courier"
fontSize="12"
textColor="green"
labelFontName="Courier"
labelFontSize="12"
labelTextColor="green"
boxFillColor="yellow"
boxStrokeColor="red"/>
Figure 15: Output from EXAMPLE 12
Barcodes
One other tag that may often find use on forms is the barCode tag. As its name implies, this creates a barcode in one of a number of different symbologies.
The three attributes you need to supply for this tag are x and y to position it on the page and code to inform rml2pdf which form of barcode you require.
This is a brief example of what a barcode tag looks like in use, and what it actually produces:
EXAMPLE 13
<barCode code="Code11" x="1cm" y="0" barWidth="1" barHeight="20">123456</barCode>
Figure 16: Output from EXAMPLE 13
This table shows you the allowed names for the code attribute, along with an example of the barcode produced.
Type | Code attribute to use | Example barcode |
---|---|---|
Codabar | Codabar | |
Code 11 | Code11 | |
Code 128 | Code128 | |
Code 39 | Standard39 | |
Code93 | Standard93 | |
I2of5 | I2of5 | |
Extended Code 39 | Extended39 | |
Extended Code93 | Extended93 | |
MSI | MSI | |
USPS FIM | FIM | |
USPS POSTNET | POSTNET | |
Universal Product Code | UPCA | |
USPS 4-State Customer Code | USPS_4State | |
European Article Number 8 | EAN8 |
8.11. Interactive Form Field tags
PDF allows documents to interact with the user provided the renderer supports this. The most common
renderers including Acrobat Reader, evince and the various browsers certainly allow this.
RML
supports the following interactive form elements
textField Attributes
Attribute | Meaning | Default |
---|---|---|
name | the text field's (ie parameter) name | None |
value | Value of the text field | '' |
x | the horizontal position on the page (absolute coordinates) | 0 |
y | the vertical position on the page (absolute coordinates) | 0 |
width | The widget width | 120 |
height | The widget height | 36 |
fontName | The name of the type 1 font to be used | 'Helvetica' |
fontSize | The size of font to be used | 12 |
maxlen | None or maximum length of the widget value | 100 |
fillColor | colour to be used to fill the widget | None |
textColor | the colour of the symbol or text | None |
borderWidth | as it says | 1 |
borderColor | the widget's border colour | None |
borderStyle | The border style name | 'solid' |
tooltip | The text to display when hovering over the widget | None |
annotationFlags | blank separated string of annotation flags | |
fieldFlags | Blank separated field flags (see below) | |
forceBorder | when true a border force a border to be drawn | False |
relative | if true obey the current canvas transform | False |
multiline | if true then add multiline flag | True |
dashLen | the dashline to be used if the borderStyle=='dashed' | 3 |
checkboxField Attributes
Attribute | Meaning | Default |
---|---|---|
name | the checkbox field's (ie parameter) name | None |
value | Value of the text field | '' |
x | the horizontal position on the page (absolute coordinates) | 0 |
y | the vertical position on the page (absolute coordinates) | 0 |
size | The outline dimensions size x size | 20 |
checked | if True the checkbox is initially checked | False |
buttonStyle | the checkbox style (see below) | check |
shape | The outline of the widget (see below) | square |
fillColor | colour to be used to fill the widget | None |
textColor | the colour of the symbol or text | None |
borderWidth | as it says | 1 |
borderColor | the widget's border colour | None |
borderStyle | The border style name | 'solid' |
tooltip | The text to display when hovering over the widget | None |
annotationFlags | blank separated string of annotation flags | 'print' |
fieldFlags | Blank separated field flags (see below) | required |
forceBorder | when true a border force a border to be drawn | False |
relative | if true obey the current canvas transform | False |
dashLen | the dashline to be used if the borderStyle=='dashed' | 3 |
radioField Attributes
Attribute | Meaning | Default |
---|---|---|
name | the radio's group (ie parameter) name | None |
value | Value of the text field | '' |
x | the horizontal position on the page (absolute coordinates) | 0 |
y | the vertical position on the page (absolute coordinates) | 0 |
size | The outline dimensions size x size | 20 |
selected | if True this radio is the selected one in its group | False |
buttonStyle | the radio select style (see below) | check |
shape | The outline of the widget (see below) | square |
fillColor | colour to be used to fill the widget | None |
textColor | the colour of the symbol or text | None |
borderWidth | as it says | 1 |
borderColor | the widget's border colour | None |
borderStyle | The border style name | 'solid' |
tooltip | The text to display when hovering over the widget | None |
annotationFlags | blank separated string of annotation flags | |
fieldFlags | Blank separated field flags (see below) | noToggleToOff required radio |
forceBorder | when true a border force a border to be drawn | False |
relative | if true obey the current canvas transform | False |
dashLen | the dashline to be used if the borderStyle=='dashed' | 3 |
choiceField Attributes
Attribute | Meaning | Default |
---|---|---|
name | the radio's group (ie parameter) name | None |
value | Singleton or list of strings of selected options | [] |
x | the horizontal position on the page (absolute coordinates) | 0 |
y | the vertical position on the page (absolute coordinates) | 0 |
width | The widget width | 120 |
height | The widget height | 36 |
fontName | The name of the type 1 font to be used | 'Helvetica' |
fontSize | The size of font to be used | 12 |
fillColor | colour to be used to fill the widget | None |
textColor | the colour of the symbol or text | None |
borderWidth | as it says | 1 |
borderColor | the widget's border colour | None |
borderStyle | The border style name | 'solid' |
tooltip | The text to display when hovering over the widget | None |
annotationFlags | blank separated string of annotation flags | |
fieldFlags | Blank separated field flags (see below) | combo |
forceBorder | when true a border force a border to be drawn | False |
relative | if true obey the current canvas transform | False |
dashLen | the dashline to be used if the borderStyle=='dashed' | 3 |
maxlen | None or maximum length of the widget value | None |
listboxField Attributes
Attribute | Meaning | Default |
---|---|---|
name | the listbox field's (ie parameter) name | None |
value | Singleton or list of strings of selected options | [] |
x | the horizontal position on the page (absolute coordinates) | 0 |
y | the vertical position on the page (absolute coordinates) | 0 |
width | The widget width | 120 |
height | The widget height | 36 |
fontName | The name of the type 1 font to be used | 'Helvetica' |
fontSize | The size of font to be used | 12 |
fillColor | colour to be used to fill the widget | None |
textColor | the colour of the symbol or text | None |
borderWidth | as it says | 1 |
borderColor | the widget's border colour | None |
borderStyle | The border style name | 'solid' |
tooltip | The text to display when hovering over the widget | None |
annotationFlags | blank separated string of annotation flags | |
fieldFlags | Blank separated field flags (see below) | |
forceBorder | when true a border force a border to be drawn | False |
relative | if true obey the current canvas transform | False |
dashLen | the dashline to be used if the borderStyle=='dashed' | 3 |
Button styles
The button style argument indicates what style of symbol should appear in the button when it is selected.
There are several choices. This is used for checkbox and radio widgets
- check
- cross
- circle
- star
- diamond
note that the document renderer can make some of these symbols wrong for their intended application. Acrobat reader prefers to use its own rendering on top of what the specification says should be shown (especially when the forms highlighting features are used)
Widget shape
The shape argument describes how the outline of the checkbox or radio widget should appear you can use
- circle
- square
the renderer may make its own decisions about how the widget should look; so Acrobat Reader prefers circular outlines for radios.
Border style
The borderStyle argument changes the 3D appearance of the widget on the page alternatives are
- solid
- dashed
- inset
- bevelled
- underlined
Field Flag Tokens and values
The fieldFlags arguments can be an integer or a string containing blank separate tokens the values are shown in the table below. For more information consult the PDF specification.
Token | Meaning | Value |
---|---|---|
readOnly | The widget is read only | 1<<0 |
required | the widget is required | 1<<1 |
noExport | don't export the widget value | 1<<2 |
noToggleToOff | radios one only must be on | 1<<14 |
radio | added by the radio method | 1<<15 |
pushButton | if the button is a push button | 1<<16 |
radiosInUnison | radios with the same value toggle together | 1<<25 |
multiline | for multiline text widget | 1<<12 |
password | password textfield | 1<<13 |
fileSelect | file selection widget | 1<<20 |
doNotSpellCheck | as it says | 1<<22 |
doNotScroll | text fields do not scroll | 1<<23 |
comb | make a comb style text based on the maxlen value | 1<<24 |
richText | if rich text is used | 1<<25 |
combo | for choice fields | 1<<17 |
edit | if the choice is editable | 1<<18 |
sort | if the values should be sorted | 1<<19 |
multiSelect | if the choice allows multi-select | 1<<21 |
commitOnSelChange | not used by reportlab | 1<<26 |
Annotation Flag Tokens and values
PDF widgets are annotations and have annotation properties these are shown in the table below
Token | Meaning | Value |
---|---|---|
invisible | The widget is not shown | 1<<0 |
hidden | The widget is hidden | 1<<1 |
The widget will print | 1<<2 | |
nozoom | The annotation will notscale with the rendered page | 1<<3 |
norotate | The widget won't rotate with the page | 1<<4 |
noview | Don't render the widget | 1<<5 |
readonly | Widget cannot be interacted with | 1<<6 |
locked | The widget cannot be changed | 1<<7 |
togglenoview | Teh widget may be viewed after some events | 1<<8 |
lockedcontents | The contents of the widget are fixed | 1<<9 |
8.12. Colorspace Checking
RML >= v2.5 supports a way to ensure the consistent enforcement of color models within a document. For more information on this topic, and examples of when you might want to use different scenarios, please refer to the 'Printing' chapter later in this document.
RGB, CMYK and the use of 'spot colors' such as Pantone can be allowed or disallowed using
the 'colorSpace' parameter to the document
tag, which
can be set to the following values:
- MIXED - The default. As in RML versions before 2.5, rgb, cmyk, spot colors and 'named' colors can all be used.
- RGB - Permits only the use of RGB colour values.
- CMYK - Permits only the use of CMYK colour values.
- SEP - 'Spot Colors' only - all colour values must define a 'spotName' value.
- SEP_BLACK - spot colors, plus shades of grey only.
- SEP_CMYK - spot colors plus cmyk values only.
The use of any color definitions outside the specified type will result in an exception when you try to compile the document, thereby ensuring that, for instance, a document can be produced for CMYK or spot color printing without containing any RGB color definitions.
Any 'named' colours (see appendix A or 'reportlab/lib/colors.py') for black or shades of grey are automatically converted to cmyk/rgb as required. So you can use lowercase 'black' as a color in all models except 'SEP'. However, any other RML 'named' colors such as 'aqua' or 'hotpink' will not be converted.
8.13. Balanced Column
Use the BalancedColumns tag to make a flowable that splits its content flowables into two or more roughly equal sized columns. Effectively n frames are synthesized to take the content and the flowable tries to balance the content between them. The created frames will be split when the total height is too large and the split will maintain the balance.
Attributes
ncols - Sets the number of columnns content should be split
needed - Sets the minimum space needed by the flowable (default is 72 points)
spaceBefore - Sets space before the content
spaceAfter - Sets space after the content
showBoundary - Draws a boundary box around each column
leftPadding - Sets left paddings
innerPadding - Sets inner padding
rightPadding - Sets right padding
topPadding - Sets top padding
bottomPadding - Sets bottom padding
More examples here test_051_balancedcolumns.rml test_051_balancedcolumns.pdf