Chapter 8: Miscellaneous useful features
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.
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 https://www.reportlab.com/examples/rml/test/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").
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
RML
<?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>
Output
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).
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 "& amp;".
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.
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>
Plug-ins: plugInGraphic and plugInFlowable
Both plugInGraphics and
plugInFlowables 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:
<plugInGraphic module="mymodule" function="myfunction">data string</plugInGraphic>
when executed results in effectively the following execution sequence:
import mymodule
mymodule.myfunction(canvas, "data string")
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:
<plugInFlowable module="mymodule" function="myfunction">data string</plugInFlowable>
when executed results in effectively the execution sequence:
import mymodule
flowable=mymodule.myfunction("data string")
story.append(flowable)
using the current canvas object.
plugInFlowable has two mandatory attributes:
module and function.
It is also used in the <pageGraphics> section
of your document.
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.
<pageDrawing>
<catchForms storageFile="storage.data"/>
<doForm name="PF0"/>
</pageDrawing>
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 doForms 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:
<includePdfPages filename="mypdffile.pdf"/>
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 pf 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\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 |
Outlines
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>
A note about levels: in order to add a level 3 outline entry, the previous outline
entry must be at least level 2 (2,3,4...). In other words, you can "move back" any
number of levels, but you can only "move forward" one level at a time.
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:
RML
<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"/>
Output
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:
RML
<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>
Output
The following code creates a row of sample textboxes illustrating
the auto-resizing text feature:
RML
<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>
Output
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:
RML
<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>
Output
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:
RML
<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>
Output
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:
RML
<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"/>
Output
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:
<barCode x="1cm" y="0" code="Code11">123456</barCode>
Output
This table shows you the allowed names for the code
attribute, along with an example of the barcode produced.
PDF allows documents to intereact 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 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 |
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 |
print |
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 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 |
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 |
'' |
name |
the radio's group (ie parameter) name |
None |
value |
the radio's group name |
None |
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 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) |
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 |
Value of the text field |
'' |
name |
the radio's group (ie parameter) name |
None |
options |
List or tuple of avaiable options |
[] |
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 |
print |
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 radio's group (ie parameter) name |
None |
value |
Value of the text field |
'' |
name |
the radio's group (ie parameter) name |
None |
options |
List or tuple of avaiable options |
[] |
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 |
print |
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
- 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 hihlighting features are used)
Widget shape
The shape argument describes how the outline of the checkbox or radio widget should appear you can use
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.s
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 |
print |
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 |
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.
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