Platypus

long flowing documents

doctemplate

This module contains the core structure of platypus.

rlatypus constructs documents. Document styles are determined by DocumentTemplates.

Each DocumentTemplate contains one or more PageTemplates which defines the look of the pages of the document.

Each PageTemplate has a procedure for drawing the “non-flowing” part of the page (for example the header, footer, page number, fixed logo graphic, watermark, etcetera) and a set of Frames which enclose the flowing part of the page (for example the paragraphs, tables, or non-fixed diagrams of the text).

A document is built when a DocumentTemplate is fed a sequence of Flowables. The action of the build consumes the flowables in order and places them onto frames on pages as space allows. When a frame runs out of space the next frame of the page is used. If no frame remains a new page is created. A new page can also be created if a page break is forced.

The special invisible flowable NextPageTemplate can be used to specify the page template for the next page (which by default is the one being used for the current frame).

class reportlab.platypus.doctemplate.ActionFlowable(action=())

This Flowable is never drawn, it can be used for data driven controls For example to change a page template (from one column to two, for example) use NextPageTemplate which creates an ActionFlowable.

apply(doc)

This is called by the doc.build processing to allow the instance to implement its behaviour

identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

class reportlab.platypus.doctemplate.BaseDocTemplate(filename, **kw)

First attempt at defining a document template class.

The basic idea is simple.

  1. The document has a list of data associated with it this data should derive from flowables. We’ll have special classes like PageBreak, FrameBreak to do things like forcing a page end etc.

  2. The document has one or more page templates.

  3. Each page template has one or more frames.

  4. The document class provides base methods for handling the story events and some reasonable methods for getting the story flowables into the frames.

  5. The document instances can override the base handler routines.

Most of the methods for this class are not called directly by the user, but in some advanced usages they may need to be overridden via subclassing.

EXCEPTION: doctemplate.build(…) must be called for most reasonable uses since it builds a document using the page template.

Each document template builds exactly one document into a file specified by the filename argument on initialization.

Possible keyword arguments for the initialization:

  • pageTemplates: A list of templates. Must be nonempty. Names assigned to the templates are used for referring to them so no two used templates should have the same name. For example you might want one template for a title page, one for a section first page, one for a first page of a chapter and two more for the interior of a chapter on odd and even pages. If this argument is omitted then at least one pageTemplate should be provided using the addPageTemplates method before the document is built.

  • pageSize: a 2-tuple or a size constant from reportlab/lib/pagesizes.pu. Used by the SimpleDocTemplate subclass which does NOT accept a list of pageTemplates but makes one for you; ignored when using pageTemplates.

  • showBoundary: if set draw a box around the frame boundaries.

  • leftMargin:

  • rightMargin:

  • topMargin:

  • bottomMargin: Margin sizes in points (default 1 inch). These margins may be overridden by the pageTemplates. They are primarily of interest for the SimpleDocumentTemplate subclass.

  • allowSplitting: If set flowables (eg, paragraphs) may be split across frames or pages (default: 1)

  • title: Internal title for document (does not automatically display on any page)

  • author: Internal author for document (does not automatically display on any page)

addPageTemplates(pageTemplates)

add one or a sequence of pageTemplates

afterFlowable(flowable)

called after a flowable has been rendered

afterInit()

This is called after initialisation of the base class.

afterPage()

This is called after page processing, and immediately after the afterDrawPage method of the current page template.

beforeDocument()

This is called before any processing is done on the document.

beforePage()

This is called at the beginning of page processing, and immediately before the beforeDrawPage method of the current page template.

build(flowables, filename=None, canvasmaker=<class 'reportlab.pdfgen.canvas.Canvas'>)

Build the document from a list of flowables. If the filename argument is provided then that filename is used rather than the one provided upon initialization. If the canvasmaker argument is provided then it will be used instead of the default. For example a slideshow might use an alternate canvas which places 6 slides on a page (by doing translations, scalings and redefining the page break operations).

clean_hanging()

handle internal postponed actions

filterFlowables(flowables)

called to filter flowables at the start of the main handle_flowable method. Upon return if flowables[0] has been set to None it is discarded and the main method returns.

handle_breakBefore(flowables)

preprocessing step to allow pageBreakBefore and frameBreakBefore attributes

handle_currentFrame(fx, resume=0)

change to the frame with name or index fx

handle_documentBegin()

implement actions at beginning of document

handle_flowable(flowables)

try to handle one flowable from the front of list flowables.

handle_frameBegin(resume=0, pageTopFlowables=None)

What to do at the beginning of a frame

handle_frameEnd(resume=0)

Handles the semantics of the end of a frame. This includes the selection of the next frame or if this is the last frame then invoke pageEnd.

handle_keepWithNext(flowables)

implements keepWithNext

handle_nextFrame(fx, resume=0)

On endFrame change to the frame with name or index fx

handle_nextPageTemplate(pt)

On endPage change to the page template with name or index pt

handle_pageBegin()

Perform actions required at beginning of page. shouldn’t normally be called directly

handle_pageBreak(slow=None)

some might choose not to end all the frames

handle_pageEnd()

show the current page check the next page template hang a page begin

multiBuild(story, maxPasses=10, **buildKwds)

Makes multiple passes until all indexing flowables are happy.

Returns number of passes

notify(kind, stuff)

Forward to any listeners

pageRef(label)

hook to register a page number

setPageCallBack(func)

Simple progress monitor - func(pageNo) called on each new page

setProgressCallBack(func)

Cleverer progress monitor - func(typ, value) called regularly

class reportlab.platypus.doctemplate.CurrentFrameFlowable(ix, resume=0)
class reportlab.platypus.doctemplate.FrameActionFlowable(*arg, **kw)
class reportlab.platypus.doctemplate.Indenter(left=0, right=0)

Increases or decreases left and right margins of frame.

This allows one to have a ‘context-sensitive’ indentation and makes nested lists way easier.

class reportlab.platypus.doctemplate.IndexingFlowable

Abstract interface definition for flowables which might hold references to other pages or themselves be targets of cross-references. XRefStart, XRefDest, Table of Contents, Indexes etc.

afterBuild()

Called after build ends but before isSatisfied

beforeBuild()

Called by multiBuild before it starts; use this to clear old contents

isIndexing()

Hook for IndexingFlowables - things which have cross references

notify(kind, stuff)

This will be called by the framework wherever ‘stuff’ happens. ‘kind’ will be a value that can be used to decide whether to pay attention or not.

class reportlab.platypus.doctemplate.LCActionFlowable(action=())
draw()

Should never be called.

wrap(availWidth, availHeight)

Should never be called.

exception reportlab.platypus.doctemplate.LayoutError
class reportlab.platypus.doctemplate.NextFrameFlowable(ix, resume=0)
class reportlab.platypus.doctemplate.NextPageTemplate(pt)
locChanger = 1

When you get to the next page, use the template specified (change to two column, for example)

class reportlab.platypus.doctemplate.NotAtTopPageBreak(nextTemplate=None)
class reportlab.platypus.doctemplate.NullActionFlowable(action=())
apply(doc)

This is called by the doc.build processing to allow the instance to implement its behaviour

class reportlab.platypus.doctemplate.PageAccumulator(name=None)

gadget to accumulate information in a page and then allow it to be interrogated at the end of the page

onPage(canv, doc)

this will be called at the start of the page

onPageEnd(canv, doc)

this will be called at the end of a page

pageEndAction(canv, doc)

this should be overridden to do something useful

class reportlab.platypus.doctemplate.PageTemplate(id=None, frames=[], onPage=<function _doNothing>, onPageEnd=<function _doNothing>, pagesize=None, autoNextPageTemplate=None, cropBox=None, artBox=None, trimBox=None, bleedBox=None)

essentially a list of Frames and an onPage routine to call at the start of a page when this is selected. onPageEnd gets called at the end. derived classes can also implement beforeDrawPage and afterDrawPage if they want

afterDrawPage(canv, doc)

This is called after the last flowable for the page has been processed. You might use this if the page header or footer needed knowledge of what flowables were drawn on this page.

beforeDrawPage(canv, doc)

Override this if you want additional functionality or prefer a class based page routine. Called before any flowables for this page are processed.

checkPageSize(canv, doc)

This gets called by the template framework If canv size != template size then the canv size is set to the template size or if that’s not available to the doc size.

class reportlab.platypus.doctemplate.SimpleDocTemplate(filename, **kw)

A special case document template that will handle many simple documents. See documentation for BaseDocTemplate. No pageTemplates are required for this special case. A page templates are inferred from the margin information and the onFirstPage, onLaterPages arguments to the build method.

A document which has all pages with the same look except for the first page may can be built using this special approach.

build(flowables, onFirstPage=<function _doNothing>, onLaterPages=<function _doNothing>, canvasmaker=<class 'reportlab.pdfgen.canvas.Canvas'>)

build the document using the flowables. Annotate the first page using the onFirstPage function and later pages using the onLaterPages function. The onXXX pages should follow the signature

def myOnFirstPage(canvas, document):

# do annotations and modify the document …

The functions can do things like draw logos, page numbers, footers, etcetera. They can use external variables to vary the look (for example providing page numbering or section names).

handle_pageBegin()

override base method to add a change of page template after the firstpage.

paragraph

The standard paragraph implementation

class reportlab.platypus.paragraph.FragLine(**attr)

class FragLine contains a styled line (ie a line with more than one style):

extraSpace  unused space for justification only
wordCount   1+spaces in line for justification purposes
words       [ParaFrags] style text lumps to be concatenated together
fontSize    maximum fontSize seen on the line; not used at present,
            but could be used for line spacing.
class reportlab.platypus.paragraph.ParaLines(**attr)
class ParaLines contains the broken into lines representation of Paragraphs

kind=0 Simple fontName, fontSize, textColor apply to whole Paragraph lines [(extraSpace1,words1),….,(extraspaceN,wordsN)]

kind==1 Complex lines [FragLine1,…,FragLineN]

class reportlab.platypus.paragraph.Paragraph(text, style, bulletText=None, caseSensitive=1)

text a string of stuff to go into the paragraph. style is a style definition as in reportlab.lib.styles. bulletText is an optional bullet defintion. caseSensitive set this to 0 if you want the markup tags and their attributes to be case-insensitive.

This class is a flowable that can format a block of text into a paragraph with a given style.

The paragraph Text can contain XML-like markup including the tags: <b> … </b> - bold < u [color=”red”] [width=”pts”] [offset=”pts”]> < /u > - underline

width and offset can be empty meaning use existing canvas line width or with an f/F suffix regarded as a fraction of the font size

< strike > < /strike > - strike through has the same parameters as underline <i> … </i> - italics <u> … </u> - underline <strike> … </strike> - strike through <super> … </super> - superscript <sub> … </sub> - subscript <font name=fontfamily/fontname color=colorname size=float> <span name=fontfamily/fontname color=colorname backcolor=colorname size=float style=stylename> <onDraw name=callable label=”a label”/> <index [name=”callablecanvasattribute”] label=”a label”/> <link>link text</link>

attributes of links

size/fontSize/uwidth/uoffset=num name/face/fontName=name fg/textColor/color/ucolor=color backcolor/backColor/bgcolor=color dest/destination/target/href/link=target underline=bool turn on underline

<a>anchor text</a>
attributes of anchors

size/fontSize/uwidth/uoffset=num fontName=name fg/textColor/color/ucolor=color backcolor/backColor/bgcolor=color href=href underline=”yes|no”

<a name=”anchorpoint”/> <unichar name=”unicode character name”/> <unichar value=”unicode code point”/> <img src=”path” width=”1in” height=”1in” valign=”bottom”/>

width=”w%” –> fontSize*w/100 idea from Roberto Alsina height=”h%” –> linewidth*h/100 <ralsina@netmanagers.com.ar>

The whole may be surrounded by <para> </para> tags

The <b> and <i> tags will work for the built-in fonts (Helvetica /Times / Courier). For other fonts you need to register a family of 4 fonts using reportlab.pdfbase.pdfmetrics.registerFont; then use the addMapping function to tell the library that these 4 fonts form a family e.g. from reportlab.lib.fonts import addMapping addMapping(‘Vera’, 0, 0, ‘Vera’) #normal addMapping(‘Vera’, 0, 1, ‘Vera-Italic’) #italic addMapping(‘Vera’, 1, 0, ‘Vera-Bold’) #bold addMapping(‘Vera’, 1, 1, ‘Vera-BoldItalic’) #italic and bold

It will also be able to handle any MathML specified Greek characters.

breakLines(width)

Returns a broken line structure. There are two cases

  1. For the simple case of a single formatting input fragment the output is
    A fragment specifier with
    • kind = 0

    • fontName, fontSize, leading, textColor

    • lines= A list of lines

      Each line has two items.

      1. unused width in points

      2. word list

  2. When there is more than one input formatting fragment the output is
    A fragment specifier with
    • kind = 1

    • lines= A list of fragments each having fields
      • extraspace (needed for justified)

      • fontSize

      • words=word list

        each word is itself a fragment with various settings

    in addition frags becomes a frag word list

This structure can be used to easily draw paragraphs with the various alignments. You can supply either a single width or a list of widths; the latter will have its last item repeated until necessary. A 2-element list is useful when there is a different first line indent; a longer list could be created to facilitate custom wraps around irregular objects.

breakLinesCJK(maxWidths)

Initially, the dumbest possible wrapping algorithm. Cannot handle font variations.

drawPara(debug=0)

Draws a paragraph according to the given style. Returns the final y position at the bottom. Not safe for paragraphs without spaces e.g. Japanese; wrapping algorithm will go infinite.

getActualLineWidths0()

Convenience function; tells you how wide each line actually is. For justified styles, this will be the same as the wrap width; for others it might be useful for seeing if paragraphs will fit in spaces.

getPlainText(identify=None)

Convenience function for templates which want access to the raw text, without XML tags.

minWidth()

Attempt to determine a minimum sensible width

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

reportlab.platypus.paragraph.cleanBlockQuotedText(text, joiner=' ')

This is an internal utility which takes triple- quoted text form within the document and returns (hopefully) the paragraph the user intended originally.

paraparser

The parser used to process markup within paragraphs

class reportlab.platypus.paraparser.ParaFrag(**attr)

class ParaFrag contains the intermediate representation of string segments as they are being parsed by the ParaParser. fontname, fontSize, rise, textColor, cbDefn

class reportlab.platypus.paraparser.ParaParser(verbose=0, caseSensitive=0, ignoreUnknownTags=1, crashOnError=True)
handle_data(data)

Creates an intermediate representation of string segments.

handle_endtag(tag)

Called by HTMLParser when a tag ends

handle_entityref(name)

Handles a named entity.

handle_starttag(tag, attrs)

Called by HTMLParser when a tag starts

parse(text, style)

attempt replacement for parse

tt_parse(tt, style)

parse from tupletree form

flowables

A flowable is a “floating element” in a document whose exact position is determined by the other elements that precede it, such as a paragraph, a diagram interspersed between paragraphs, a section header, etcetera. Examples of non-flowables include page numbering annotations, headers, footers, fixed diagrams or logos, among others.

Flowables are defined here as objects which know how to determine their size and which can draw themselves onto a page with respect to a relative “origin” position determined at a higher level. The object’s draw() method should assume that (0,0) corresponds to the bottom left corner of the enclosing rectangle that will contain the object. The attributes vAlign and hAlign may be used by ‘packers’ as hints as to how the object should be placed.

Some Flowables also know how to “split themselves”. For example a long paragraph might split itself between one page and the next.

Packers should set the canv attribute during wrap, split & draw operations to allow the flowable to work out sizes etc in the proper context.

The “text” of a document usually consists mainly of a sequence of flowables which flow into a document from top to bottom (with column and page breaks controlled by higher level components).

class reportlab.platypus.flowables.AnchorFlowable(name)

create a bookmark in the pdf

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.BalancedColumns(F, nCols=2, needed=72, spaceBefore=0, spaceAfter=0, showBoundary=None, leftPadding=None, innerPadding=None, rightPadding=None, topPadding=None, bottomPadding=None, name='', endSlack=0.1, boxStrokeColor=None, boxStrokeWidth=0, boxFillColor=None, boxMargin=None, vLinesStrokeColor=None, vLinesStrokeWidth=None)

combine a list of flowables and an Image

getSpaceAfter()

returns how much space should follow this item if another item follows on the same page.

getSpaceBefore()

returns how much space should precede this item if another item precedess on the same page.

identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.CallerMacro(drawCallable=None, wrapCallable=None)

like Macro, but with callable command(s) drawCallable(self) wrapCallable(self,aW,aH)

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.CondPageBreak(height)
identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

locChanger = 1

use up a frame if not enough vertical space effectively CondFrameBreak

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.DDIndenter(flowable, leftIndent=0, rightIndent=0)
drawOn(canv, x, y, _sW=0)

Tell it to draw itself on the canvas. Do not override

identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

split(aW, aH)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.DocAssert(cond, format=None)
wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.DocAssign(var, expr, life='forever')

At wrap time this flowable evaluates var=expr in the doctemplate namespace

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.DocExec(stmt, lifetime='forever')

at wrap time exec stmt in doc._nameSpace

class reportlab.platypus.flowables.DocIf(cond, thenBlock, elseBlock=[])
wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.DocPara(expr, format=None, style=None, klass=None, escape=True)

at wrap time create a paragraph with the value of expr as text if format is specified it should use %(__expr__)s for string interpolation of the expression expr (if any). It may also use %(name)s interpolations for other variables in the namespace. suitable defaults will be used if style and klass are None

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.DocWhile(cond, whileBlock)
wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.FailOnDraw
wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.FailOnWrap
wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.Flowable

Abstract base class for things to be drawn. Key concepts:

  1. It knows its size

  2. It draws in its own coordinate system (this requires the base API to provide a translate() function.

drawOn(canvas, x, y, _sW=0)

Tell it to draw itself on the canvas. Do not override

getKeepWithNext()

returns boolean determining whether the next flowable should stay with this one

getSpaceAfter()

returns how much space should follow this item if another item follows on the same page.

getSpaceBefore()

returns how much space should precede this item if another item precedess on the same page.

identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

isIndexing()

Hook for IndexingFlowables - things which have cross references

minWidth()

This should return the minimum required width

split(availWidth, availheight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

splitOn(canv, aW, aH)

intended for use by packers allows setting the canvas on during the actual split

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

wrapOn(canv, aW, aH)

intended for use by packers allows setting the canvas on during the actual wrap

class reportlab.platypus.flowables.FrameBG(color=None, left=0, right=0, start=True, strokeWidth=None, strokeColor=None, strokeDashArray=None)

Start or stop coloring the frame background left & right are distances from the edge of the frame to start stop colouring. if start in (‘frame’,’frame-permanent’) then the background is filled from here to the bottom of the frame and immediately discarded for the frame case.

class reportlab.platypus.flowables.FrameSplitter(nextTemplate, nextFrames=[], gap=10, required=72, adjustHeight=True)

When encountered this flowable should either switch directly to nextTemplate if remaining space in the current frame is less than gap+required or it should temporarily modify the current template to have the frames from nextTemplate that are listed in nextFrames and switch to the first of those frames.

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.HRFlowable(width='80%', thickness=1, lineCap='round', color=Color(.827451, .827451, .827451, 1), spaceBefore=1, spaceAfter=1, hAlign='CENTER', vAlign='BOTTOM', dash=None)

Like the hr tag

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.Image(filename, width=None, height=None, kind='direct', mask='auto', lazy=1, hAlign='CENTER', useDPI=False)

an image (digital picture). Formats supported by PIL/Java 1.4 (the Python/Java Imaging Library are supported. Images as flowables may be aligned horizontally in the frame with the hAlign parameter - accepted values are ‘CENTER’, ‘LEFT’ or ‘RIGHT’ with ‘CENTER’ being the default. We allow for two kinds of lazyness to allow for many images in a document which could lead to file handle starvation. lazy=1 don’t open image until required. lazy=2 open image when required then shut it.

identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.ImageAndFlowables(I, F, imageLeftPadding=0, imageRightPadding=3, imageTopPadding=0, imageBottomPadding=3, imageSide='right', imageHref=None)

combine a list of flowables and an Image

drawOn(canv, x, y, _sW=0)

we simulate being added to a frame

getSpaceAfter()

returns how much space should follow this item if another item follows on the same page.

getSpaceBefore()

returns how much space should precede this item if another item precedess on the same page.

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.KeepInFrame(maxWidth, maxHeight, content=[], mergeSpace=1, mode='shrink', name='', hAlign='LEFT', vAlign='BOTTOM', fakeWidth=None)
drawOn(canv, x, y, _sW=0)

we simulate being added to a frame

identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.KeepTogether(flowables, maxHeight=None)
identity(maxLen=None)

This method should attempt to return a string that can be used to identify a particular flowable uniquely. The result can then be used for debugging and or error printouts

split(aW, aH)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.LIIndenter(flowable, leftIndent=0, rightIndent=0, bullet=None, spaceBefore=None, spaceAfter=None)
drawOn(canv, x, y, _sW=0)

Tell it to draw itself on the canvas. Do not override

split(aW, aH)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

class reportlab.platypus.flowables.ListFlowable(flowables, start=None, style=None, **kwds)
split(aW, aH)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.Macro(command)

This is not actually drawn (i.e. it has zero height) but is executed when it would fit in the frame. Allows direct access to the canvas through the object ‘canvas’

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.NullDraw
class reportlab.platypus.flowables.PTOContainer(contentList, trailerList, headerList)

A container for flowables decorated with trailer & header lists. If the split operation would be called then the trailer and header lists are injected before and after the split. This allows specialist “please turn over” and “continued from previous” like behaviours.

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.PageBreak(nextTemplate=None)
locChanger = 1

Move on to the next page in the document. This works by consuming all remaining space in the frame!

class reportlab.platypus.flowables.PageBreakIfNotEmpty(nextTemplate=None)
class reportlab.platypus.flowables.ParagraphAndImage(P, I, xpad=3, ypad=3, side='right')

combine a Paragraph and an Image

getSpaceAfter()

returns how much space should follow this item if another item follows on the same page.

getSpaceBefore()

returns how much space should precede this item if another item precedess on the same page.

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.Preformatted(text, style, bulletText=None, dedent=0, maxLineLength=None, splitChars=None, newLineChars='')

This is like the HTML <PRE> tag. It attempts to display text exactly as you typed it in a fixed width “typewriter” font. By default the line breaks are exactly where you put them, and it will not be wrapped. You can optionally define a maximum line length and the code will be wrapped; and extra characters to be inserted at the beginning of each wrapped line (e.g. ‘> ‘).

minWidth()

This should return the minimum required width

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.SetPageTopFlowables(F, show=False)
wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.SetTopFlowables(F, show=False)
wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.SlowPageBreak(nextTemplate=None)
class reportlab.platypus.flowables.Spacer(width, height, isGlue=False)

A spacer just takes up space and doesn’t draw anything - it guarantees a gap between objects.

class reportlab.platypus.flowables.TopPadder(f)

wrap a single flowable so that its first bit will be padded to fill out the space so that it appears at the bottom of its frame

drawOn(canvas, x, y, _sW=0)

Tell it to draw itself on the canvas. Do not override

split(aW, aH)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(aW, aH)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.TraceInfo

Holder for info about where an object originated

class reportlab.platypus.flowables.UseUpSpace
wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.flowables.XBox(width, height, text='A Box')

Example flowable - a box with an x through it and a caption. This has a known size, so does not need to respond to wrap().

frames

A frame is a container for content on a page.

class reportlab.platypus.frames.Frame(x1, y1, width, height, leftPadding=6, bottomPadding=6, rightPadding=6, topPadding=6, id=None, showBoundary=0, overlapAttachedSpace=None, _debug=None)

A Frame is a piece of space in a document that is filled by the “flowables” in the story. For example in a book like document most pages have the text paragraphs in one or two frames. For generality a page might have several frames (for example for 3 column text or for text that wraps around a graphic).

After creation a Frame is not usually manipulated directly by the applications program – it is used internally by the platypus modules.

Here is a diagramatid abstraction for the definitional part of a Frame:

        width                    x2,y2
+---------------------------------+
| l  top padding                r | h
| e +-------------------------+ i | e
| f |                         | g | i
| t |                         | h | g
|   |                         | t | h
| p |                         |   | t
| a |                         | p |
| d |                         | a |
|   |                         | d |
|   +-------------------------+   |
|    bottom padding               |
+---------------------------------+
(x1,y1) <-- lower left corner

NOTE!! Frames are stateful objects. No single frame should be used in two documents at the same time (especially in the presence of multithreading.

add(flowable, canv, trySplit=0)

Draws the flowable at the current position. Returns 1 if successful, 0 if it would not fit. Raises a LayoutError if the object is too wide, or if it is too high for a totally empty frame, to avoid infinite loops

addFromList(drawlist, canv)

Consumes objects from the front of the list until the frame is full. If it cannot fit one object, raises an exception.

split(flowable, canv)

Ask the flowable to split using up the available space.

figures

This includes some demos of platypus for use in the API proposal

class reportlab.platypus.figures.DrawingFigure(modulename, classname, caption, baseDir=None, background=None)

Drawing with a caption below it. Clunky, scaling fails.

class reportlab.platypus.figures.Figure(width, height, caption='', captionFont='Helvetica-Oblique', captionSize=12, background=None, captionTextColor=Color(0, 0, 0, 1), captionBackColor=None, border=None, spaceBefore=12, spaceAfter=12, captionGap=None, captionAlign='centre', captionPosition='bottom', hAlign='CENTER')
drawBackground()

For use when using a figure on a differently coloured background. Allows you to specify a colour to be used as a background for the figure.

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.figures.FlexFigure(width, height, caption, background=None, captionFont='Helvetica-Oblique', captionSize=8, captionTextColor=Color(0, 0, 0, 1), shrinkToFit=1, growToFit=1, spaceBefore=12, spaceAfter=12, captionGap=9, captionAlign='centre', captionPosition='top', scaleFactor=None, hAlign='CENTER', border=1)

Base for a figure class with a caption. Can grow or shrink in proportion

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.figures.ImageFigure(filename, caption, background=None, scaleFactor=None, hAlign='CENTER', border=None)

Image with a caption below it

class reportlab.platypus.figures.PageFigure(background=None)

Shows a blank page in a frame, and draws on that. Used in illustrations of how PLATYPUS works.

class reportlab.platypus.figures.PlatPropFigure1

This shows a page with a frame on it

tables

Tables are created by passing the constructor a tuple of column widths, a tuple of row heights and the data in row order. Drawing of the table can be controlled by using a TableStyle instance. This allows control of the color and weight of the lines (if any), and the font, alignment and padding of the text.

None values in the sequence of row heights or column widths, mean that the corresponding rows or columns should be automatically sized.

All the cell values should be convertible to strings; embedded newline ‘n’ characters cause the value to wrap (ie are like a traditional linefeed).

See the test output from running this module as a script for a discussion of the method for constructing tables and table styles.

class reportlab.platypus.tables.LongTable(data, colWidths=None, rowHeights=None, style=None, repeatRows=0, repeatCols=0, splitByRow=1, splitInRow=0, emptyTableAction=None, ident=None, hAlign=None, vAlign=None, normalizedData=0, cellStyles=None, rowSplitRange=None, spaceBefore=None, spaceAfter=None, longTableOptimize=None, minRowHeights=None, cornerRadii=__UNSET__)

Henning von Bargen’s changes will be active

class reportlab.platypus.tables.Table(data, colWidths=None, rowHeights=None, style=None, repeatRows=0, repeatCols=0, splitByRow=1, splitInRow=0, emptyTableAction=None, ident=None, hAlign=None, vAlign=None, normalizedData=0, cellStyles=None, rowSplitRange=None, spaceBefore=None, spaceAfter=None, longTableOptimize=None, minRowHeights=None, cornerRadii=__UNSET__)
identity(maxLen=30)

Identify our selves as well as possible

minWidth()

This should return the minimum required width

normCellRange(sc, ec, sr, er)

ensure cell range ends are with the table bounds

normalizeData(data)

Takes a block of input data (list of lists etc.) and - coerces unicode strings to non-unicode UTF8 - coerces nulls to ‘’ -

onSplit(T, byRow=1)

This method will be called when the Table is split. Special purpose tables can override to do special stuff.

split(availWidth, availHeight)

This will be called by more sophisticated frames when wrap fails. Stupid flowables should return []. Clever flowables should split themselves and return a list of flowables. If they decide that nothing useful can be fitted in the available space (e.g. if you have a table and not enough space for the first row), also return []

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

tableofcontents

Experimental class to generate Tables of Contents easily

This module defines a single TableOfContents() class that can be used to create automatically a table of tontents for Platypus documents like this:

story = [] toc = TableOfContents() story.append(toc) # some heading paragraphs here… doc = MyTemplate(path) doc.multiBuild(story)

The data needed to create the table is a list of (level, text, pageNum) triplets, plus some paragraph styles for each level of the table itself. The triplets will usually be created in a document template’s method like afterFlowable(), making notification calls using the notify() method with appropriate data like this:

(level, text, pageNum) = … self.notify(‘TOCEntry’, (level, text, pageNum))

Optionally the list can contain four items in which case the last item is a destination key which the entry should point to. A bookmark with this key needs to be created first like this:

key = ‘ch%s’ % self.seq.nextf(‘chapter’) self.canv.bookmarkPage(key) self.notify(‘TOCEntry’, (level, text, pageNum, key))

As the table of contents need at least two passes over the Platypus story which is why the multiBuild() method must be called.

The level<NUMBER>ParaStyle variables are the paragraph styles used to format the entries in the table of contents. Their indentation is calculated like this: each entry starts at a multiple of some constant named delta. If one entry spans more than one line, all lines after the first are indented by the same constant named epsilon.

reportlab.platypus.tableofcontents.AlphabeticIndex

alias of reportlab.platypus.tableofcontents.SimpleIndex

class reportlab.platypus.tableofcontents.ReferenceText(textPattern, targetKey)

Fakery to illustrate how a reference would work if we could put it in a paragraph.

beforeBuild()

Called by multiBuild before it starts; use this to clear old contents

drawOn(canvas, x, y, _sW=0)

Tell it to draw itself on the canvas. Do not override

notify(kind, stuff)

This will be called by the framework wherever ‘stuff’ happens. ‘kind’ will be a value that can be used to decide whether to pay attention or not.

wrap(availWidth, availHeight)

This will be called by the enclosing frame before objects are asked their size, drawn or whatever. It returns the size actually used.

class reportlab.platypus.tableofcontents.SimpleIndex(**kwargs)

Creates multi level indexes. The styling can be cutomized and alphabetic headers turned on and off.

addEntry(text, pageNum, key=None)

Allows incremental buildup

beforeBuild()

Called by multiBuild before it starts; use this to clear old contents

drawOn(canvas, x, y, _sW=0)

Don’t do this at home! The standard calls for implementing draw(); we are hooking this in order to delegate ALL the drawing work to the embedded table object.

getLevelStyle(n)

Returns the style for level n, generating and caching styles on demand if not present.

isIndexing()

Hook for IndexingFlowables - things which have cross references

notify(kind, stuff)

The notification hook called to register all kinds of events.

Here we are interested in ‘IndexEntry’ events only.

setup(style=None, dot=None, tableStyle=None, headers=True, name=None, format='123', offset=0)

This method makes it possible to change styling and other parameters on an existing object.

style is the paragraph style to use for index entries. dot can either be None or a string. If it’s None, entries are immediatly followed by their

corresponding page numbers. If it’s a string, page numbers are aligned on the right side of the document and the gap filled with a repeating sequence of the string.

tableStyle is the style used by the table which the index uses to draw itself. Use this to

change properties like spacing between elements.

headers is a boolean. If it is True, alphabetic headers are displayed in the Index when the first letter changes. If False, we just output some extra space before the next item name makes it possible to use several indexes in one document. If you want this use this

parameter to give each index a unique name. You can then index a term by refering to the name of the index which it should appear in:

<index item=”term” name=”myindex” />

format can be ‘I’, ‘i’, ‘123’, ‘ABC’, ‘abc’

split(availWidth, availHeight)

At this stage we do not care about splitting the entries, we will just return a list of platypus tables. Presumably the calling app has a pointer to the original TableOfContents object; Platypus just sees tables.

wrap(availWidth, availHeight)

All table properties should be known by now.

class reportlab.platypus.tableofcontents.TableOfContents(**kwds)

This creates a formatted table of contents.

It presumes a correct block of data is passed in. The data block contains a list of (level, text, pageNumber) triplets. You can supply a paragraph style for each level (starting at zero). Set dotsMinLevel to determine from which level on a line of dots should be drawn between the text and the page number. If dotsMinLevel is set to a negative value, no dotted lines are drawn.

addEntries(listOfEntries)

Bulk creation of entries in the table of contents.

If you knew the titles but not the page numbers, you could supply them to get sensible output on the first run.

addEntry(level, text, pageNum, key=None)

Adds one entry to the table of contents.

This allows incremental buildup by a doctemplate. Requires that enough styles are defined.

beforeBuild()

Called by multiBuild before it starts; use this to clear old contents

drawOn(canvas, x, y, _sW=0)

Don’t do this at home! The standard calls for implementing draw(); we are hooking this in order to delegate ALL the drawing work to the embedded table object.

getLevelStyle(n)

Returns the style for level n, generating and caching styles on demand if not present.

isIndexing()

Hook for IndexingFlowables - things which have cross references

notify(kind, stuff)

The notification hook called to register all kinds of events.

Here we are interested in ‘TOCEntry’ events only.

split(availWidth, availHeight)

At this stage we do not care about splitting the entries, we will just return a list of platypus tables. Presumably the calling app has a pointer to the original TableOfContents object; Platypus just sees tables.

wrap(availWidth, availHeight)

All table properties should be known by now.

reportlab.platypus.tableofcontents.drawPageNumbers(canvas, style, pages, availWidth, availHeight, dot=' . ', formatter=None)

Draws pagestr on the canvas using the given style. If dot is None, pagestr is drawn at the current position in the canvas. If dot is a string, pagestr is drawn right-aligned. If the string is not empty, the gap is filled with it.

xpreformatted

A ‘rich preformatted text’ widget allowing internal markup

class reportlab.platypus.xpreformatted.PythonPreformatted(text, style, bulletText=None, dedent=0, frags=None)

Used for syntax-colored Python code, otherwise like XPreformatted.

fontify(code)

Return a fontified version of some Python code.

class reportlab.platypus.xpreformatted.XPreformatted(text, style, bulletText=None, frags=None, caseSensitive=1, dedent=0)
breakLines(width)

Returns a broken line structure. There are two cases

  1. For the simple case of a single formatting input fragment the output is
    A fragment specifier with
    • kind = 0

    • fontName, fontSize, leading, textColor

    • lines= A list of lines

      Each line has two items:

      1. unused width in points

      2. a list of words

  2. When there is more than one input formatting fragment the out put is
    A fragment specifier with
    • kind = 1

    • lines = A list of fragments each having fields:

      • extraspace (needed for justified)

      • fontSize

      • words=word list

      • each word is itself a fragment with

      • various settings

This structure can be used to easily draw paragraphs with the various alignments. You can supply either a single width or a list of widths; the latter will have its last item repeated until necessary. A 2-element list is useful when there is a different first line indent; a longer list could be created to facilitate custom wraps around irregular objects.

breakLinesCJK(width)

Returns a broken line structure. There are two cases

  1. For the simple case of a single formatting input fragment the output is
    A fragment specifier with
    • kind = 0

    • fontName, fontSize, leading, textColor

    • lines= A list of lines

      Each line has two items:

      1. unused width in points

      2. a list of words

  2. When there is more than one input formatting fragment the out put is
    A fragment specifier with
    • kind = 1

    • lines = A list of fragments each having fields:

      • extraspace (needed for justified)

      • fontSize

      • words=word list

      • each word is itself a fragment with

      • various settings

This structure can be used to easily draw paragraphs with the various alignments. You can supply either a single width or a list of widths; the latter will have its last item repeated until necessary. A 2-element list is useful when there is a different first line indent; a longer list could be created to facilitate custom wraps around irregular objects.