maxPasses:
- raise IndexError("Index entries not resolved after %d passes" % maxPasses)
-
- #work through any edits
- while mbe:
- e = mbe.pop(0)
- e[0](*e[1:])
-
- del self._multiBuildEdits
- if verbose: print('saved')
- return passes
-
- #these are pure virtuals override in derived classes
- #NB these get called at suitable places by the base class
- #so if you derive and override the handle_xxx methods
- #it's up to you to ensure that they maintain the needed consistency
- def afterInit(self):
- """This is called after initialisation of the base class."""
- pass
-
- def beforeDocument(self):
- """This is called before any processing is
- done on the document."""
- pass
-
- def beforePage(self):
- """This is called at the beginning of page
- processing, and immediately before the
- beforeDrawPage method of the current page
- template."""
- pass
-
- def afterPage(self):
- """This is called after page processing, and
- immediately after the afterDrawPage method
- of the current page template."""
- pass
-
- def filterFlowables(self,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.
- '''
- pass
-
- def afterFlowable(self, flowable):
- '''called after a flowable has been rendered'''
- pass
-
- _allowedLifetimes = 'page','frame','build','forever'
- def docAssign(self,var,expr,lifetime):
- if not isinstance(expr,strTypes): expr=str(expr)
- expr=expr.strip()
- var=var.strip()
- self.docExec('%s=(%s)'%(var.strip(),expr.strip()),lifetime)
-
- def docExec(self,stmt,lifetime):
- stmt=stmt.strip()
- NS=self._nameSpace
- K0=list(NS.keys())
- try:
- if lifetime not in self._allowedLifetimes:
- raise ValueError('bad lifetime %r not in %r'%(lifetime,self._allowedLifetimes))
- exec(stmt, {},NS)
- except:
- exc = sys.exc_info()[1]
- args = list(exc.args)
- msg = '\ndocExec %s lifetime=%r failed!' % (stmt,lifetime)
- args.append(msg)
- exc.args = tuple(args)
- for k in NS.keys():
- if k not in K0:
- del NS[k]
- raise
- self._addVars([k for k in NS.keys() if k not in K0],lifetime)
-
- def _addVars(self,vars,lifetime):
- '''add namespace variables to lifetimes lists'''
- LT=self._lifetimes
- for var in vars:
- for v in LT.values():
- if var in v:
- v.remove(var)
- LT.setdefault(lifetime,set([])).add(var)
-
- def _removeVars(self,lifetimes):
- '''remove namespace variables for with lifetime in lifetimes'''
- LT=self._lifetimes
- NS=self._nameSpace
- for lifetime in lifetimes:
- for k in LT.setdefault(lifetime,[]):
- try:
- del NS[k]
- except KeyError:
- pass
- del LT[lifetime]
-
- def docEval(self,expr):
- try:
- return eval(expr.strip(),{},self._nameSpace)
- except:
- exc = sys.exc_info()[1]
- args = list(exc.args)
- args[-1] += '\ndocEval %s failed!' % expr
- exc.args = tuple(args)
- raise
-
-class SimpleDocTemplate(BaseDocTemplate):
- """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.
- """
- _invalidInitArgs = ('pageTemplates',)
-
- def handle_pageBegin(self):
- '''override base method to add a change of page template after the firstpage.
- '''
- self._handle_pageBegin()
- self._handle_nextPageTemplate('Later')
-
- def build(self,flowables,onFirstPage=_doNothing, onLaterPages=_doNothing, canvasmaker=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).
- """
- self._calc() #in case we changed margins sizes etc
- frameT = Frame(self.leftMargin, self.bottomMargin, self.width, self.height, id='normal')
- self.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=onFirstPage,pagesize=self.pagesize),
- PageTemplate(id='Later',frames=frameT, onPage=onLaterPages,pagesize=self.pagesize)])
- if onFirstPage is _doNothing and hasattr(self,'onFirstPage'):
- self.pageTemplates[0].beforeDrawPage = self.onFirstPage
- if onLaterPages is _doNothing and hasattr(self,'onLaterPages'):
- self.pageTemplates[1].beforeDrawPage = self.onLaterPages
- BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker)
-
-def progressCB(typ, value):
- """Example prototype for progress monitoring.
-
- This aims to provide info about what is going on
- during a big job. It should enable, for example, a reasonably
- smooth progress bar to be drawn. We design the argument
- signature to be predictable and conducive to programming in
- other (type safe) languages. If set, this will be called
- repeatedly with pairs of values. The first is a string
- indicating the type of call; the second is a numeric value.
-
- typ 'STARTING', value = 0
- typ 'SIZE_EST', value = numeric estimate of job size
- typ 'PASS', value = number of this rendering pass
- typ 'PROGRESS', value = number between 0 and SIZE_EST
- typ 'PAGE', value = page number of page
- type 'FINISHED', value = 0
-
- The sequence is
- STARTING - always called once
- SIZE_EST - always called once
- PROGRESS - called often
- PAGE - called often when page is emitted
- FINISHED - called when really, really finished
-
- some juggling is needed to accurately estimate numbers of
- pages in pageDrawing mode.
-
- NOTE: the SIZE_EST is a guess. It is possible that the
- PROGRESS value may slightly exceed it, or may even step
- back a little on rare occasions. The only way to be
- really accurate would be to do two passes, and I don't
- want to take that performance hit.
- """
- print('PROGRESS MONITOR: %-10s %d' % (typ, value))
-
-if __name__ == '__main__':
- from reportlab.lib.styles import _baseFontName, _baseFontNameB
- def myFirstPage(canvas, doc):
- from reportlab.lib.colors import red
- PAGE_HEIGHT = canvas._pagesize[1]
- canvas.saveState()
- canvas.setStrokeColor(red)
- canvas.setLineWidth(5)
- canvas.line(66,72,66,PAGE_HEIGHT-72)
- canvas.setFont(_baseFontNameB,24)
- canvas.drawString(108, PAGE_HEIGHT-108, "TABLE OF CONTENTS DEMO")
- canvas.setFont(_baseFontName,12)
- canvas.drawString(4 * inch, 0.75 * inch, "First Page")
- canvas.restoreState()
-
- def myLaterPages(canvas, doc):
- from reportlab.lib.colors import red
- PAGE_HEIGHT = canvas._pagesize[1]
- canvas.saveState()
- canvas.setStrokeColor(red)
- canvas.setLineWidth(5)
- canvas.line(66,72,66,PAGE_HEIGHT-72)
- canvas.setFont(_baseFontName,12)
- canvas.drawString(4 * inch, 0.75 * inch, "Page %d" % doc.page)
- canvas.restoreState()
-
- def run():
- objects_to_draw = []
- from reportlab.lib.styles import ParagraphStyle
- #from paragraph import Paragraph
- from reportlab.platypus.doctemplate import SimpleDocTemplate
-
- #need a style
- normal = ParagraphStyle('normal')
- normal.firstLineIndent = 18
- normal.spaceBefore = 6
- from reportlab.lib.randomtext import randomText
- import random
- for i in range(15):
- height = 0.5 + (2*random.random())
- box = XBox(6 * inch, height * inch, 'Box Number %d' % i)
- objects_to_draw.append(box)
- para = Paragraph(randomText(), normal)
- objects_to_draw.append(para)
-
- SimpleDocTemplate('doctemplate.pdf').build(objects_to_draw,
- onFirstPage=myFirstPage,onLaterPages=myLaterPages)
-
- run()
diff --git a/reportlab/platypus/figures.py b/reportlab/platypus/figures.py
deleted file mode 100644
index 33aaad62..00000000
--- a/reportlab/platypus/figures.py
+++ /dev/null
@@ -1,433 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/figures.py
-"""This includes some demos of platypus for use in the API proposal"""
-__version__=''' $Id$ '''
-
-import os
-
-from reportlab.lib import colors
-from reportlab.pdfgen.canvas import Canvas
-from reportlab.lib.styles import ParagraphStyle
-from reportlab.lib.utils import recursiveImport, strTypes
-from reportlab.platypus import Frame
-from reportlab.platypus import Flowable
-from reportlab.platypus import Paragraph
-from reportlab.lib.units import inch
-from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER
-from reportlab.lib.validators import isColor
-from reportlab.lib.colors import toColor
-from reportlab.lib.styles import _baseFontName, _baseFontNameI
-
-captionStyle = ParagraphStyle('Caption', fontName=_baseFontNameI, fontSize=10, alignment=TA_CENTER)
-
-class Figure(Flowable):
- def __init__(self, width, height, caption="",
- captionFont=_baseFontNameI, captionSize=12,
- background=None,
- captionTextColor=toColor('black'),
- captionBackColor=None,
- border=None,
- spaceBefore=12,
- spaceAfter=12,
- captionGap=None,
- captionAlign='centre',
- captionPosition='bottom',
- hAlign='CENTER',
- ):
- Flowable.__init__(self)
- self.width = width
- self.figureHeight = height
- self.caption = caption
- self.captionFont = captionFont
- self.captionSize = captionSize
- self.captionTextColor = captionTextColor
- self.captionBackColor = captionBackColor
- self.captionGap = captionGap or 0.5*captionSize
- self.captionAlign = captionAlign
- self.captionPosition = captionPosition
- self._captionData = None
- self.captionHeight = 0 # work out later
- self.background = background
- self.border = border
- self.spaceBefore = spaceBefore
- self.spaceAfter = spaceAfter
- self.hAlign=hAlign
- self._getCaptionPara() #Larry Meyn's fix - otherwise they all get the number of the last chapter.
-
- def _getCaptionPara(self):
- caption = self.caption
- captionFont = self.captionFont
- captionSize = self.captionSize
- captionTextColor = self.captionTextColor
- captionBackColor = self.captionBackColor
- captionAlign = self.captionAlign
- captionPosition = self.captionPosition
- if self._captionData!=(caption,captionFont,captionSize,captionTextColor,captionBackColor,captionAlign,captionPosition):
- self._captionData = (caption,captionFont,captionSize,captionTextColor,captionBackColor,captionAlign,captionPosition)
- if isinstance(caption,Paragraph):
- self.captionPara = caption
- elif isinstance(caption,strTypes):
- self.captionStyle = ParagraphStyle(
- 'Caption',
- fontName=captionFont,
- fontSize=captionSize,
- leading=1.2*captionSize,
- textColor = captionTextColor,
- backColor = captionBackColor,
- #seems to be getting ignored
- spaceBefore=self.captionGap,
- alignment=TA_LEFT if captionAlign=='left' else TA_RIGHT if captionAlign=='right' else TA_CENTER,
- )
- #must build paragraph now to get sequencing in synch with rest of story
- self.captionPara = Paragraph(self.caption, self.captionStyle)
- else:
- raise ValueError('Figure caption of type %r is not a string or Paragraph' % type(caption))
-
- def wrap(self, availWidth, availHeight):
- # try to get the caption aligned
- if self.caption:
- self._getCaptionPara()
- w, h = self.captionPara.wrap(self.width, availHeight - self.figureHeight)
- self.captionHeight = h + self.captionGap
- self.height = self.captionHeight + self.figureHeight
- if w>self.width: self.width = w
- else:
- self.height = self.figureHeight
- if self.hAlign in ('CENTER','CENTRE',TA_CENTER):
- self.dx = 0.5 * (availWidth - self.width)
- elif self.hAlign in ('RIGHT',TA_RIGHT):
- self.dx = availWidth - self.width
- else:
- self.dx = 0
- return (self.width, self.height)
-
- def draw(self):
- self.canv.translate(self.dx, 0)
- if self.caption and self.captionPosition=='bottom':
- self.canv.translate(0, self.captionHeight)
- if self.background:
- self.drawBackground()
- if self.border:
- self.drawBorder()
- self.canv.saveState()
- self.drawFigure()
- self.canv.restoreState()
- if self.caption:
- if self.captionPosition=='bottom':
- self.canv.translate(0, -self.captionHeight)
- else:
- self.canv.translate(0, self.figureHeight+self.captionGap)
- self._getCaptionPara()
- self.drawCaption()
-
- def drawBorder(self):
- canv = self.canv
- border = self.border
- bc = getattr(border,'color',None)
- bw = getattr(border,'width',None)
- bd = getattr(border,'dashArray',None)
- ss = bc or bw or bd
- if ss:
- canv.saveState()
- if bc: canv.setStrokeColor(bc)
- if bw: canv.setLineWidth(bw)
- if bd: canv.setDash(bd)
- canv.rect(0, 0, self.width, self.figureHeight,fill=0,stroke=1)
- if ss:
- canv.restoreState()
-
- def _doBackground(self, color):
- self.canv.saveState()
- self.canv.setFillColor(self.background)
- self.canv.rect(0, 0, self.width, self.figureHeight, fill=1)
- self.canv.restoreState()
-
- def drawBackground(self):
- """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."""
- if isColor(self.background):
- self._doBackground(self.background)
- else:
- try:
- c = toColor(self.background)
- self._doBackground(c)
- except:
- pass
-
- def drawCaption(self):
- self.captionPara.drawOn(self.canv, 0, 0)
-
- def drawFigure(self):
- pass
-
-def drawPage(canvas,x, y, width, height):
- #draws something which looks like a page
- pth = canvas.beginPath()
- corner = 0.05*width
-
- # shaded backdrop offset a little
- canvas.setFillColorRGB(0.5,0.5,0.5)
- canvas.rect(x + corner, y - corner, width, height, stroke=0, fill=1)
-
- #'sheet of paper' in light yellow
- canvas.setFillColorRGB(1,1,0.9)
- canvas.setLineWidth(0)
- canvas.rect(x, y, width, height, stroke=1, fill=1)
-
- #reset
- canvas.setFillColorRGB(0,0,0)
- canvas.setStrokeColorRGB(0,0,0)
-
-class PageFigure(Figure):
- """Shows a blank page in a frame, and draws on that. Used in
- illustrations of how PLATYPUS works."""
- def __init__(self, background=None):
- Figure.__init__(self, 3*inch, 3*inch)
- self.caption = 'Figure 1 - a blank page'
- self.captionStyle = captionStyle
- self.background = background
-
- def drawVirtualPage(self):
- pass
-
- def drawFigure(self):
- drawPage(self.canv, 0.625*inch, 0.25*inch, 1.75*inch, 2.5*inch)
- self.canv.translate(0.625*inch, 0.25*inch)
- self.canv.scale(1.75/8.27, 2.5/11.69)
- self.drawVirtualPage()
-
-class PlatPropFigure1(PageFigure):
- """This shows a page with a frame on it"""
- def __init__(self):
- PageFigure.__init__(self)
- self.caption = "Figure 1 - a page with a simple frame"
- def drawVirtualPage(self):
- demo1(self.canv)
-
-class FlexFigure(Figure):
- """Base for a figure class with a caption. Can grow or shrink in proportion"""
- def __init__(self, width, height, caption, background=None,
- captionFont='Helvetica-Oblique',captionSize=8,
- captionTextColor=colors.black,
- shrinkToFit=1,
- growToFit=1,
- spaceBefore=12,
- spaceAfter=12,
- captionGap=9,
- captionAlign='centre',
- captionPosition='top',
- scaleFactor=None,
- hAlign='CENTER',
- border=1,
- ):
- Figure.__init__(self, width, height, caption,
- captionFont=captionFont,
- captionSize=captionSize,
- background=None,
- captionTextColor=captionTextColor,
- spaceBefore = spaceBefore,
- spaceAfter = spaceAfter,
- captionGap=captionGap,
- captionAlign=captionAlign,
- captionPosition=captionPosition,
- hAlign=hAlign,
- border=border,
- )
- self.shrinkToFit = shrinkToFit #if set and wrap is too tight, shrinks
- self.growToFit = growToFit #if set and wrap is too small, grows
- self.scaleFactor = scaleFactor
- self._scaleFactor = None
- self.background = background
-
- def _scale(self,availWidth,availHeight):
- "Rescale to fit according to the rules, but only once"
- if self._scaleFactor is None or self.width>availWidth or self.height>availHeight:
- w, h = Figure.wrap(self, availWidth, availHeight)
- captionHeight = h - self.figureHeight
- if self.scaleFactor is None:
- #scale factor None means auto
- self._scaleFactor = min(availWidth/self.width,(availHeight-captionHeight)/self.figureHeight)
- else: #they provided a factor
- self._scaleFactor = self.scaleFactor
- if self._scaleFactor<1 and self.shrinkToFit:
- self.width = self.width * self._scaleFactor - 0.0001
- self.figureHeight = self.figureHeight * self._scaleFactor
- elif self._scaleFactor>1 and self.growToFit:
- self.width = self.width*self._scaleFactor - 0.0001
- self.figureHeight = self.figureHeight * self._scaleFactor
-
- def wrap(self, availWidth, availHeight):
- self._scale(availWidth,availHeight)
- return Figure.wrap(self, availWidth, availHeight)
-
- def split(self, availWidth, availHeight):
- self._scale(availWidth,availHeight)
- return Figure.split(self, availWidth, availHeight)
-
-class ImageFigure(FlexFigure):
- """Image with a caption below it"""
- def __init__(self, filename, caption, background=None,scaleFactor=None,hAlign='CENTER',border=None):
- assert os.path.isfile(filename), 'image file %s not found' % filename
- from reportlab.lib.utils import ImageReader
- w, h = ImageReader(filename).getSize()
- self.filename = filename
- FlexFigure.__init__(self, w, h, caption, background,scaleFactor=scaleFactor,hAlign=hAlign,border=border)
-
- def drawFigure(self):
- self.canv.drawImage(self.filename,
- 0, 0,self.width, self.figureHeight)
-
-class DrawingFigure(FlexFigure):
- """Drawing with a caption below it. Clunky, scaling fails."""
- def __init__(self, modulename, classname, caption, baseDir=None, background=None):
- module = recursiveImport(modulename, baseDir)
- klass = getattr(module, classname)
- self.drawing = klass()
- FlexFigure.__init__(self,
- self.drawing.width,
- self.drawing.height,
- caption,
- background)
- self.growToFit = 1
-
- def drawFigure(self):
- self.canv.scale(self._scaleFactor, self._scaleFactor)
- self.drawing.drawOn(self.canv, 0, 0)
-
-try:
- from rlextra.pageCatcher.pageCatcher import restoreForms, storeForms, storeFormsInMemory, restoreFormsInMemory
- _hasPageCatcher = 1
-except ImportError:
- _hasPageCatcher = 0
-if _hasPageCatcher:
- ####################################################################
- #
- # PageCatcher plugins
- # These let you use our PageCatcher product to add figures
- # to other documents easily.
- ####################################################################
- class PageCatcherCachingMixIn:
- "Helper functions to cache pages for figures"
-
- def getFormName(self, pdfFileName, pageNo):
- #naming scheme works within a directory only
- dirname, filename = os.path.split(pdfFileName)
- root, ext = os.path.splitext(filename)
- return '%s_page%d' % (root, pageNo)
-
- def needsProcessing(self, pdfFileName, pageNo):
- "returns 1 if no forms or form is older"
- formName = self.getFormName(pdfFileName, pageNo)
- if os.path.exists(formName + '.frm'):
- formModTime = os.stat(formName + '.frm')[8]
- pdfModTime = os.stat(pdfFileName)[8]
- return (pdfModTime > formModTime)
- else:
- return 1
-
- def processPDF(self, pdfFileName, pageNo):
- formName = self.getFormName(pdfFileName, pageNo)
- storeForms(pdfFileName, formName + '.frm',
- prefix= formName + '_',
- pagenumbers=[pageNo])
- #print 'stored %s.frm' % formName
- return formName + '.frm'
-
- class cachePageCatcherFigureNonA4(FlexFigure, PageCatcherCachingMixIn):
- """PageCatcher page with a caption below it. Size to be supplied."""
- # This should merge with PageFigure into one class that reuses
- # form information to determine the page orientation...
- def __init__(self, filename, pageNo, caption, width, height, background=None):
- self.dirname, self.filename = os.path.split(filename)
- if self.dirname == '':
- self.dirname = os.curdir
- self.pageNo = pageNo
- self.formName = self.getFormName(self.filename, self.pageNo) + '_' + str(pageNo)
- FlexFigure.__init__(self, width, height, caption, background)
-
- def drawFigure(self):
- self.canv.saveState()
- if not self.canv.hasForm(self.formName):
- restorePath = self.dirname + os.sep + self.filename
- #does the form file exist? if not, generate it.
- formFileName = self.getFormName(restorePath, self.pageNo) + '.frm'
- if self.needsProcessing(restorePath, self.pageNo):
- #print 'preprocessing PDF %s page %s' % (restorePath, self.pageNo)
- self.processPDF(restorePath, self.pageNo)
- names = restoreForms(formFileName, self.canv)
- self.canv.scale(self._scaleFactor, self._scaleFactor)
- self.canv.doForm(self.formName)
- self.canv.restoreState()
-
- class cachePageCatcherFigure(cachePageCatcherFigureNonA4):
- """PageCatcher page with a caption below it. Presumes A4, Portrait.
- This needs our commercial PageCatcher product, or you'll get a blank."""
- def __init__(self, filename, pageNo, caption, width=595, height=842, background=None):
- cachePageCatcherFigureNonA4.__init__(self, filename, pageNo, caption, width, height, background=background)
-
- class PageCatcherFigureNonA4(FlexFigure):
- """PageCatcher page with a caption below it. Size to be supplied."""
- # This should merge with PageFigure into one class that reuses
- # form information to determine the page orientation...
- _cache = {}
- def __init__(self, filename, pageNo, caption, width, height, background=None, caching=None):
- fn = self.filename = filename
- self.pageNo = pageNo
- fn = fn.replace(os.sep,'_').replace('/','_').replace('\\','_').replace('-','_').replace(':','_')
- self.prefix = fn.replace('.','_')+'_'+str(pageNo)+'_'
- self.formName = self.prefix + str(pageNo)
- self.caching = caching
- FlexFigure.__init__(self, width, height, caption, background)
-
- def drawFigure(self):
- if not self.canv.hasForm(self.formName):
- if self.filename in self._cache:
- f,data = self._cache[self.filename]
- else:
- f = open(self.filename,'rb')
- pdf = f.read()
- f.close()
- f, data = storeFormsInMemory(pdf, pagenumbers=[self.pageNo], prefix=self.prefix)
- if self.caching=='memory':
- self._cache[self.filename] = f, data
- f = restoreFormsInMemory(data, self.canv)
- self.canv.saveState()
- self.canv.scale(self._scaleFactor, self._scaleFactor)
- self.canv.doForm(self.formName)
- self.canv.restoreState()
-
- class PageCatcherFigure(PageCatcherFigureNonA4):
- """PageCatcher page with a caption below it. Presumes A4, Portrait.
- This needs our commercial PageCatcher product, or you'll get a blank."""
- def __init__(self, filename, pageNo, caption, width=595, height=842, background=None, caching=None):
- PageCatcherFigureNonA4.__init__(self, filename, pageNo, caption, width, height, background=background, caching=caching)
-
-def demo1(canvas):
- frame = Frame(
- 2*inch, # x
- 4*inch, # y at bottom
- 4*inch, # width
- 5*inch, # height
- showBoundary = 1 # helps us see what's going on
- )
- bodyStyle = ParagraphStyle('Body', fontName=_baseFontName, fontSize=24, leading=28, spaceBefore=6)
- para1 = Paragraph('Spam spam spam spam. ' * 5, bodyStyle)
- para2 = Paragraph('Eggs eggs eggs. ' * 5, bodyStyle)
- mydata = [para1, para2]
-
- #this does the packing and drawing. The frame will consume
- #items from the front of the list as it prints them
- frame.addFromList(mydata,canvas)
-
-def test1():
- c = Canvas('figures.pdf')
- f = Frame(inch, inch, 6*inch, 9*inch, showBoundary=1)
- v = PlatPropFigure1()
- v.captionTextColor = toColor('blue')
- v.captionBackColor = toColor('lightyellow')
- f.addFromList([v],c)
- c.save()
-
-if __name__ == '__main__':
- test1()
diff --git a/reportlab/platypus/flowables.py b/reportlab/platypus/flowables.py
deleted file mode 100644
index f14c3640..00000000
--- a/reportlab/platypus/flowables.py
+++ /dev/null
@@ -1,1979 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/flowables.py
-__version__=''' $Id$ '''
-__doc__="""
-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).
-"""
-import os
-from copy import deepcopy, copy
-from reportlab.lib.colors import red, gray, lightgrey
-from reportlab.lib.rl_accel import fp_str
-from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
-from reportlab.lib.styles import _baseFontName
-from reportlab.lib.utils import strTypes
-from reportlab.pdfbase import pdfutils
-from reportlab.pdfbase.pdfmetrics import stringWidth
-from reportlab.rl_config import _FUZZ, overlapAttachedSpace, ignoreContainerActions, listWrapOnFakeWidth
-import collections
-
-__all__=('TraceInfo','Flowable','XBox','Preformatted','Image','Spacer','PageBreak','SlowPageBreak',
- 'CondPageBreak','KeepTogether','Macro','CallerMacro','ParagraphAndImage',
- 'FailOnWrap','HRFlowable','PTOContainer','KeepInFrame','UseUpSpace',
- 'ListFlowable','ListItem','DDIndenter','LIIndenter',
- 'DocAssign', 'DocExec', 'DocAssert', 'DocPara', 'DocIf', 'DocWhile',
- 'PageBreakIfNotEmpty',
- )
-class TraceInfo:
- "Holder for info about where an object originated"
- def __init__(self):
- self.srcFile = '(unknown)'
- self.startLineNo = -1
- self.startLinePos = -1
- self.endLineNo = -1
- self.endLinePos = -1
-
-#############################################################
-# Flowable Objects - a base class and a few examples.
-# One is just a box to get some metrics. We also have
-# a paragraph, an image and a special 'page break'
-# object which fills the space.
-#############################################################
-class 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.
-
- """
- _fixedWidth = 0 #assume wrap results depend on arguments?
- _fixedHeight = 0
-
- def __init__(self):
- self.width = 0
- self.height = 0
- self.wrapped = 0
-
- #these are hints to packers/frames as to how the floable should be positioned
- self.hAlign = 'LEFT' #CENTER/CENTRE or RIGHT
- self.vAlign = 'BOTTOM' #MIDDLE or TOP
-
- #optional holder for trace info
- self._traceInfo = None
- self._showBoundary = None
-
- #many flowables handle text and must be processed in the
- #absence of a canvas. tagging them with their encoding
- #helps us to get conversions right. Use Python codec names.
- self.encoding = None
-
- def _drawOn(self,canv):
- '''ensure canv is set on and then draw'''
- self.canv = canv
- self.draw()#this is the bit you overload
- del self.canv
-
- def _hAlignAdjust(self,x,sW=0):
- if sW and hasattr(self,'hAlign'):
- a = self.hAlign
- if a in ('CENTER','CENTRE', TA_CENTER):
- x += 0.5*sW
- elif a in ('RIGHT',TA_RIGHT):
- x += sW
- elif a not in ('LEFT',TA_LEFT):
- raise ValueError("Bad hAlign value "+str(a))
- return x
-
- def drawOn(self, canvas, x, y, _sW=0):
- "Tell it to draw itself on the canvas. Do not override"
- x = self._hAlignAdjust(x,_sW)
- canvas.saveState()
- canvas.translate(x, y)
- self._drawOn(canvas)
- if hasattr(self, '_showBoundary') and self._showBoundary:
- #diagnostic tool support
- canvas.setStrokeColor(gray)
- canvas.rect(0,0,self.width, self.height)
- canvas.restoreState()
-
- def wrapOn(self, canv, aW, aH):
- '''intended for use by packers allows setting the canvas on
- during the actual wrap'''
- self.canv = canv
- w, h = self.wrap(aW,aH)
- del self.canv
- return w, h
-
- def wrap(self, 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."""
- return (self.width, self.height)
-
- def minWidth(self):
- """This should return the minimum required width"""
- return getattr(self,'_minWidth',self.width)
-
- def splitOn(self, canv, aW, aH):
- '''intended for use by packers allows setting the canvas on
- during the actual split'''
- self.canv = canv
- S = self.split(aW,aH)
- del self.canv
- return S
-
- def split(self, 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 []"""
- return []
-
- def getKeepWithNext(self):
- """returns boolean determining whether the next flowable should stay with this one"""
- if hasattr(self,'keepWithNext'): return self.keepWithNext
- elif hasattr(self,'style') and hasattr(self.style,'keepWithNext'): return self.style.keepWithNext
- else: return 0
-
- def getSpaceAfter(self):
- """returns how much space should follow this item if another item follows on the same page."""
- if hasattr(self,'spaceAfter'): return self.spaceAfter
- elif hasattr(self,'style') and hasattr(self.style,'spaceAfter'): return self.style.spaceAfter
- else: return 0
-
- def getSpaceBefore(self):
- """returns how much space should precede this item if another item precedess on the same page."""
- if hasattr(self,'spaceBefore'): return self.spaceBefore
- elif hasattr(self,'style') and hasattr(self.style,'spaceBefore'): return self.style.spaceBefore
- else: return 0
-
- def isIndexing(self):
- """Hook for IndexingFlowables - things which have cross references"""
- return 0
-
- def identity(self, 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
- '''
- if hasattr(self, 'getPlainText'):
- r = self.getPlainText(identify=1)
- elif hasattr(self, 'text'):
- r = str(self.text)
- else:
- r = '...'
- if r and maxLen:
- r = r[:maxLen]
- return "<%s at %s%s>%s" % (self.__class__.__name__, hex(id(self)), self._frameName(), r)
-
- def _doctemplateAttr(self,a):
- return getattr(getattr(getattr(self,'canv',None),'_doctemplate',None),a,None)
-
- def _frameName(self):
- f = getattr(self,'_frame',None)
- if not f: f = self._doctemplateAttr('frame')
- if f and f.id: return ' frame=%s' % f.id
- return ''
-
-class XBox(Flowable):
- """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()."""
- def __init__(self, width, height, text = 'A Box'):
- Flowable.__init__(self)
- self.width = width
- self.height = height
- self.text = text
-
- def __repr__(self):
- return "XBox(w=%s, h=%s, t=%s)" % (self.width, self.height, self.text)
-
- def draw(self):
- self.canv.rect(0, 0, self.width, self.height)
- self.canv.line(0, 0, self.width, self.height)
- self.canv.line(0, self.height, self.width, 0)
-
- #centre the text
- self.canv.setFont(_baseFontName,12)
- self.canv.drawCentredString(0.5*self.width, 0.5*self.height, self.text)
-
-def _trimEmptyLines(lines):
- #don't want the first or last to be empty
- while len(lines) and lines[0].strip() == '':
- lines = lines[1:]
- while len(lines) and lines[-1].strip() == '':
- lines = lines[:-1]
- return lines
-
-def _dedenter(text,dedent=0):
- '''
- tidy up text - carefully, it is probably code. If people want to
- indent code within a source script, you can supply an arg to dedent
- and it will chop off that many character, otherwise it leaves
- left edge intact.
- '''
- lines = text.split('\n')
- if dedent>0:
- templines = _trimEmptyLines(lines)
- lines = []
- for line in templines:
- line = line[dedent:].rstrip()
- lines.append(line)
- else:
- lines = _trimEmptyLines(lines)
-
- return lines
-
-
-SPLIT_CHARS = "[{( ,.;:/\\-"
-
-def splitLines(lines, maximum_length, split_characters, new_line_characters):
- if split_characters is None:
- split_characters = SPLIT_CHARS
- if new_line_characters is None:
- new_line_characters = ""
- # Return a table of lines
- lines_splitted = []
- for line in lines:
- if len(line) > maximum_length:
- splitLine(line, lines_splitted, maximum_length, \
- split_characters, new_line_characters)
- else:
- lines_splitted.append(line)
- return lines_splitted
-
-def splitLine(line_to_split, lines_splitted, maximum_length, \
-split_characters, new_line_characters):
- # Used to implement the characters added
- #at the beginning of each new line created
- first_line = True
-
- # Check if the text can be splitted
- while line_to_split and len(line_to_split)>0:
-
- # Index of the character where we can split
- split_index = 0
-
- # Check if the line length still exceeds the maximum length
- if len(line_to_split) <= maximum_length:
- # Return the remaining of the line
- split_index = len(line_to_split)
- else:
- # Iterate for each character of the line
- for line_index in range(maximum_length):
- # Check if the character is in the list
- # of allowed characters to split on
- if line_to_split[line_index] in split_characters:
- split_index = line_index + 1
-
- # If the end of the line was reached
- # with no character to split on
- if split_index==0:
- split_index = line_index + 1
-
- if first_line:
- lines_splitted.append(line_to_split[0:split_index])
- first_line = False
- maximum_length -= len(new_line_characters)
- else:
- lines_splitted.append(new_line_characters + \
- line_to_split[0:split_index])
-
- # Remaining text to split
- line_to_split = line_to_split[split_index:]
-
-class Preformatted(Flowable):
- """This is like the HTML 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. '> ').
- """
- def __init__(self, text, style, bulletText = None, dedent=0, maxLineLength=None, splitChars=None, newLineChars=""):
- """text is the text to display. If dedent is set then common leading space
- will be chopped off the front (for example if the entire text is indented
- 6 spaces or more then each line will have 6 spaces removed from the front).
- """
- self.style = style
- self.bulletText = bulletText
- self.lines = _dedenter(text,dedent)
- if text and maxLineLength:
- self.lines = splitLines(
- self.lines,
- maxLineLength,
- splitChars,
- newLineChars
- )
-
- def __repr__(self):
- bT = self.bulletText
- H = "Preformatted("
- if bT is not None:
- H = "Preformatted(bulletText=%s," % repr(bT)
- return "%s'''\\ \n%s''')" % (H, '\n'.join(self.lines))
-
- def wrap(self, availWidth, availHeight):
- self.width = availWidth
- self.height = self.style.leading*len(self.lines)
- return (self.width, self.height)
-
- def minWidth(self):
- style = self.style
- fontSize = style.fontSize
- fontName = style.fontName
- return max([stringWidth(line,fontName,fontSize) for line in self.lines])
-
- def split(self, availWidth, availHeight):
- #returns two Preformatted objects
-
- #not sure why they can be called with a negative height
- if availHeight < self.style.leading:
- return []
-
- linesThatFit = int(availHeight * 1.0 / self.style.leading)
-
- text1 = '\n'.join(self.lines[0:linesThatFit])
- text2 = '\n'.join(self.lines[linesThatFit:])
- style = self.style
- if style.firstLineIndent != 0:
- style = deepcopy(style)
- style.firstLineIndent = 0
- return [Preformatted(text1, self.style), Preformatted(text2, style)]
-
- def draw(self):
- #call another method for historical reasons. Besides, I
- #suspect I will be playing with alternate drawing routines
- #so not doing it here makes it easier to switch.
-
- cur_x = self.style.leftIndent
- cur_y = self.height - self.style.fontSize
- self.canv.addLiteral('%PreformattedPara')
- if self.style.textColor:
- self.canv.setFillColor(self.style.textColor)
- tx = self.canv.beginText(cur_x, cur_y)
- #set up the font etc.
- tx.setFont( self.style.fontName,
- self.style.fontSize,
- self.style.leading)
-
- for text in self.lines:
- tx.textLine(text)
- self.canv.drawText(tx)
-
-class Image(Flowable):
- """an image (digital picture). Formats supported by PIL/Java 1.4 (the Python/Java Imaging Library
- are supported. At the present time images as flowables are always centered horozontally
- in the frame. 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.
- """
- _fixedWidth = 1
- _fixedHeight = 1
- def __init__(self, filename, width=None, height=None, kind='direct', mask="auto", lazy=1):
- """If size to draw at not specified, get it from the image."""
- self.hAlign = 'CENTER'
- self._mask = mask
- fp = hasattr(filename,'read')
- if fp:
- self._file = filename
- self.filename = repr(filename)
- else:
- self._file = self.filename = filename
- if not fp and os.path.splitext(filename)[1] in ['.jpg', '.JPG', '.jpeg', '.JPEG']:
- # if it is a JPEG, will be inlined within the file -
- # but we still need to know its size now
- from reportlab.lib.utils import open_for_read
- f = open_for_read(filename, 'b')
- try:
- try:
- info = pdfutils.readJPEGInfo(f)
- except:
- #couldn't read as a JPEG, try like normal
- self._setup(width,height,kind,lazy)
- return
- finally:
- f.close()
- self.imageWidth = info[0]
- self.imageHeight = info[1]
- self._img = None
- self._setup(width,height,kind,0)
- elif fp:
- self._setup(width,height,kind,0)
- else:
- self._setup(width,height,kind,lazy)
-
- def _setup(self,width,height,kind,lazy):
- self._lazy = lazy
- self._width = width
- self._height = height
- self._kind = kind
- if lazy<=0: self._setup_inner()
-
- def _setup_inner(self):
- width = self._width
- height = self._height
- kind = self._kind
- img = self._img
- if img: self.imageWidth, self.imageHeight = img.getSize()
- if self._lazy>=2: del self._img
- if kind in ['direct','absolute']:
- self.drawWidth = width or self.imageWidth
- self.drawHeight = height or self.imageHeight
- elif kind in ['percentage','%']:
- self.drawWidth = self.imageWidth*width*0.01
- self.drawHeight = self.imageHeight*height*0.01
- elif kind in ['bound','proportional']:
- factor = min(float(width)/self.imageWidth,float(height)/self.imageHeight)
- self.drawWidth = self.imageWidth*factor
- self.drawHeight = self.imageHeight*factor
-
- def _restrictSize(self,aW,aH):
- if self.drawWidth>aW+_FUZZ or self.drawHeight>aH+_FUZZ:
- self._oldDrawSize = self.drawWidth, self.drawHeight
- factor = min(float(aW)/self.drawWidth,float(aH)/self.drawHeight)
- self.drawWidth *= factor
- self.drawHeight *= factor
- return self.drawWidth, self.drawHeight
-
- def _unRestrictSize(self):
- dwh = getattr(self,'_oldDrawSize',None)
- if dwh:
- self.drawWidth, self.drawHeight = dwh
-
- def __getattr__(self,a):
- if a=='_img':
- from reportlab.lib.utils import ImageReader #this may raise an error
- self._img = ImageReader(self._file)
- if not isinstance(self._file,strTypes):
- self._file = None
- if self._lazy>=2: self._lazy = 1 #here we're assuming we cannot read again
- return self._img
- elif a in ('drawWidth','drawHeight','imageWidth','imageHeight'):
- self._setup_inner()
- return self.__dict__[a]
- raise AttributeError(".%s" % (id(self),a))
-
- def wrap(self, availWidth, availHeight):
- #the caller may decide it does not fit.
- return self.drawWidth, self.drawHeight
-
- def draw(self):
- lazy = self._lazy
- if lazy>=2: self._lazy = 1
- self.canv.drawImage( self._img or self.filename,
- getattr(self,'_offs_x',0),
- getattr(self,'_offs_y',0),
- self.drawWidth,
- self.drawHeight,
- mask=self._mask,
- )
- if lazy>=2:
- self._img = self._file = None
- self._lazy = lazy
-
- def identity(self,maxLen=None):
- r = Flowable.identity(self,maxLen)
- if r[-4:]=='>...' and isinstance(self.filename,str):
- r = "%s filename=%s>" % (r[:-4],self.filename)
- return r
-
-class NullDraw(Flowable):
- def draw(self):
- pass
-
-class Spacer(NullDraw):
- """A spacer just takes up space and doesn't draw anything - it guarantees
- a gap between objects."""
- _fixedWidth = 1
- _fixedHeight = 1
- def __init__(self, width, height, isGlue=False):
- self.width = width
- if isGlue:
- self.height = 1e-4
- self.spacebefore = height
- self.height = height
-
- def __repr__(self):
- return "%s(%s, %s)" % (self.__class__.__name__,self.width, self.height)
-
-class UseUpSpace(NullDraw):
- def __init__(self):
- pass
-
- def __repr__(self):
- return "%s()" % self.__class__.__name__
-
- def wrap(self, availWidth, availHeight):
- self.width = availWidth
- self.height = availHeight
- return (availWidth,availHeight-1e-8) #step back a point
-
-class PageBreak(UseUpSpace):
- """Move on to the next page in the document.
- This works by consuming all remaining space in the frame!"""
- def __init__(self,nextTemplate=None):
- self.nextTemplate = nextTemplate
-
-class SlowPageBreak(PageBreak):
- pass
-
-class PageBreakIfNotEmpty(PageBreak):
- pass
-
-class CondPageBreak(Spacer):
- """use up a frame if not enough vertical space effectively CondFrameBreak"""
- def __init__(self, height):
- self.height = height
-
- def __repr__(self):
- return "CondPageBreak(%s)" %(self.height,)
-
- def wrap(self, availWidth, availHeight):
- if availHeightaH and (not self._maxHeight or aH>self._maxHeight)
- C1 = (self._H0>aH) or C0 and atTop
- if C0 or C1:
- if C0:
- from reportlab.platypus.doctemplate import FrameBreak
- A = FrameBreak
- else:
- from reportlab.platypus.doctemplate import NullActionFlowable
- A = NullActionFlowable
- S.insert(0,A())
- return S
-
- def identity(self, maxLen=None):
- msg = "<%s at %s%s> containing :%s" % (self.__class__.__name__,hex(id(self)),self._frameName(),"\n".join([f.identity() for f in self._content]))
- if maxLen:
- return msg[0:maxLen]
- else:
- return msg
-
-class Macro(Flowable):
- """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'"""
- def __init__(self, command):
- self.command = command
- def __repr__(self):
- return "Macro(%s)" % repr(self.command)
- def wrap(self, availWidth, availHeight):
- return (0,0)
- def draw(self):
- exec(self.command, globals(), {'canvas':self.canv})
-
-def _nullCallable(*args,**kwds):
- pass
-
-class CallerMacro(Flowable):
- '''
- like Macro, but with callable command(s)
- drawCallable(self)
- wrapCallable(self,aW,aH)
- '''
- def __init__(self, drawCallable=None, wrapCallable=None):
- self._drawCallable = drawCallable or _nullCallable
- self._wrapCallable = wrapCallable or _nullCallable
- def __repr__(self):
- return "CallerMacro(%r,%r)" % (self._drawCallable,self._wrapCallable)
- def wrap(self, aW, aH):
- self._wrapCallable(self,aW,aH)
- return (0,0)
- def draw(self):
- self._drawCallable(self)
-
-class ParagraphAndImage(Flowable):
- '''combine a Paragraph and an Image'''
- def __init__(self,P,I,xpad=3,ypad=3,side='right'):
- self.P = P
- self.I = I
- self.xpad = xpad
- self.ypad = ypad
- self._side = side
-
- def getSpaceBefore(self):
- return max(self.P.getSpaceBefore(),self.I.getSpaceBefore())
-
- def getSpaceAfter(self):
- return max(self.P.getSpaceAfter(),self.I.getSpaceAfter())
-
- def wrap(self,availWidth,availHeight):
- wI, hI = self.I.wrap(availWidth,availHeight)
- self.wI = wI
- self.hI = hI
- # work out widths array for breaking
- self.width = availWidth
- P = self.P
- style = P.style
- xpad = self.xpad
- ypad = self.ypad
- leading = style.leading
- leftIndent = style.leftIndent
- later_widths = availWidth - leftIndent - style.rightIndent
- intermediate_widths = later_widths - xpad - wI
- first_line_width = intermediate_widths - style.firstLineIndent
- P.width = 0
- nIW = int((hI+ypad)/(leading*1.0))
- P.blPara = P.breakLines([first_line_width] + nIW*[intermediate_widths]+[later_widths])
- if self._side=='left':
- self._offsets = [wI+xpad]*(1+nIW)+[0]
- P.height = len(P.blPara.lines)*leading
- self.height = max(hI,P.height)
- return (self.width, self.height)
-
- def split(self,availWidth, availHeight):
- P, wI, hI, ypad = self.P, self.wI, self.hI, self.ypad
- if hI+ypad>availHeight or len(P.frags)<=0: return []
- S = P.split(availWidth,availHeight)
- if not S: return S
- P = self.P = S[0]
- del S[0]
- style = P.style
- P.height = len(self.P.blPara.lines)*style.leading
- self.height = max(hI,P.height)
- return [self]+S
-
- def draw(self):
- canv = self.canv
- if self._side=='left':
- self.I.drawOn(canv,0,self.height-self.hI)
- self.P._offsets = self._offsets
- try:
- self.P.drawOn(canv,0,0)
- finally:
- del self.P._offsets
- else:
- self.I.drawOn(canv,self.width-self.wI-self.xpad,self.height-self.hI)
- self.P.drawOn(canv,0,0)
-
-class FailOnWrap(NullDraw):
- def wrap(self, availWidth, availHeight):
- raise ValueError("FailOnWrap flowable wrapped and failing as ordered!")
-
-class FailOnDraw(Flowable):
- def wrap(self, availWidth, availHeight):
- return 0,0
-
- def draw(self):
- raise ValueError("FailOnDraw flowable drawn, and failing as ordered!")
-
-class HRFlowable(Flowable):
- '''Like the hr tag'''
- def __init__(self,
- width="80%",
- thickness=1,
- lineCap='round',
- color=lightgrey,
- spaceBefore=1, spaceAfter=1,
- hAlign='CENTER', vAlign='BOTTOM',
- dash=None):
- Flowable.__init__(self)
- self.width = width
- self.lineWidth = thickness
- self.lineCap=lineCap
- self.spaceBefore = spaceBefore
- self.spaceAfter = spaceAfter
- self.color = color
- self.hAlign = hAlign
- self.vAlign = vAlign
- self.dash = dash
-
- def __repr__(self):
- return "HRFlowable(width=%s, height=%s)" % (self.width, self.height)
-
- def wrap(self, availWidth, availHeight):
- w = self.width
- if type(w) is type(''):
- w = w.strip()
- if w.endswith('%'): w = availWidth*float(w[:-1])*0.01
- else: w = float(w)
- w = min(w,availWidth)
- self._width = w
- return w, self.lineWidth
-
- def draw(self):
- canv = self.canv
- canv.saveState()
- canv.setLineWidth(self.lineWidth)
- canv.setLineCap({'butt':0,'round':1, 'square': 2}[self.lineCap.lower()])
- canv.setStrokeColor(self.color)
- if self.dash: canv.setDash(self.dash)
- canv.line(0, 0, self._width, self.height)
- canv.restoreState()
-
-class _PTOInfo:
- def __init__(self,trailer,header):
- self.trailer = _flowableSublist(trailer)
- self.header = _flowableSublist(header)
-
-def cdeepcopy(obj):
- if hasattr(obj,'deepcopy'):
- return obj.deepcopy()
- else:
- return deepcopy(obj)
-
-class _Container(_ContainerSpace): #Abstract some common container like behaviour
- def drawOn(self, canv, x, y, _sW=0, scale=1.0, content=None, aW=None):
- '''we simulate being added to a frame'''
- from reportlab.platypus.doctemplate import ActionFlowable, Indenter
- x0 = x
- y0 = y
- pS = 0
- if aW is None: aW = self.width
- aW *= scale
- if content is None:
- content = self._content
- x = self._hAlignAdjust(x,_sW*scale)
- y += self.height*scale
- yt = y
- frame = getattr(self,'_frame',None)
- for c in content:
- if not ignoreContainerActions and isinstance(c,ActionFlowable):
- c.apply(self.canv._doctemplate)
- continue
- if isinstance(c,Indenter):
- x += c.left*scale
- aW -= (c.left+c.right)*scale
- continue
- w, h = c.wrapOn(canv,aW,0xfffffff)
- if (w<_FUZZ or h<_FUZZ) and not getattr(c,'_ZEROSIZE',None): continue
- if yt!=y:
- s = c.getSpaceBefore()
- if not getattr(c,'_SPACETRANSFER',False):
- h += max(s-pS,0)
- y -= h
- fbg = getattr(frame,'_frameBGs',None)
- s = c.getSpaceAfter()
- if getattr(c,'_SPACETRANSFER',False):
- s = pS
- pS = s
- if fbg:
- fbgl, fbgr, fbgc = fbg[-1]
- fbw = scale*(frame._width-fbgl-fbgr)
- fbh = y + h + pS
- fby = max(y0,y-pS)
- fbh = max(0,fbh-fby)
- if abs(fbw)>_FUZZ and abs(fbh)>_FUZZ:
- canv.saveState()
- canv.setFillColor(fbgc)
- canv.rect(x0+scale*(fbgl-frame._leftPadding)-0.1,fby-0.1,fbw+0.2,fbh+0.2,stroke=0,fill=1)
- canv.restoreState()
- c._frame = frame
- c.drawOn(canv,x,y,_sW=aW-w)
- if c is not content[-1] and not getattr(c,'_SPACETRANSFER',None):
- y -= pS
- del c._frame
-
- def copyContent(self,content=None):
- C = [].append
- for c in (content or self._content):
- C(cdeepcopy(c))
- self._content = C.__self__
-
-class PTOContainer(_Container,Flowable):
- '''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.'''
- def __init__(self,content,trailer=None,header=None):
- I = _PTOInfo(trailer,header)
- self._content = C = []
- for _ in _flowableSublist(content):
- if isinstance(_,PTOContainer):
- C.extend(_._content)
- else:
- C.append(_)
- if not hasattr(_,'_ptoinfo'): _._ptoinfo = I
-
- def wrap(self,availWidth,availHeight):
- self.width, self.height = _listWrapOn(self._content,availWidth,self.canv)
- return self.width,self.height
-
- def split(self, availWidth, availHeight):
- from reportlab.platypus.doctemplate import Indenter
- if availHeight<0: return []
- canv = self.canv
- C = self._content
- x = i = H = pS = hx = 0
- n = len(C)
- I2W = {}
- dLeft = dRight = 0
- for x in xrange(n):
- c = C[x]
- I = c._ptoinfo
- if I not in I2W.keys():
- T = I.trailer
- Hdr = I.header
- tW, tH = _listWrapOn(T, availWidth, self.canv)
- if len(T): #trailer may have no content
- tSB = T[0].getSpaceBefore()
- else:
- tSB = 0
- I2W[I] = T,tW,tH,tSB
- else:
- T,tW,tH,tSB = I2W[I]
- _, h = c.wrapOn(canv,availWidth,0xfffffff)
- if isinstance(c,Indenter):
- dw = c.left+c.right
- dLeft += c.left
- dRight += c.right
- availWidth -= dw
- pS = 0
- hx = 0
- else:
- if x:
- hx = max(c.getSpaceBefore()-pS,0)
- h += hx
- pS = c.getSpaceAfter()
- H += h+pS
- tHS = tH+max(tSB,pS)
- if H+tHS>=availHeight-_FUZZ: break
- i += 1
-
- #first retract last thing we tried
- H -= (h+pS)
-
- #attempt a sub split on the last one we have
- aH = (availHeight-H-tHS-hx)*0.99999
- if aH>=0.05*availHeight:
- SS = c.splitOn(canv,availWidth,aH)
- else:
- SS = []
-
- if abs(dLeft)+abs(dRight)>1e-8:
- R1I = [Indenter(-dLeft,-dRight)]
- R2I = [Indenter(dLeft,dRight)]
- else:
- R1I = R2I = []
-
- if not SS:
- j = i
- while i>1 and C[i-1].getKeepWithNext():
- i -= 1
- C[i].keepWithNext = 0
-
- if i==1 and C[0].getKeepWithNext():
- #robin's black sheep
- i = j
- C[0].keepWithNext = 0
-
- F = [UseUpSpace()]
-
- if len(SS)>1:
- R1 = C[:i]+SS[:1]+R1I+T+F
- R2 = Hdr+R2I+SS[1:]+C[i+1:]
- elif not i:
- return []
- else:
- R1 = C[:i]+R1I+T+F
- R2 = Hdr+R2I+C[i:]
- T = R1 + [PTOContainer(R2,[copy(x) for x in I.trailer],[copy(x) for x in I.header])]
- return T
-
-#utility functions used by KeepInFrame
-def _hmodel(s0,s1,h0,h1):
- # calculate the parameters in the model
- # h = a/s**2 + b/s
- a11 = 1./s0**2
- a12 = 1./s0
- a21 = 1./s1**2
- a22 = 1./s1
- det = a11*a22-a12*a21
- b11 = a22/det
- b12 = -a12/det
- b21 = -a21/det
- b22 = a11/det
- a = b11*h0+b12*h1
- b = b21*h0+b22*h1
- return a,b
-
-def _qsolve(h,ab):
- '''solve the model v = a/s**2 + b/s for an s which gives us v==h'''
- a,b = ab
- if abs(a)<=_FUZZ:
- return b/h
- t = 0.5*b/a
- from math import sqrt
- f = -h/a
- r = t*t-f
- if r<0: return None
- r = sqrt(r)
- if t>=0:
- s1 = -t - r
- else:
- s1 = -t + r
- s2 = f/s1
- return max(1./s1, 1./s2)
-
-class KeepInFrame(_Container,Flowable):
- def __init__(self, maxWidth, maxHeight, content=[], mergeSpace=1, mode='shrink', name='',hAlign='LEFT',vAlign='BOTTOM', fakeWidth=None):
- '''mode describes the action to take when overflowing
- error raise an error in the normal way
- continue ignore ie just draw it and report maxWidth, maxHeight
- shrink shrinkToFit
- truncate fit as much as possible
- set fakeWidth to False to make _listWrapOn do the 'right' thing
- '''
- self.name = name
- self.maxWidth = maxWidth
- self.maxHeight = maxHeight
- self.mode = mode
- assert mode in ('error','overflow','shrink','truncate'), '%s invalid mode value %s' % (self.identity(),mode)
- assert maxHeight>=0, '%s invalid maxHeight value %s' % (self.identity(),maxHeight)
- if mergeSpace is None: mergeSpace = overlapAttachedSpace
- self.mergespace = mergeSpace
- self._content = content or []
- self.vAlign = vAlign
- self.hAlign = hAlign
- self.fakeWidth = fakeWidth
-
- def _getAvailableWidth(self):
- return self.maxWidth - self._leftExtraIndent - self._rightExtraIndent
-
- def identity(self, maxLen=None):
- return "<%s at %s%s%s> size=%sx%s" % (self.__class__.__name__, hex(id(self)), self._frameName(),
- getattr(self,'name','') and (' name="%s"'% getattr(self,'name','')) or '',
- getattr(self,'maxWidth','') and (' maxWidth=%s'%fp_str(getattr(self,'maxWidth',0))) or '',
- getattr(self,'maxHeight','')and (' maxHeight=%s' % fp_str(getattr(self,'maxHeight')))or '')
-
- def wrap(self,availWidth,availHeight):
- from reportlab.platypus.doctemplate import LayoutError
- mode = self.mode
- maxWidth = float(min(self.maxWidth or availWidth,availWidth))
- maxHeight = float(min(self.maxHeight or availHeight,availHeight))
- fakeWidth = self.fakeWidth
- W, H = _listWrapOn(self._content,maxWidth,self.canv, fakeWidth=fakeWidth)
- if (mode=='error' and (W>maxWidth+_FUZZ or H>maxHeight+_FUZZ)):
- ident = 'content %sx%s too large for %s' % (W,H,self.identity(30))
- #leave to keep apart from the raise
- raise LayoutError(ident)
- elif W<=maxWidth+_FUZZ and H<=maxHeight+_FUZZ:
- self.width = W-_FUZZ #we take what we get
- self.height = H-_FUZZ
- elif mode in ('overflow','truncate'): #we lie
- self.width = min(maxWidth,W)-_FUZZ
- self.height = min(maxHeight,H)-_FUZZ
- else:
- def func(x):
- x = float(x)
- W, H = _listWrapOn(self._content,x*maxWidth,self.canv, fakeWidth=fakeWidth)
- W /= x
- H /= x
- return W, H
- W0 = W
- H0 = H
- s0 = 1
- if W>maxWidth+_FUZZ:
- #squeeze out the excess width and or Height
- s1 = W/maxWidth #linear model
- W, H = func(s1)
- if H<=maxHeight+_FUZZ:
- self.width = W-_FUZZ
- self.height = H-_FUZZ
- self._scale = s1
- return W,H
- s0 = s1
- H0 = H
- W0 = W
- s1 = H/maxHeight
- W, H = func(s1)
- self.width = W-_FUZZ
- self.height = H-_FUZZ
- self._scale = s1
- if H=maxHeight+_FUZZ:
- #the standard case W should be OK, H is short we want
- #to find the smallest s with H<=maxHeight
- H1 = H
- for f in 0, 0.01, 0.05, 0.10, 0.15:
- #apply the quadratic model
- s = _qsolve(maxHeight*(1-f),_hmodel(s0,s1,H0,H1))
- W, H = func(s)
- if H<=maxHeight+_FUZZ and W<=maxWidth+_FUZZ:
- self.width = W-_FUZZ
- self.height = H-_FUZZ
- self._scale = s
- break
-
- return self.width, self.height
-
- def drawOn(self, canv, x, y, _sW=0):
- scale = getattr(self,'_scale',1.0)
- truncate = self.mode=='truncate'
- ss = scale!=1.0 or truncate
- if ss:
- canv.saveState()
- if truncate:
- p = canv.beginPath()
- p.rect(x, y, self.width,self.height)
- canv.clipPath(p,stroke=0)
- else:
- canv.translate(x,y)
- x=y=0
- canv.scale(1.0/scale, 1.0/scale)
- _Container.drawOn(self, canv, x, y, _sW=_sW, scale=scale)
- if ss: canv.restoreState()
-
-class ImageAndFlowables(_Container,Flowable):
- '''combine a list of flowables and an Image'''
- def __init__(self,I,F,imageLeftPadding=0,imageRightPadding=3,imageTopPadding=0,imageBottomPadding=3,
- imageSide='right', imageHref=None):
- self._content = _flowableSublist(F)
- self._I = I
- self._irpad = imageRightPadding
- self._ilpad = imageLeftPadding
- self._ibpad = imageBottomPadding
- self._itpad = imageTopPadding
- self._side = imageSide
- self.imageHref = imageHref
-
- def deepcopy(self):
- c = copy(self) #shallow
- self._reset()
- c.copyContent() #partially deep?
- return c
-
- def getSpaceAfter(self):
- if hasattr(self,'_C1'):
- C = self._C1
- elif hasattr(self,'_C0'):
- C = self._C0
- else:
- C = self._content
- return _Container.getSpaceAfter(self,C)
-
- def getSpaceBefore(self):
- return max(self._I.getSpaceBefore(),_Container.getSpaceBefore(self))
-
- def _reset(self):
- for a in ('_wrapArgs','_C0','_C1'):
- try:
- delattr(self,a)
- except:
- pass
-
- def wrap(self,availWidth,availHeight):
- canv = self.canv
- I = self._I
- if hasattr(self,'_wrapArgs'):
- if self._wrapArgs==(availWidth,availHeight) and getattr(I,'_oldDrawSize',None) is None:
- return self.width,self.height
- self._reset()
- I._unRestrictSize()
- self._wrapArgs = availWidth, availHeight
- I.wrap(availWidth,availHeight)
- wI, hI = I._restrictSize(availWidth,availHeight)
- self._wI = wI
- self._hI = hI
- ilpad = self._ilpad
- irpad = self._irpad
- ibpad = self._ibpad
- itpad = self._itpad
- self._iW = iW = availWidth - irpad - wI - ilpad
- aH = itpad + hI + ibpad
- if iW>_FUZZ:
- W,H0,self._C0,self._C1 = self._findSplit(canv,iW,aH)
- else:
- W = availWidth
- H0 = 0
- if W>iW+_FUZZ:
- self._C0 = []
- self._C1 = self._content
- aH = self._aH = max(aH,H0)
- self.width = availWidth
- if not self._C1:
- self.height = aH
- else:
- W1,H1 = _listWrapOn(self._C1,availWidth,canv)
- self.height = aH+H1
- return self.width, self.height
-
- def split(self,availWidth, availHeight):
- if hasattr(self,'_wrapArgs'):
- I = self._I
- if self._wrapArgs!=(availWidth,availHeight) or getattr(I,'_oldDrawSize',None) is not None:
- self._reset()
- I._unRestrictSize()
- W,H=self.wrap(availWidth,availHeight)
- if self._aH>availHeight: return []
- C1 = self._C1
- if C1:
- S = C1[0].split(availWidth,availHeight-self._aH)
- if not S:
- _C1 = []
- else:
- _C1 = [S[0]]
- C1 = S[1:]+C1[1:]
- else:
- _C1 = []
- return [ImageAndFlowables(
- self._I,
- self._C0+_C1,
- imageLeftPadding=self._ilpad,
- imageRightPadding=self._irpad,
- imageTopPadding=self._itpad,
- imageBottomPadding=self._ibpad,
- imageSide=self._side, imageHref=self.imageHref)
- ]+C1
-
- def drawOn(self, canv, x, y, _sW=0):
- if self._side=='left':
- Ix = x + self._ilpad
- Fx = Ix+ self._irpad + self._wI
- else:
- Ix = x + self.width-self._wI-self._irpad
- Fx = x
- self._I.drawOn(canv,Ix,y+self.height-self._itpad-self._hI)
-
- if self.imageHref:
- canv.linkURL(self.imageHref, (Ix, y+self.height-self._itpad-self._hI, Ix + self._wI, y+self.height), relative=1)
-
- if self._C0:
- _Container.drawOn(self, canv, Fx, y, content=self._C0, aW=self._iW)
- if self._C1:
- aW, aH = self._wrapArgs
- _Container.drawOn(self, canv, x, y-self._aH,content=self._C1, aW=aW)
-
- def _findSplit(self,canv,availWidth,availHeight,mergeSpace=1,obj=None):
- '''return max width, required height for a list of flowables F'''
- W = 0
- H = 0
- pS = sB = 0
- atTop = 1
- F = self._content
- for i,f in enumerate(F):
- w,h = f.wrapOn(canv,availWidth,0xfffffff)
- if w<=_FUZZ or h<=_FUZZ: continue
- W = max(W,w)
- if not atTop:
- s = f.getSpaceBefore()
- if mergeSpace: s = max(s-pS,0)
- H += s
- else:
- if obj is not None: obj._spaceBefore = f.getSpaceBefore()
- atTop = 0
- if H>=availHeight or w>availWidth:
- return W, availHeight, F[:i],F[i:]
- H += h
- if H>availHeight:
- from reportlab.platypus.paragraph import Paragraph
- aH = availHeight-(H-h)
- if isinstance(f,(Paragraph,Preformatted)):
- leading = f.style.leading
- nH = leading*int(aH/float(leading))+_FUZZ
- if nH1:
- S[0] = TopPadder(S[0])
- return S
-
- def drawOn(self, canvas, x, y, _sW=0):
- self.__f.drawOn(canvas,x,y-max(0,self.__dh-1e-8),_sW)
-
- def __setattr__(self,a,v):
- setattr(self.__f,a,v)
-
- def __getattr__(self,a):
- return getattr(self.__f,a)
-
- def __delattr__(self,a):
- delattr(self.__f,a)
-
-class DocAssign(NullDraw):
- '''At wrap time this flowable evaluates var=expr in the doctemplate namespace'''
- _ZEROSIZE=1
- def __init__(self,var,expr,life='forever'):
- Flowable.__init__(self)
- self.args = var,expr,life
-
- def funcWrap(self,aW,aH):
- NS=self._doctemplateAttr('_nameSpace')
- NS.update(dict(availableWidth=aW,availableHeight=aH))
- try:
- return self.func()
- finally:
- for k in 'availableWidth','availableHeight':
- try:
- del NS[k]
- except:
- pass
-
- def func(self):
- return self._doctemplateAttr('d'+self.__class__.__name__[1:])(*self.args)
-
- def wrap(self,aW,aH):
- self.funcWrap(aW,aH)
- return 0,0
-
-class DocExec(DocAssign):
- '''at wrap time exec stmt in doc._nameSpace'''
- def __init__(self,stmt,lifetime='forever'):
- Flowable.__init__(self)
- self.args=stmt,lifetime
-
-class DocPara(DocAssign):
- '''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
- '''
- def __init__(self,expr,format=None,style=None,klass=None,escape=True):
- Flowable.__init__(self)
- self.expr=expr
- self.format=format
- self.style=style
- self.klass=klass
- self.escape=escape
-
- def func(self):
- expr = self.expr
- if expr:
- if not isinstance(expr,str): expr = str(expr)
- return self._doctemplateAttr('docEval')(expr)
-
- def add_content(self,*args):
- self._doctemplateAttr('frame').add_generated_content(*args)
-
- def get_value(self,aW,aH):
- value = self.funcWrap(aW,aH)
- if self.format:
- NS=self._doctemplateAttr('_nameSpace').copy()
- NS.update(dict(availableWidth=aW,availableHeight=aH))
- NS['__expr__'] = value
- value = self.format % NS
- else:
- value = str(value)
- return value
-
- def wrap(self,aW,aH):
- value = self.get_value(aW,aH)
- P = self.klass
- if not P:
- from reportlab.platypus.paragraph import Paragraph as P
- style = self.style
- if not style:
- from reportlab.lib.styles import getSampleStyleSheet
- style=getSampleStyleSheet()['Code']
- if self.escape:
- from xml.sax.saxutils import escape
- value=escape(value)
- self.add_content(P(value,style=style))
- return 0,0
-
-class DocAssert(DocPara):
- def __init__(self,cond,format=None):
- Flowable.__init__(self)
- self.expr=cond
- self.format=format
-
- def funcWrap(self,aW,aH):
- self._cond = DocPara.funcWrap(self,aW,aH)
- return self._cond
-
- def wrap(self,aW,aH):
- value = self.get_value(aW,aH)
- if not bool(self._cond):
- raise AssertionError(value)
- return 0,0
-
-class DocIf(DocPara):
- def __init__(self,cond,thenBlock,elseBlock=[]):
- Flowable.__init__(self)
- self.expr = cond
- self.blocks = elseBlock or [],thenBlock
-
- def checkBlock(self,block):
- if not isinstance(block,(list,tuple)):
- block = (block,)
- return block
-
- def wrap(self,aW,aH):
- self.add_content(*self.checkBlock(self.blocks[int(bool(self.funcWrap(aW,aH)))]))
- return 0,0
-
-class DocWhile(DocIf):
- def __init__(self,cond,whileBlock):
- Flowable.__init__(self)
- self.expr = cond
- self.block = self.checkBlock(whileBlock)
-
- def wrap(self,aW,aH):
- if bool(self.funcWrap(aW,aH)):
- self.add_content(*(list(self.block)+[self]))
- return 0,0
diff --git a/reportlab/platypus/frames.py b/reportlab/platypus/frames.py
deleted file mode 100644
index 81a3277c..00000000
--- a/reportlab/platypus/frames.py
+++ /dev/null
@@ -1,282 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/frames.py
-
-__version__=''' $Id$ '''
-
-__doc__="""A frame is a container for content on a page.
-"""
-
-import logging
-logger = logging.getLogger('reportlab.platypus')
-
-_geomAttr=('x1', 'y1', 'width', 'height', 'leftPadding', 'bottomPadding', 'rightPadding', 'topPadding')
-from reportlab import rl_config, isPy3
-_FUZZ=rl_config._FUZZ
-
-class ShowBoundaryValue:
- def __init__(self,color=(0,0,0),width=0.1):
- self.color = color
- self.width = width
-
- if isPy3:
- def __bool__(self):
- return self.color is not None and self.width>=0
- else:
- def __nonzero__(self):
- return self.color is not None and self.width>=0
-
-
-class Frame:
- '''
- 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.
- '''
- def __init__(self, x1, y1, width,height, leftPadding=6, bottomPadding=6,
- rightPadding=6, topPadding=6, id=None, showBoundary=0,
- overlapAttachedSpace=None,_debug=None):
- self.id = id
- self._debug = _debug
-
- #these say where it goes on the page
- self.__dict__['_x1'] = x1
- self.__dict__['_y1'] = y1
- self.__dict__['_width'] = width
- self.__dict__['_height'] = height
-
- #these create some padding.
- self.__dict__['_leftPadding'] = leftPadding
- self.__dict__['_bottomPadding'] = bottomPadding
- self.__dict__['_rightPadding'] = rightPadding
- self.__dict__['_topPadding'] = topPadding
-
- # if we want a boundary to be shown
- self.showBoundary = showBoundary
-
- if overlapAttachedSpace is None: overlapAttachedSpace = rl_config.overlapAttachedSpace
- self._oASpace = overlapAttachedSpace
- self._geom()
- self._reset()
-
- def __getattr__(self,a):
- if a in _geomAttr: return self.__dict__['_'+a]
- raise AttributeError(a)
-
- def __setattr__(self,a,v):
- if a in _geomAttr:
- self.__dict__['_'+a] = v
- self._geom()
- else:
- self.__dict__[a] = v
-
- def _saveGeom(self, **kwds):
- if not self.__dict__.setdefault('_savedGeom',{}):
- for ga in _geomAttr:
- ga = '_'+ga
- self.__dict__['_savedGeom'][ga] = self.__dict__[ga]
- for k,v in kwds.items():
- setattr(self,k,v)
-
- def _restoreGeom(self):
- if self.__dict__.get('_savedGeom',None):
- for ga in _geomAttr:
- ga = '_'+ga
- self.__dict__[ga] = self.__dict__[ga]['_savedGeom']
- del self.__dict__['_savedGeom']
- self._geom()
-
- def _geom(self):
- self._x2 = self._x1 + self._width
- self._y2 = self._y1 + self._height
- #efficiency
- self._y1p = self._y1 + self._bottomPadding
- #work out the available space
- self._aW = self._x2 - self._x1 - self._leftPadding - self._rightPadding
- self._aH = self._y2 - self._y1p - self._topPadding
-
- def _reset(self):
- self._restoreGeom()
- #drawing starts at top left
- self._x = self._x1 + self._leftPadding
- self._y = self._y2 - self._topPadding
- self._atTop = 1
- self._prevASpace = 0
-
- # these two should NOT be set on a frame.
- # they are used when Indenter flowables want
- # to adjust edges e.g. to do nested lists
- self._leftExtraIndent = 0.0
- self._rightExtraIndent = 0.0
-
- def _getAvailableWidth(self):
- return self._aW - self._leftExtraIndent - self._rightExtraIndent
-
- def _add(self, 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"""
- flowable._frame = self
- flowable.canv = canv #so they can use stringWidth etc
- try:
- if getattr(flowable,'frameAction',None):
- flowable.frameAction(self)
- return 1
-
- y = self._y
- p = self._y1p
- s = 0
- aW = self._getAvailableWidth()
- if not self._atTop:
- s =flowable.getSpaceBefore()
- if self._oASpace:
- if getattr(flowable,'_SPACETRANSFER',False):
- s = self._prevASpace
- s = max(s-self._prevASpace,0)
- h = y - p - s
- if h>0:
- w, h = flowable.wrap(aW, h)
- else:
- return 0
-
- h += s
- y -= h
-
- if y < p-_FUZZ:
- if not rl_config.allowTableBoundsErrors and ((h>self._aH or w>aW) and not trySplit):
- from reportlab.platypus.doctemplate import LayoutError
- raise LayoutError("Flowable %s (%sx%s points) too large for frame (%sx%s points)." % (
- flowable.__class__, w,h, aW,self._aH))
- return 0
- else:
- #now we can draw it, and update the current point.
- s = flowable.getSpaceAfter()
- fbg = getattr(self,'_frameBGs',None)
- if fbg:
- fbgl, fbgr, fbgc = fbg[-1]
- fbw = self._width-fbgl-fbgr
- fbh = y + h + s
- fby = max(p,y-s)
- fbh = max(0,fbh-fby)
- if abs(fbw)>_FUZZ and abs(fbh)>_FUZZ:
- canv.saveState()
- canv.setFillColor(fbgc)
- canv.rect(self._x1+fbgl,fby,fbw,fbh,stroke=0,fill=1)
- canv.restoreState()
-
- flowable.drawOn(canv, self._x + self._leftExtraIndent, y, _sW=aW-w)
- flowable.canv=canv
- if self._debug: logger.debug('drew %s' % flowable.identity())
- y -= s
- if self._oASpace:
- if getattr(flowable,'_SPACETRANSFER',False):
- s = self._prevASpace
- self._prevASpace = s
- if y!=self._y: self._atTop = 0
- self._y = y
- return 1
- finally:
- #sometimes canv/_frame aren't still on the flowable
- for a in ('canv', '_frame'):
- if hasattr(flowable,a):
- delattr(flowable,a)
-
- add = _add
-
- def split(self,flowable,canv):
- '''Ask the flowable to split using up the available space.'''
- y = self._y
- p = self._y1p
- s = 0
- if not self._atTop:
- s = flowable.getSpaceBefore()
- if self._oASpace:
- s = max(s-self._prevASpace,0)
- flowable._frame = self #some flowables might need these
- flowable.canv = canv
- try:
- r = flowable.split(self._aW, y-p-s)
- finally:
- #sometimes canv/_frame aren't still on the flowable
- for a in ('canv', '_frame'):
- if hasattr(flowable,a):
- delattr(flowable,a)
- return r
-
-
- def drawBoundary(self,canv):
- "draw the frame boundary as a rectangle (primarily for debugging)."
- from reportlab.lib.colors import Color, toColor
- sb = self.showBoundary
- ss = isinstance(sb,(str,tuple,list)) or isinstance(sb,Color)
- w = -1
- if ss:
- c = toColor(sb,self)
- ss = c is not self
- elif isinstance(sb,ShowBoundaryValue) and sb:
- c = toColor(sb.color,self)
- w = sb.width
- ss = c is not self
- if ss:
- canv.saveState()
- canv.setStrokeColor(c)
- if w>=0:
- canv.setLineWidth(w)
- canv.rect(
- self._x1,
- self._y1,
- self._x2 - self._x1,
- self._y2 - self._y1
- )
- if ss: canv.restoreState()
-
- def addFromList(self, drawlist, canv):
- """Consumes objects from the front of the list until the
- frame is full. If it cannot fit one object, raises
- an exception."""
-
- if self._debug: logger.debug("enter Frame.addFromlist() for frame %s" % self.id)
- if self.showBoundary:
- self.drawBoundary(canv)
-
- while len(drawlist) > 0:
- head = drawlist[0]
- if self.add(head,canv,trySplit=0):
- del drawlist[0]
- else:
- #leave it in the list for later
- break
-
- def add_generated_content(self,*C):
- self.__dict__.setdefault('_generated_content',[]).extend(C)
-
- def _aSpaceString(self):
- return '(%s x %s%s)' % (self._getAvailableWidth(),self._aH,self._atTop and '*' or '')
diff --git a/reportlab/platypus/para.py b/reportlab/platypus/para.py
deleted file mode 100644
index 898ff8a3..00000000
--- a/reportlab/platypus/para.py
+++ /dev/null
@@ -1,2366 +0,0 @@
-"""new experimental paragraph implementation
-
-Intended to allow support for paragraphs in paragraphs, hotlinks,
-embedded flowables, and underlining. The main entry point is the
-function
-
-def Paragraph(text, style, bulletText=None, frags=None)
-
-Which is intended to be plug compatible with the "usual" platypus
-paragraph except that it supports more functionality.
-
-In this implementation you may embed paragraphs inside paragraphs
-to create hierarchically organized documents.
-
-This implementation adds the following paragraph-like tags (which
-support the same attributes as paragraphs, for font specification, etc).
-
-- Unnumberred lists (ala html)::
-
-
- - first one
- - second one
-
-
-
-Also (default) or , .
-
-- Numberred lists (ala html)::
-
-
- - first one
- - second one
-
-
-Also (default) or , .
-
-- Display lists (ala HTML):
-
-For example
-
-
-- frogs
- Little green slimy things. Delicious with garlic
-- kittens
- cute, furry, not edible
-- bunnies
- cute, furry,. Delicious with garlic
-
-
-ALSO the following additional internal paragraph markup tags are supported
-
-underlined text
-
-hyperlinked text
-hyperlinked text
-
-Go to the end (go to document internal destination)
-Go to the beginning
-
-This is the document start
- (define document destination inside paragraph, color is optional)
-
-"""
-from reportlab.pdfbase.pdfmetrics import stringWidth
-from reportlab.lib.rl_accel import fp_str
-from reportlab.platypus.flowables import Flowable
-from reportlab.lib import colors
-from reportlab.lib.styles import _baseFontName
-
-# SET THIS TO CAUSE A VIEWING BUG WITH ACROREAD 3 (for at least one input)
-# CAUSEERROR = 0
-
-debug = 0
-
-DUMPPROGRAM = 0
-
-TOOSMALLSPACE = 1e-5
-
-from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
-
-# indent changes effect the next line
-# align changes effect the current line
-
-# need to fix spacing questions... if ends with space then space may be inserted
-
-# NEGATIVE SPACE SHOULD NEVER BE EXPANDED (IN JUSTIFICATION, EG)
-
-class paragraphEngine:
- # text origin of 0,0 is upper left corner
- def __init__(self, program = None):
- from reportlab.lib.colors import black
- if program is None:
- program = []
- self.lineOpHandlers = [] # for handling underlining and hyperlinking, etc
- self.program = program
- self.indent = self.rightIndent = 0.0
- self.baseindent = 0.0 # adjust this to add more indentation for bullets, eg
- self.fontName = "Helvetica"
- self.fontSize = 10
- self.leading = 12
- self.fontColor = black
- self.x = self.y = self.rise = 0.0
- from reportlab.lib.enums import TA_LEFT
- self.alignment = TA_LEFT
- self.textStateStack = []
-
- TEXT_STATE_VARIABLES = ("indent", "rightIndent", "fontName", "fontSize",
- "leading", "fontColor", "lineOpHandlers", "rise",
- "alignment")
- #"textStateStack")
-
- def pushTextState(self):
- state = []
- for var in self.TEXT_STATE_VARIABLES:
- val = getattr(self, var)
- state.append(val)
- #self.textStateStack.append(state)
- self.textStateStack = self.textStateStack+[state] # fresh copy
- #print "push", self.textStateStack
- #print "push", len(self.textStateStack), state
- return state
-
- def popTextState(self):
- state = self.textStateStack[-1]
- self.textStateStack = self.textStateStack[:-1]
- #print "pop", self.textStateStack
- state = state[:] # copy for destruction
- #print "pop", len(self.textStateStack), state
- #print "handlers before", self.lineOpHandlers
- for var in self.TEXT_STATE_VARIABLES:
- val = state[0]
- del state[0]
- setattr(self, var, val)
-
- def format(self, maxwidth, maxheight, program, leading=0):
- "return program with line operations added if at least one line fits"
- # note: a generated formatted segment should not be formatted again
- startstate = self.__dict__.copy()
- #remainder = self.cleanProgram(program)
- remainder = program[:]
- #program1 = remainder[:] # debug only
- lineprogram = []
- #if maxheight=self.leading and remainder:
- #print "getting line with statestack", len(self.textStateStack)
- #heightremaining = heightremaining - self.leading
- indent = self.indent
- rightIndent = self.rightIndent
- linewidth = maxwidth - indent - rightIndent
- beforelinestate = self.__dict__.copy()
- if linewidthleading:
- heightremaining = heightremaining-leading
- else:
- room = 0
- #self.resetState(beforelinestate)
- self.__dict__.update(beforelinestate)
- break # no room for this line
-## if debug:
-## print "line", line
-## if lineIsFull: print "is full"
-## else: print "is partially full"
-## print "consumes", cursor, "elements"
-## print "covers", currentLength, "of", maxwidth
- alignment = self.alignment # last declared alignment for this line used
- # recompute linewidth using the used indent
- #linewidth = maxwidth - usedIndent - rightIndent
- remainder = remainder[cursor:]
- if not remainder:
- # trim off the extra end of line
- del line[-1]
- # do justification if any
- #line = self.shrinkWrap(line
- if alignment==TA_LEFT:
- #if debug:
- # print "ALIGN LEFT"
- if justStrings:
- line = stringLine(line, currentLength)
- else:
- line = self.shrinkWrap(line)
- pass
- elif alignment==TA_CENTER:
- #if debug:
- # print "ALIGN CENTER"
- if justStrings:
- line = stringLine(line, currentLength)
- else:
- line = self.shrinkWrap(line)
- line = self.centerAlign(line, currentLength, maxLength)
- elif alignment==TA_RIGHT:
- #if debug:
- # print "ALIGN RIGHT"
- if justStrings:
- line = stringLine(line, currentLength)
- else:
- line = self.shrinkWrap(line)
- line = self.rightAlign(line, currentLength, maxLength)
- elif alignment==TA_JUSTIFY:
- #if debug:
- # print "JUSTIFY"
- if remainder and lineIsFull:
- if justStrings:
- line = simpleJustifyAlign(line, currentLength, maxLength)
- else:
- line = self.justifyAlign(line, currentLength, maxLength)
- else:
- if justStrings:
- line = stringLine(line, currentLength)
- else:
- line = self.shrinkWrap(line)
- if debug:
- print("no justify because line is not full or end of para")
- else:
- raise ValueError("bad alignment "+repr(alignment))
- if not justStrings:
- line = self.cleanProgram(line)
- lineprogram.extend(line)
- laststate = self.__dict__.copy()
- #self.resetState(startstate)
- self.__dict__.update(startstate)
- heightused = maxheight - heightremaining
- return (lineprogram, remainder, laststate, heightused)
-
- def getState(self):
- # inlined
- return self.__dict__.copy()
-
- def resetState(self, state):
- # primarily inlined
- self.__dict__.update(state)
-
-## def sizeOfWord(self, word):
-## inlineThisFunctionForEfficiency
-## return float(stringWidth(word, self.fontName, self.fontSize))
-
- def fitLine(self, program, totalLength):
- "fit words (and other things) onto a line"
- # assuming word lengths and spaces have not been yet added
- # fit words onto a line up to maxlength, adding spaces and respecting extra space
- from reportlab.pdfbase.pdfmetrics import stringWidth
- usedIndent = self.indent
- maxLength = totalLength - usedIndent - self.rightIndent
- done = 0
- line = []
- cursor = 0
- lineIsFull = 0
- currentLength = 0
- maxcursor = len(program)
- needspace = 0
- first = 1
- terminated = None
- fontName = self.fontName
- fontSize = self.fontSize
- spacewidth = stringWidth(" ", fontName, fontSize) #self.sizeOfWord(" ")
- justStrings = 1
- while not done and cursormaxLength and not first: # always do at least one thing
- # this word won't fit
- #if debug:
- # print "WORD", opcode, "wont fit, width", width, "fullwidth", fullwidth
- # print " currentLength", currentLength, "newlength", newlength, "maxLength", maxLength
- done = 1
- lineIsFull = 1
- else:
- # fit the word: add a space then the word
- if lastneedspace:
- line.append( spacewidth ) # expandable space: positive
- if opcode:
- line.append( opcode )
- if abs(width)>TOOSMALLSPACE:
- line.append( -width ) # non expanding space: negative
- currentLength = newlength
- #print line
- #stop
- first = 0
- elif isinstance(opcode,float):
- justStrings = 0
- aopcode = abs(opcode) # negative means non expanding
- if aopcode>TOOSMALLSPACE:
- nextLength = currentLength+aopcode
- if nextLength>maxLength and not first: # always do at least one thing
- #if debug: print "EXPLICIT spacer won't fit", maxLength, nextLength, opcode
- done = 1
- else:
- if aopcode>TOOSMALLSPACE:
- currentLength = nextLength
- line.append(opcode)
- first = 0
- elif isinstance(opcode,tuple):
- justStrings = 0
- indicator = opcode[0]
- #line.append(opcode)
- if indicator=="nextLine":
- # advance to nextLine
- #(i, endallmarks) = opcode
- line.append(opcode)
- cursor = cursor+1 # consume this element
- terminated = done = 1
- #if debug:
- # print "nextLine encountered"
- elif indicator=="color":
- # change fill color
- oldcolor = self.fontColor
- (i, colorname) = opcode
- #print "opcode", opcode
- if isinstance(colorname,str):
- color = self.fontColor = getattr(colors, colorname)
- else:
- color = self.fontColor = colorname # assume its something sensible :)
- line.append(opcode)
- elif indicator=="face":
- # change font face
- (i, fontname) = opcode
- fontName = self.fontName = fontname
- spacewidth = stringWidth(" ", fontName, fontSize) #self.sizeOfWord(" ")
- line.append(opcode)
- elif indicator=="size":
- # change font size
- (i, fontsize) = opcode
- size = abs(float(fontsize))
- if isinstance(fontsize,str):
- if fontsize[:1]=="+":
- fontSize = self.fontSize = self.fontSize + size
- elif fontsize[:1]=="-":
- fontSize = self.fontSize = self.fontSize - size
- else:
- fontSize = self.fontSize = size
- else:
- fontSize = self.fontSize = size
- spacewidth = stringWidth(" ", fontName, fontSize) #self.sizeOfWord(" ")
- line.append(opcode)
- elif indicator=="leading":
- # change font leading
- (i, leading) = opcode
- self.leading = leading
- line.append(opcode)
- elif indicator=="indent":
- # increase the indent
- (i, increment) = opcode
- indent = self.indent = self.indent + increment
- if first:
- usedIndent = max(indent, usedIndent)
- maxLength = totalLength - usedIndent - self.rightIndent
- line.append(opcode)
- elif indicator=="push":
- self.pushTextState()
- line.append(opcode)
- elif indicator=="pop":
- try:
- self.popTextState()
- except:
-## print "stack fault near", cursor
-## for i in program[max(0, cursor-10):cursor+10]:
-## if i==cursor:
-## print "***>>>",
-## print i
- raise
- fontName = self.fontName
- fontSize = self.fontSize
- spacewidth = stringWidth(" ", fontName, fontSize) #self.sizeOfWord(" ")
- line.append(opcode)
- elif indicator=="bullet":
- (i, bullet, indent, font, size) = opcode
- # adjust for base indent (only at format time -- only execute once)
- indent = indent + self.baseindent
- opcode = (i, bullet, indent, font, size)
- if not first:
- raise ValueError("bullet not at beginning of line")
- bulletwidth = float(stringWidth(bullet, font, size))
- spacewidth = float(stringWidth(" ", font, size))
- bulletmin = indent+spacewidth+bulletwidth
- # decrease the line size to allow bullet
- usedIndent = max(bulletmin, usedIndent)
- if first:
- maxLength = totalLength - usedIndent - self.rightIndent
- line.append(opcode)
- elif indicator=="rightIndent":
- # increase the right indent
- (i, increment) = opcode
- self.rightIndent = self.rightIndent+increment
- if first:
- maxLength = totalLength - usedIndent - self.rightIndent
- line.append(opcode)
- elif indicator=="rise":
- (i, rise) = opcode
- newrise = self.rise = self.rise+rise
- line.append(opcode)
- elif indicator=="align":
- (i, alignment) = opcode
- #if debug:
- # print "SETTING ALIGNMENT", alignment
- self.alignment = alignment
- line.append(opcode)
- elif indicator=="lineOperation":
- (i, handler) = opcode
- line.append(opcode)
- self.lineOpHandlers = self.lineOpHandlers + [handler] # fresh copy
- elif indicator=="endLineOperation":
- (i, handler) = opcode
- h = self.lineOpHandlers[:] # fresh copy
- h.remove(handler)
- self.lineOpHandlers = h
- line.append(opcode)
-
- else:
- raise ValueError("at format time don't understand indicator "+repr(indicator))
- else:
- raise ValueError("op must be string, float, instance, or tuple "+repr(opcode))
- if not done:
- cursor = cursor+1
- #first = 0
-## if debug:
-## if done:
-## print "DONE FLAG IS SET"
-## if cursor>=maxcursor:
-## print "AT END OF PROGRAM"
- if not terminated:
- line.append( ("nextLine", 0) )
- #print "fitline", line
- return (lineIsFull, line, cursor, currentLength, usedIndent, maxLength, justStrings)
-
- def centerAlign(self, line, lineLength, maxLength):
- diff = maxLength-lineLength
- shift = diff/2.0
- if shift>TOOSMALLSPACE:
- return self.insertShift(line, shift)
- return line
-
- def rightAlign(self, line, lineLength, maxLength):
- shift = maxLength-lineLength
- #die
- if shift>TOOSMALLSPACE:
- return self.insertShift(line, shift)
- return line
-
- def insertShift(self, line, shift):
- # insert shift just before first visible element in line
- result = []
- first = 1
- for e in line:
- if first and (isinstance(e,str) or hasattr(e,'width')):
- result.append(shift)
- first = 0
- result.append(e)
- return result
-
- def justifyAlign(self, line, lineLength, maxLength):
- diff = maxLength-lineLength
- # count EXPANDABLE SPACES AFTER THE FIRST VISIBLE
- spacecount = 0
- visible = 0
- for e in line:
- if isinstance(e,float) and e>TOOSMALLSPACE and visible:
- spacecount = spacecount+1
- elif first and (isinstance(e,str) or hasattr(e,'width')):
- visible = 1
- #if debug: print "diff is", diff, "wordcount", wordcount #; die
- if spacecount<1:
- return line
- shift = diff/float(spacecount)
- if shift<=TOOSMALLSPACE:
- #if debug: print "shift too small", shift
- return line
- first = 1
- visible = 0
- result = []
- cursor = 0
- nline = len(line)
- while cursorTOOSMALLSPACE and visible:
- expanded = e+shift
- result[-1] = expanded
- cursor = cursor+1
- return result
-
-## if not first:
-## #if debug: print "shifting", shift, e
-## #result.append(shift)
-## # add the shift in result before any start markers before e
-## insertplace = len(result)-1
-## done = 0
-## myshift = shift
-## while insertplace>0 and not done:
-## beforeplace = insertplace-1
-## beforething = result[beforeplace]
-## if isinstance(beforething,tuple):
-## indicator = beforething[0]
-## if indicator=="endLineOperation":
-## done = 1
-## elif debug:
-## print "adding shift before", beforething
-## elif isinstance(beforething,float):
-## myshift = myshift + beforething
-## del result[beforeplace]
-## else:
-## done = 1
-## if not done:
-## insertplace = beforeplace
-## result.insert(insertplace, myshift)
-## first = 0
-## cursor = cursor+1
-## return result
-
- def shrinkWrap(self, line):
- # for non justified text, collapse adjacent text/shift's into single operations
- result = []
- index = 0
- maxindex = len(line)
- while index0:
- thefloats = -thefloats
- if nexte<0 and thefloats>0:
- nexte = -nexte
- thefloats = thefloats + nexte
- elif isinstance(nexte,str):
- thestrings.append(nexte)
- index = index+1
- if index0:
- last = -last
- if e<0 and last>0:
- e = -e
- last = float(last)+e
- else:
- if abs(last)>TOOSMALLSPACE:
- result.append(last)
- result.append(e)
- last = 0
- if last:
- result.append(last)
- # now go backwards and delete all floats occurring after all visible elements
-## count = len(result)-1
-## done = 0
-## while count>0 and not done:
-## e = result[count]
-## if hasattr(e,'width') or isinstance(e,str):
-## done = 1
-## elif isinstance(e,float):
-## del result[count]
-## count = count-1
- # move end operations left and start operations left up to visibles
- change = 1
- rline = list(range(len(result)-1))
- while change:
- #print line
- change = 0
- for index in rline:
- nextindex = index+1
- this = result[index]
- next = result[nextindex]
- doswap = 0
- # don't swap visibles
- if isinstance(this,str) or \
- isinstance(next,str) or \
- hasattr(this,'width') or hasattr(next,'width'):
- doswap = 0
- # only swap two tuples if the second one is an end operation and the first is something else
- elif isinstance(this,tuple):
- thisindicator = this[0]
- if isinstance(next,tuple):
- nextindicator = next[0]
- doswap = 0
- if (nextindicator=="endLineOperation" and thisindicator!="endLineOperation"
- and thisindicator!="lineOperation"):
- doswap = 1 # swap nonend!=end
- elif isinstance(next,float):
- if thisindicator=="lineOperation":
- doswap = 1 # begin != space
- if doswap:
- #print "swap", line[index],line[nextindex]
- result[index] = next
- result[nextindex] = this
- change = 1
- return result
-
- def runOpCodes(self, program, canvas, textobject):
- "render the line(s)"
-
- escape = canvas._escape
- code = textobject._code
- startstate = self.__dict__.copy()
- font = None
- size = None
- # be sure to set them before using them (done lazily below)
- #textobject.setFont(self.fontName, self.fontSize)
- textobject.setFillColor(self.fontColor)
- xstart = self.x
- thislineindent = self.indent
- thislinerightIndent = self.rightIndent
- indented = 0
- for opcode in program:
- if isinstance(opcode,str) or hasattr(opcode,'width'):
- if not indented:
- if abs(thislineindent)>TOOSMALLSPACE:
- #if debug: print "INDENTING", thislineindent
- #textobject.moveCursor(thislineindent, 0)
- code.append('%s Td' % fp_str(thislineindent, 0))
- self.x = self.x + thislineindent
- for handler in self.lineOpHandlers:
- #handler.end_at(x, y, self, canvas, textobject) # finish, eg, underlining this line
- handler.start_at(self.x, self.y, self, canvas, textobject) # start underlining the next
- indented = 1
- # lazily set font (don't do it again if not needed)
- if font!=self.fontName or size!=self.fontSize:
- font = self.fontName
- size = self.fontSize
- textobject.setFont(font, size)
- if isinstance(opcode,str):
- textobject.textOut(opcode)
- else:
- # drawable thing
- opcode.execute(self, textobject, canvas)
- elif isinstance(opcode,float):
- # use abs value (ignore expandable marking)
- opcode = abs(opcode)
- if opcode>TOOSMALLSPACE:
- #textobject.moveCursor(opcode, 0)
- code.append('%s Td' % fp_str(opcode, 0))
- self.x = self.x + opcode
- elif isinstance(opcode,tuple):
- indicator = opcode[0]
- if indicator=="nextLine":
- # advance to nextLine
- (i, endallmarks) = opcode
- x = self.x
- y = self.y
- newy = self.y = self.y-self.leading
- newx = self.x = xstart
- thislineindent = self.indent
- thislinerightIndent = self.rightIndent
- indented = 0
- for handler in self.lineOpHandlers:
- handler.end_at(x, y, self, canvas, textobject) # finish, eg, underlining this line
- #handler.start_at(newx, newy, self, canvas, textobject)) # start underlining the next
- textobject.setTextOrigin(newx, newy)
- elif indicator=="color":
- # change fill color
- oldcolor = self.fontColor
- (i, colorname) = opcode
- #print "opcode", opcode
- if isinstance(colorname,str):
- color = self.fontColor = getattr(colors, colorname)
- else:
- color = self.fontColor = colorname # assume its something sensible :)
- #if debug:
- # print color.red, color.green, color.blue
- # print dir(color)
- #print "color is", color
- #from reportlab.lib.colors import green
- #if color is green: print "color is green"
- if color!=oldcolor:
- textobject.setFillColor(color)
- elif indicator=="face":
- # change font face
- (i, fontname) = opcode
- self.fontName = fontname
- #textobject.setFont(self.fontName, self.fontSize)
- elif indicator=="size":
- # change font size
- (i, fontsize) = opcode
- size = abs(float(fontsize))
- if isinstance(fontsize,str):
- if fontsize[:1]=="+":
- fontSize = self.fontSize = self.fontSize + size
- elif fontsize[:1]=="-":
- fontSize = self.fontSize = self.fontSize - size
- else:
- fontSize = self.fontSize = size
- else:
- fontSize = self.fontSize = size
- #(i, fontsize) = opcode
- self.fontSize = fontSize
- textobject.setFont(self.fontName, self.fontSize)
- elif indicator=="leading":
- # change font leading
- (i, leading) = opcode
- self.leading = leading
- elif indicator=="indent":
- # increase the indent
- (i, increment) = opcode
- indent = self.indent = self.indent + increment
- thislineindent = max(thislineindent, indent)
- elif indicator=="push":
- self.pushTextState()
- elif indicator=="pop":
- oldcolor = self.fontColor
- oldfont = self.fontName
- oldsize = self.fontSize
- self.popTextState()
- #if CAUSEERROR or oldfont!=self.fontName or oldsize!=self.fontSize:
- # textobject.setFont(self.fontName, self.fontSize)
- if oldcolor!=self.fontColor:
- textobject.setFillColor(self.fontColor)
- elif indicator=="wordSpacing":
- (i, ws) = opcode
- textobject.setWordSpace(ws)
- elif indicator=="bullet":
- (i, bullet, indent, font, size) = opcode
- if abs(self.x-xstart)>TOOSMALLSPACE:
- raise ValueError("bullet not at beginning of line")
- bulletwidth = float(stringWidth(bullet, font, size))
- spacewidth = float(stringWidth(" ", font, size))
- bulletmin = indent+spacewidth+bulletwidth
- # decrease the line size to allow bullet as needed
- if bulletmin > thislineindent:
- #if debug: print "BULLET IS BIG", bullet, bulletmin, thislineindent
- thislineindent = bulletmin
- textobject.moveCursor(indent, 0)
- textobject.setFont(font, size)
- textobject.textOut(bullet)
- textobject.moveCursor(-indent, 0)
- #textobject.textOut("M")
- textobject.setFont(self.fontName, self.fontSize)
- elif indicator=="rightIndent":
- # increase the right indent
- (i, increment) = opcode
- self.rightIndent = self.rightIndent+increment
- elif indicator=="rise":
- (i, rise) = opcode
- newrise = self.rise = self.rise+rise
- textobject.setRise(newrise)
- elif indicator=="align":
- (i, alignment) = opcode
- self.alignment = alignment
- elif indicator=="lineOperation":
- (i, handler) = opcode
- handler.start_at(self.x, self.y, self, canvas, textobject)
- #self.lineOpHandlers.append(handler)
- #if debug: print "adding", handler, self.lineOpHandlers
- self.lineOpHandlers = self.lineOpHandlers + [handler] # fresh copy!
- elif indicator=="endLineOperation":
- (i, handler) = opcode
- handler.end_at(self.x, self.y, self, canvas, textobject)
- newh = self.lineOpHandlers = self.lineOpHandlers[:] # fresh copy
- #if debug: print "removing", handler, self.lineOpHandlers
- if handler in newh:
- self.lineOpHandlers.remove(handler)
- else:
- pass
- #print "WARNING: HANDLER", handler, "NOT IN", newh
- else:
- raise ValueError("don't understand indicator "+repr(indicator))
- else:
- raise ValueError("op must be string float or tuple "+repr(opcode))
- laststate = self.__dict__.copy()
- #self.resetState(startstate)
- self.__dict__.update(startstate)
- return laststate
-
-def stringLine(line, length):
- "simple case: line with just strings and spacings which can be ignored"
-
- strings = []
- for x in line:
- if isinstance(x,str):
- strings.append(x)
- text = ' '.join(strings)
- result = [text, float(length)]
- nextlinemark = ("nextLine", 0)
- if line and line[-1]==nextlinemark:
- result.append( nextlinemark )
- return result
-
-def simpleJustifyAlign(line, currentLength, maxLength):
- "simple justification with only strings"
-
- strings = []
- for x in line[:-1]:
- if isinstance(x,str):
- strings.append(x)
- nspaces = len(strings)-1
- slack = maxLength-currentLength
- text = ' '.join(strings)
- if nspaces>0 and slack>0:
- wordspacing = slack/float(nspaces)
- result = [("wordSpacing", wordspacing), text, maxLength, ("wordSpacing", 0)]
- else:
- result = [text, currentLength, ("nextLine", 0)]
- nextlinemark = ("nextLine", 0)
- if line and line[-1]==nextlinemark:
- result.append( nextlinemark )
- return result
-
-from reportlab.lib.colors import black
-
-def readBool(text):
- if text.upper() in ("Y", "YES", "TRUE", "1"):
- return 1
- elif text.upper() in ("N", "NO", "FALSE", "0"):
- return 0
- else:
- raise ValueError("true/false attribute has illegal value '%s'" % text)
-
-def readAlignment(text):
- up = text.upper()
- if up == 'LEFT':
- return TA_LEFT
- elif up == 'RIGHT':
- return TA_RIGHT
- elif up in ['CENTER', 'CENTRE']:
- return TA_CENTER
- elif up == 'JUSTIFY':
- return TA_JUSTIFY
-
-def readLength(text):
- """Read a dimension measurement: accept "3in", "5cm",
- "72 pt" and so on."""
- text = text.strip()
- try:
- return float(text)
- except ValueError:
- text = text.lower()
- numberText, units = text[:-2],text[-2:]
- numberText = numberText.strip()
- try:
- number = float(numberText)
- except ValueError:
- raise ValueError("invalid length attribute '%s'" % text)
- try:
- multiplier = {
- 'in':72,
- 'cm':28.3464566929, #72/2.54; is this accurate?
- 'mm':2.83464566929,
- 'pt':1
- }[units]
- except KeyError:
- raise ValueError("invalid length attribute '%s'" % text)
-
- return number * multiplier
-
-def lengthSequence(s, converter=readLength):
- """from "(2, 1)" or "2,1" return [2,1], for example"""
- s = s.strip()
- if s[:1]=="(" and s[-1:]==")":
- s = s[1:-1]
- sl = s.split(',')
- sl = [s.strip() for s in sl]
- sl = [converter(s) for s in sl]
- return sl
-
-
-def readColor(text):
- """Read color names or tuples, RGB or CMYK, and return a Color object."""
- if not text:
- return None
- from reportlab.lib import colors
- from string import letters
- if text[0] in letters:
- return colors.__dict__[text]
- tup = lengthSequence(text)
-
- msg = "Color tuple must have 3 (or 4) elements for RGB (or CMYC)."
- assert 3 <= len(tup) <= 4, msg
- msg = "Color tuple must have all elements <= 1.0."
- for i in range(len(tup)):
- assert tup[i] <= 1.0, msg
-
- if len(tup) == 3:
- colClass = colors.Color
- elif len(tup) == 4:
- colClass = colors.CMYKColor
- return colClass(*tup)
-
-class StyleAttributeConverters:
- fontSize=[readLength]
- leading=[readLength]
- leftIndent=[readLength]
- rightIndent=[readLength]
- firstLineIndent=[readLength]
- alignment=[readAlignment]
- spaceBefore=[readLength]
- spaceAfter=[readLength]
- bulletFontSize=[readLength]
- bulletIndent=[readLength]
- textColor=[readColor]
- backColor=[readColor]
-
-class SimpleStyle:
- "simplified paragraph style without all the fancy stuff"
- name = "basic"
- fontName=_baseFontName
- fontSize=10
- leading=12
- leftIndent=0
- rightIndent=0
- firstLineIndent=0
- alignment=TA_LEFT
- spaceBefore=0
- spaceAfter=0
- bulletFontName=_baseFontName
- bulletFontSize=10
- bulletIndent=0
- textColor=black
- backColor=None
-
- def __init__(self, name, parent=None, **kw):
- mydict = self.__dict__
- if parent:
- for a,b in parent.__dict__.items():
- mydict[a]=b
- for a,b in kw.items():
- mydict[a] = b
-
- def addAttributes(self, dictionary):
- for key in dictionary.keys():
- value = dictionary[key]
- if value is not None:
- if hasattr(StyleAttributeConverters, key):
- converter = getattr(StyleAttributeConverters, key)[0]
- value = converter(value)
- setattr(self, key, value)
-
-
-DEFAULT_ALIASES = {
- "h1.defaultStyle": "Heading1",
- "h2.defaultStyle": "Heading2",
- "h3.defaultStyle": "Heading3",
- "h4.defaultStyle": "Heading4",
- "h5.defaultStyle": "Heading5",
- "h6.defaultStyle": "Heading6",
- "title.defaultStyle": "Title",
- "subtitle.defaultStyle": "SubTitle",
- "para.defaultStyle": "Normal",
- "pre.defaultStyle": "Code",
- "ul.defaultStyle": "UnorderedList",
- "ol.defaultStyle": "OrderedList",
- "li.defaultStyle": "Definition",
- }
-
-class FastPara(Flowable):
- "paragraph with no special features (not even a single ampersand!)"
-
- def __init__(self, style, simpletext):
- #if debug:
- # print "FAST", id(self)
- if "&" in simpletext:
- raise ValueError("no ampersands please!")
- self.style = style
- self.simpletext = simpletext
- self.lines = None
-
- def wrap(self, availableWidth, availableHeight):
- simpletext = self.simpletext
- self.availableWidth = availableWidth
- style = self.style
- text = self.simpletext
- rightIndent = style.rightIndent
- leftIndent = style.leftIndent
- leading = style.leading
- font = style.fontName
- size = style.fontSize
- firstindent = style.firstLineIndent
- #textcolor = style.textColor
- words = simpletext.split()
- lines = []
- from reportlab.pdfbase.pdfmetrics import stringWidth
- spacewidth = stringWidth(" ", font, size)
- currentline = []
- currentlength = 0
- firstmaxlength = availableWidth - rightIndent - firstindent
- maxlength = availableWidth - rightIndent - leftIndent
- if maxlengthavailableHeight:
- done = 1
- if currentlength and not done:
- lines.append( (' '.join(currentline), currentlength, len(currentline) ))
- heightused = heightused+leading
- self.lines = lines
- self.height = heightused
- remainder = self.remainder = ' '.join(words[cursor:])
- #print "lines", lines
- #print "remainder is", remainder
- else:
- remainder = None
- heightused = self.height
- lines = self.lines
- if remainder:
- result = (availableWidth, availableHeight+leading) # need to split
- else:
- result = (availableWidth, heightused)
- #if debug: print "wrap is", (availableWidth, availableHeight), result, len(lines)
- return result
-
- def split(self, availableWidth, availableHeight):
- style = self.style
- leading = style.leading
- if availableHeight1:
- # patch from doug@pennatus.com, 9 Nov 2002, no extraspace on last line
- textobject.setWordSpace((basicWidth-length)/(nwords-1.0))
- else:
- textobject.setWordSpace(0.0)
- textobject.setTextOrigin(x,y)
- textobject.textOut(text)
- y = y-leading
- c.drawText(textobject)
-
- def getSpaceBefore(self):
- #if debug:
- # print "got space before", self.spaceBefore
- return self.style.spaceBefore
-
- def getSpaceAfter(self):
- #print "got space after", self.spaceAfter
- return self.style.spaceAfter
-
-def defaultContext():
- result = {}
- from reportlab.lib.styles import getSampleStyleSheet
- styles = getSampleStyleSheet()
- for stylenamekey, stylenamevalue in DEFAULT_ALIASES.items():
- result[stylenamekey] = styles[stylenamevalue]
- return result
-
-def buildContext(stylesheet=None):
- result = {}
- from reportlab.lib.styles import getSampleStyleSheet
- if stylesheet is not None:
- # Copy styles with the same name as aliases
- for stylenamekey, stylenamevalue in DEFAULT_ALIASES.items():
- if stylenamekey in stylesheet:
- result[stylenamekey] = stylesheet[stylenamekey]
- # Then make aliases
- for stylenamekey, stylenamevalue in DEFAULT_ALIASES.items():
- if stylenamevalue in stylesheet:
- result[stylenamekey] = stylesheet[stylenamevalue]
-
- styles = getSampleStyleSheet()
- # Then, fill in defaults if they were not filled yet.
- for stylenamekey, stylenamevalue in DEFAULT_ALIASES.items():
- if stylenamekey not in result and stylenamevalue in styles:
- result[stylenamekey] = styles[stylenamevalue]
- return result
-
-class Para(Flowable):
-
- spaceBefore = 0
- spaceAfter = 0
-
- def __init__(self, style, parsedText=None, bulletText=None, state=None, context=None, baseindent=0):
- #print id(self), "para", parsedText
- self.baseindent = baseindent
- self.context = buildContext(context)
- self.parsedText = parsedText
- self.bulletText = bulletText
- self.style1 = style # make sure Flowable doesn't use this unless wanted! call it style1 NOT style
- #self.spaceBefore = self.spaceAfter = 0
- self.program = [] # program before layout
- self.formattedProgram = [] # after layout
- self.remainder = None # follow on paragraph if any
- self.state = state # initial formatting state (for completions)
- if not state:
- self.spaceBefore = style.spaceBefore
- self.spaceAfter = style.spaceAfter
- #self.spaceBefore = "invalid value"
- #if hasattr(self, "spaceBefore") and debug:
- # print "spaceBefore is", self.spaceBefore, self.parsedText
- self.bold = 0
- self.italic = 0
- self.face = style.fontName
- self.size = style.fontSize
-
- def getSpaceBefore(self):
- #if debug:
- # print "got space before", self.spaceBefore
- return self.spaceBefore
-
- def getSpaceAfter(self):
- #print "got space after", self.spaceAfter
- return self.spaceAfter
-
- def wrap(self, availableWidth, availableHeight):
- if debug:
- print("WRAPPING", id(self), availableWidth, availableHeight)
- print(" ", self.formattedProgram)
- print(" ", self.program)
- self.availableHeight = availableHeight
- self.myengine = p = paragraphEngine()
- p.baseindent = self.baseindent # for shifting bullets as needed
- parsedText = self.parsedText
- formattedProgram = self.formattedProgram
- state = self.state
- if state:
- leading = state["leading"]
- else:
- leading = self.style1.leading
- program = self.program
- self.cansplit = 1 # until proven otherwise
- if state:
- p.resetState(state)
- p.x = 0
- p.y = 0
- needatleast = state["leading"]
- else:
- needatleast = self.style1.leading
- if availableHeight<=needatleast:
- self.cansplit = 0
- #if debug:
- # print "CANNOT COMPILE, NEED AT LEAST", needatleast, 'AVAILABLE', availableHeight
- return (availableHeight+1, availableWidth) # cannot split
- if parsedText is None and program is None:
- raise ValueError("need parsedText for formatting")
- if not program:
- self.program = program = self.compileProgram(parsedText)
- if not self.formattedProgram:
- (formattedProgram, remainder, \
- laststate, heightused) = p.format(availableWidth, availableHeight, program, leading)
- self.formattedProgram = formattedProgram
- self.height = heightused
- self.laststate = laststate
- self.remainderProgram = remainder
- else:
- heightused = self.height
- remainder = None
- # too big if there is a remainder
- if remainder:
- # lie about the height: it must be split anyway
- #if debug:
- # print "I need to split", self.formattedProgram
- # print "heightused", heightused, "available", availableHeight, "remainder", len(remainder)
- height = availableHeight + 1
- #print "laststate is", laststate
- #print "saving remainder", remainder
- self.remainder = Para(self.style1, parsedText=None, bulletText=None, \
- state=laststate, context=self.context)
- self.remainder.program = remainder
- self.remainder.spaceAfter = self.spaceAfter
- self.spaceAfter = 0
- else:
- self.remainder = None # no extra
- height = heightused
- if height>availableHeight:
- height = availableHeight-0.1
- #if debug:
- # print "giving height", height, "of", availableHeight, self.parsedText
- result = (availableWidth, height)
- if debug:
- (w, h) = result
- if abs(availableHeight-h)<0.2:
- print("exact match???" + repr(availableHeight, h))
- print("wrap is", (availableWidth, availableHeight), result)
- return result
-
- def split(self, availableWidth, availableHeight):
- #if debug:
- # print "SPLITTING", id(self), availableWidth, availableHeight
- if availableHeight<=0 or not self.cansplit:
- #if debug:
- # print "cannot split", availableWidth, "too small"
- return [] # wrap failed to find a split
- self.availableHeight = availableHeight
- formattedProgram = self.formattedProgram
- #print "formattedProgram is", formattedProgram
- if formattedProgram is None:
- raise ValueError("must call wrap before split")
- elif not formattedProgram:
- # no first line in self: fail to split
- return []
- remainder = self.remainder
- if remainder:
- #print "SPLITTING"
- result= [self, remainder]
- else:
- result= [self]
- #if debug: print "split is", result
- return result
-
- def draw(self):
- p = self.myengine #paragraphEngine()
- formattedProgram = self.formattedProgram
- if formattedProgram is None:
- raise ValueError("must call wrap before draw")
- state = self.state
- laststate = self.laststate
- if state:
- p.resetState(state)
- p.x = 0
- p.y = 0
- c = self.canv
- #if debug:
- # print id(self), "page number", c.getPageNumber()
- height = self.height
- if state:
- leading = state["leading"]
- else:
- leading = self.style1.leading
- #if debug:
- # c.rect(0,0,-1, height-self.size, fill=1, stroke=1)
- c.translate(0, height-self.size)
- t = c.beginText()
- #t.setTextOrigin(0,0)
- if DUMPPROGRAM or debug:
- print("="*44, "now running program")
- for x in formattedProgram:
- print(x)
- print("-"*44)
- laststate = p.runOpCodes(formattedProgram, c, t)
- #print laststate["x"], laststate["y"]
- c.drawText(t)
-
- def compileProgram(self, parsedText, program=None):
- style = self.style1
- # standard parameters
- #program = self.program
- if program is None:
- program = []
- a = program.append
- fn = style.fontName
- # add style information if there was no initial state
- a( ("face", fn ) )
- from reportlab.lib.fonts import ps2tt
- (self.face, self.bold, self.italic) = ps2tt(fn)
- a( ("size", style.fontSize ) )
- self.size = style.fontSize
- a( ("align", style.alignment ) )
- a( ("indent", style.leftIndent ) )
- if style.firstLineIndent:
- a( ("indent", style.firstLineIndent ) ) # must be undone later
- a( ("rightIndent", style.rightIndent ) )
- a( ("leading", style.leading) )
- if style.textColor:
- a( ("color", style.textColor) )
- #a( ("nextLine", 0) ) # clear for next line
- if self.bulletText:
- self.do_bullet(self.bulletText, program)
- self.compileComponent(parsedText, program)
- # now look for a place where to insert the unindent after the first line
- if style.firstLineIndent:
- count = 0
- for x in program:
- count = count+1
- if isinstance(x,str) or hasattr(x,'width'):
- break
- program.insert( count, ("indent", -style.firstLineIndent ) ) # defaults to end if no visibles
- #print "="*8, id(self), "program is"
- #for x in program:
- # print x
-## print "="*11
-## # check pushes and pops
-## stackcount = 0
-## dump = 0
-## for x in program:
-## if dump:
-## print "dump:", x
-## if isinstance(x,tuple):
-## i = x[0]
-## if i=="push":
-## stackcount = stackcount+1
-## print " "*stackcount, "push", stackcount
-## if i=="pop":
-## stackcount = stackcount-1
-## print " "*stackcount, "pop", stackcount
-## if stackcount<0:
-## dump=1
-## print "STACK UNDERFLOW!"
-## if dump: stop
- return program
-
- def linearize(self, program = None, parsedText=None):
- #print "LINEARIZING", self
- #program = self.program = []
- if parsedText is None:
- parsedText = self.parsedText
- style = self.style1
- if program is None:
- program = []
- program.append( ("push",) )
- if style.spaceBefore:
- program.append( ("leading", style.spaceBefore+style.leading) )
- else:
- program.append( ("leading", style.leading) )
- program.append( ("nextLine", 0) )
- program = self.compileProgram(parsedText, program=program)
- program.append( ("pop",) )
- # go to old margin
- program.append( ("push",) )
- if style.spaceAfter:
- program.append( ("leading", style.spaceAfter) )
- else:
- program.append( ("leading", 0) )
- program.append( ("nextLine", 0) )
- program.append( ("pop",) )
-
- def compileComponent(self, parsedText, program):
- #program = self.program
- if isinstance(parsedText,str):
- # handle special characters here...
- # short cut
- if parsedText:
- stext = parsedText.strip()
- if not stext:
- program.append(" ") # contract whitespace to single space
- else:
- handleSpecialCharacters(self, parsedText, program)
- elif isinstance(parsedText,list):
- for e in parsedText:
- self.compileComponent(e, program)
- elif isinstance(parsedText,tuple):
- (tagname, attdict, content, extra) = parsedText
- if not attdict:
- attdict = {}
- compilername = "compile_"+tagname
- compiler = getattr(self, compilername, None)
- if compiler is not None:
- compiler(attdict, content, extra, program)
- else:
- # just pass the tag through
- if debug:
- L = [ "<" + tagname ]
- a = L.append
- if not attdict: attdict = {}
- for k, v in attdict.items():
- a(" %s=%s" % (k,v))
- if content:
- a(">")
- a(str(content))
- a("%s>" % tagname)
- else:
- a("/>")
- t = ''.join(L)
- handleSpecialCharacters(self, t, program)
- else:
- raise ValueError("don't know how to handle tag " + repr(tagname))
-
- def shiftfont(self, program, face=None, bold=None, italic=None):
- oldface = self.face
- oldbold = self.bold
- olditalic = self.italic
- oldfontinfo = (oldface, oldbold, olditalic)
- if face is None: face = oldface
- if bold is None: bold = oldbold
- if italic is None: italic = olditalic
- self.face = face
- self.bold = bold
- self.italic = italic
- from reportlab.lib.fonts import tt2ps
- font = tt2ps(face,bold,italic)
- oldfont = tt2ps(oldface,oldbold,olditalic)
- if font!=oldfont:
- program.append( ("face", font ) )
- return oldfontinfo
-
- def compile_(self, attdict, content, extra, program):
- # "anonymous" tag: just do the content
- for e in content:
- self.compileComponent(e, program)
- #compile_para = compile_ # at least for now...
-
- def compile_pageNumber(self, attdict, content, extra, program):
- program.append(PageNumberObject())
-
- def compile_b(self, attdict, content, extra, program):
- (f,b,i) = self.shiftfont(program, bold=1)
- for e in content:
- self.compileComponent(e, program)
- self.shiftfont(program, bold=b)
-
- def compile_i(self, attdict, content, extra, program):
- (f,b,i) = self.shiftfont(program, italic=1)
- for e in content:
- self.compileComponent(e, program)
- self.shiftfont(program, italic=i)
-
- def compile_u(self, attdict, content, extra, program):
- # XXXX must eventually add things like alternative colors
- #program = self.program
- program.append( ('lineOperation', UNDERLINE) )
- for e in content:
- self.compileComponent(e, program)
- program.append( ('endLineOperation', UNDERLINE) )
-
- def compile_sub(self, attdict, content, extra, program):
- size = self.size
- self.size = newsize = size * 0.7
- rise = size*0.5
- #program = self.program
- program.append( ('size', newsize) )
- self.size = size
- program.append( ('rise', -rise) )
- for e in content:
- self.compileComponent(e, program)
- program.append( ('size', size) )
- program.append( ('rise', rise) )
-
- def compile_ul(self, attdict, content, extra, program, tagname="ul"):
- # by transformation
- #print "compile", tagname, attdict
- atts = attdict.copy()
- bulletmaker = bulletMaker(tagname, atts, self.context)
- # now do each element as a separate paragraph
- for e in content:
- if isinstance(e,str):
- if e.strip():
- raise ValueError("don't expect CDATA between list elements")
- elif isinstance(e,tuple):
- (tagname, attdict1, content1, extra) = e
- if tagname!="li":
- raise ValueError("don't expect %s inside list" % repr(tagname))
- newatts = atts.copy()
- if attdict1:
- newatts.update(attdict1)
- bulletmaker.makeBullet(newatts)
- self.compile_para(newatts, content1, extra, program)
-
- def compile_ol(self, attdict, content, extra, program):
- return self.compile_ul(attdict, content, extra, program, tagname="ol")
-
- def compile_dl(self, attdict, content, extra, program):
- # by transformation
- #print "compile", tagname, attdict
- atts = attdict.copy()
- # by transformation
- #print "compile", tagname, attdict
- atts = attdict.copy()
- bulletmaker = bulletMaker("dl", atts, self.context)
- # now do each element as a separate paragraph
- contentcopy = list(content) # copy for destruction
- bullet = ""
- while contentcopy:
- e = contentcopy[0]
- del contentcopy[0]
- if isinstance(e,str):
- if e.strip():
- raise ValueError("don't expect CDATA between list elements")
- elif not contentcopy:
- break # done at ending whitespace
- else:
- continue # ignore intermediate whitespace
- elif isinstance(e,tuple):
- (tagname, attdict1, content1, extra) = e
- if tagname!="dd" and tagname!="dt":
- raise ValueError("don't expect %s here inside list, expect 'dd' or 'dt'" % \
- repr(tagname))
- if tagname=="dt":
- if bullet:
- raise ValueError("dt will not be displayed unless followed by a dd: "+repr(bullet))
- if content1:
- self.compile_para(attdict1, content1, extra, program)
- # raise ValueError, \
- # "only simple strings supported in dd content currently: "+repr(content1)
- elif tagname=="dd":
- newatts = atts.copy()
- if attdict1:
- newatts.update(attdict1)
- bulletmaker.makeBullet(newatts, bl=bullet)
- self.compile_para(newatts, content1, extra, program)
- bullet = "" # don't use this bullet again
- if bullet:
- raise ValueError("dt will not be displayed unless followed by a dd"+repr(bullet))
-
- def compile_super(self, attdict, content, extra, program):
- size = self.size
- self.size = newsize = size * 0.7
- rise = size*0.5
- #program = self.program
- program.append( ('size', newsize) )
- program.append( ('rise', rise) )
- for e in content:
- self.compileComponent(e, program)
- program.append( ('size', size) )
- self.size = size
- program.append( ('rise', -rise) )
-
- def compile_font(self, attdict, content, extra, program):
- #program = self.program
- program.append( ("push",) ) # store current data
- if "face" in attdict:
- face = attdict["face"]
- from reportlab.lib.fonts import tt2ps
- try:
- font = tt2ps(face,self.bold,self.italic)
- except:
- font = face # better work!
- program.append( ("face", font ) )
- if "color" in attdict:
- colorname = attdict["color"]
- program.append( ("color", colorname) )
- if "size" in attdict:
- #size = float(attdict["size"]) # really should convert int, cm etc here!
- size = attdict["size"]
- program.append( ("size", size) )
- for e in content:
- self.compileComponent(e, program)
- program.append( ("pop",) ) # restore as before
-
- def compile_a(self, attdict, content, extra, program):
- url = attdict["href"]
- colorname = attdict.get("color", "blue")
- #program = self.program
- Link = HotLink(url)
- program.append( ("push",) ) # store current data
- program.append( ("color", colorname) )
- program.append( ('lineOperation', Link) )
- program.append( ('lineOperation', UNDERLINE) )
- for e in content:
- self.compileComponent(e, program)
- program.append( ('endLineOperation', UNDERLINE) )
- program.append( ('endLineOperation', Link) )
- program.append( ("pop",) ) # restore as before
-
- def compile_link(self, attdict, content, extra, program):
- dest = attdict["destination"]
- colorname = attdict.get("color", None)
- #program = self.program
- Link = InternalLink(dest)
- program.append( ("push",) ) # store current data
- if colorname:
- program.append( ("color", colorname) )
- program.append( ('lineOperation', Link) )
- program.append( ('lineOperation', UNDERLINE) )
- for e in content:
- self.compileComponent(e, program)
- program.append( ('endLineOperation', UNDERLINE) )
- program.append( ('endLineOperation', Link) )
- program.append( ("pop",) ) # restore as before
-
- def compile_setLink(self, attdict, content, extra, program):
- dest = attdict["destination"]
- colorname = attdict.get("color", "blue")
- #program = self.program
- Link = DefDestination(dest)
- program.append( ("push",) ) # store current data
- if colorname:
- program.append( ("color", colorname) )
- program.append( ('lineOperation', Link) )
- if colorname:
- program.append( ('lineOperation', UNDERLINE) )
- for e in content:
- self.compileComponent(e, program)
- if colorname:
- program.append( ('endLineOperation', UNDERLINE) )
- program.append( ('endLineOperation', Link) )
- program.append( ("pop",) ) # restore as before
-
- #def compile_p(self, attdict, content, extra, program):
- # # have to be careful about base indent here!
- # not finished
-
- def compile_bullet(self, attdict, content, extra, program):
- ### eventually should allow things like images and graphics in bullets too XXXX
- if len(content)!=1 or not isinstance(content[0],str):
- raise ValueError("content for bullet must be a single string")
- text = content[0]
- self.do_bullet(text, program)
-
- def do_bullet(self, text, program):
- style = self.style1
- #program = self.program
- indent = style.bulletIndent + self.baseindent
- font = style.bulletFontName
- size = style.bulletFontSize
- program.append( ("bullet", text, indent, font, size) )
-
- def compile_tt(self, attdict, content, extra, program):
- (f,b,i) = self.shiftfont(program, face="Courier")
- for e in content:
- self.compileComponent(e, program)
- self.shiftfont(program, face=f)
-
- def compile_greek(self, attdict, content, extra, program):
- self.compile_font({"face": "symbol"}, content, extra, program)
-
- def compile_evalString(self, attdict, content, extra, program):
- program.append( EvalStringObject(attdict, content, extra, self.context) )
-
- def compile_name(self, attdict, content, extra, program):
- program.append( NameObject(attdict, content, extra, self.context) )
-
- def compile_getName(self, attdict, content, extra, program):
- program.append( GetNameObject(attdict, content, extra, self.context) )
-
- def compile_seq(self, attdict, content, extra, program):
- program.append( SeqObject(attdict, content, extra, self.context) )
-
- def compile_seqReset(self, attdict, content, extra, program):
- program.append( SeqResetObject(attdict, content, extra, self.context) )
-
- def compile_seqDefault(self, attdict, content, extra, program):
- program.append( SeqDefaultObject(attdict, content, extra, self.context) )
-
- def compile_para(self, attdict, content, extra, program, stylename = "para.defaultStyle"):
- if attdict is None:
- attdict = {}
- context = self.context
- stylename = attdict.get("style", stylename)
- style = context[stylename]
- newstyle = SimpleStyle(name="rml2pdf internal embedded style", parent=style)
- newstyle.addAttributes(attdict)
- bulletText = attdict.get("bulletText", None)
- mystyle = self.style1
- thepara = Para(newstyle, content, context=context, bulletText=bulletText)
- # possible ref loop on context, break later
- # now compile it and add it to the program
- mybaseindent = self.baseindent
- self.baseindent = thepara.baseindent = mystyle.leftIndent + self.baseindent
- thepara.linearize(program=program)
- program.append( ("nextLine", 0) )
- self.baseindent = mybaseindent
-
-class bulletMaker:
- def __init__(self, tagname, atts, context):
- self.tagname = tagname
- #print "context is", context
- style = "li.defaultStyle"
- self.style = style = atts.get("style", style)
- typ = {"ul": "disc", "ol": "1", "dl": None}[tagname]
- #print tagname, "bulletmaker type is", typ
- self.typ =typ = atts.get("type", typ)
- #print tagname, "bulletmaker type is", typ
- if "leftIndent" not in atts:
- # get the style so you can choose an indent length
- thestyle = context[style]
- from reportlab.pdfbase.pdfmetrics import stringWidth
- size = thestyle.fontSize
- indent = stringWidth("XXX", "Courier", size)
- atts["leftIndent"] = str(indent)
- self.count = 0
- self._first = 1
-
- def makeBullet(self, atts, bl=None):
- if not self._first:
- # forget space before for non-first elements
- atts["spaceBefore"] = "0"
- else:
- self._first = 0
- typ = self.typ
- tagname = self.tagname
- if bl is None:
- if tagname=="ul":
- if typ=="disc": bl = chr(109)
- elif typ=="circle": bl = chr(108)
- elif typ=="square": bl = chr(110)
- else:
- raise ValueError("unordered list type %s not implemented" % repr(typ))
- if "bulletFontName" not in atts:
- atts["bulletFontName"] = "ZapfDingbats"
- elif tagname=="ol":
- if 'value' in atts:
- self.count = int(atts['value'])
- else:
- self.count += 1
- if typ=="1": bl = str(self.count)
- elif typ=="a":
- theord = ord("a")+self.count-1
- bl = chr(theord)
- elif typ=="A":
- theord = ord("A")+self.count-1
- bl = chr(theord)
- else:
- raise ValueError("ordered bullet type %s not implemented" % repr(typ))
- else:
- raise ValueError("bad tagname "+repr(tagname))
- if "bulletText" not in atts:
- atts["bulletText"] = bl
- if "style" not in atts:
- atts["style"] = self.style
-
-class EvalStringObject:
- "this will only work if rml2pdf is present"
-
- tagname = "evalString"
-
- def __init__(self, attdict, content, extra, context):
- if not attdict:
- attdict = {}
- self.attdict = attdict
- self.content = content
- self.context = context
- self.extra = extra
-
- def getOp(self, tuple, engine):
- from rlextra.rml2pdf.rml2pdf import Controller
- #print "tuple", tuple
- op = self.op = Controller.processTuple(tuple, self.context, {})
- return op
-
- def width(self, engine):
- from reportlab.pdfbase.pdfmetrics import stringWidth
- content = self.content
- if not content:
- content = []
- tuple = (self.tagname, self.attdict, content, self.extra)
- op = self.op = self.getOp(tuple, engine)
- #print op.__class__
- #print op.pcontent
- #print self
- s = str(op)
- return stringWidth(s, engine.fontName, engine.fontSize)
-
- def execute(self, engine, textobject, canvas):
- textobject.textOut(str(self.op))
-
-class SeqObject(EvalStringObject):
-
- def getOp(self, tuple, engine):
- from reportlab.lib.sequencer import getSequencer
- globalsequencer = getSequencer()
- attr = self.attdict
- #if it has a template, use that; otherwise try for id;
- #otherwise take default sequence
- if 'template' in attr:
- templ = attr['template']
- op = self.op = templ % globalsequencer
- return op
- elif 'id' in attr:
- id = attr['id']
- else:
- id = None
- op = self.op = globalsequencer.nextf(id)
- return op
-
-class NameObject(EvalStringObject):
- tagname = "name"
- def execute(self, engine, textobject, canvas):
- pass # name doesn't produce any output
-
-class SeqDefaultObject(NameObject):
-
- def getOp(self, tuple, engine):
- from reportlab.lib.sequencer import getSequencer
- globalsequencer = getSequencer()
- attr = self.attdict
- try:
- default = attr['id']
- except KeyError:
- default = None
- globalsequencer.setDefaultCounter(default)
- self.op = ""
- return ""
-
-class SeqResetObject(NameObject):
-
- def getOp(self, tuple, engine):
- from reportlab.lib.sequencer import getSequencer
- globalsequencer = getSequencer()
- attr = self.attdict
- try:
- id = attr['id']
- except KeyError:
- id = None
- try:
- base = int(attr['base'])
- except:
- base=0
- globalsequencer.reset(id, base)
- self.op = ""
- return ""
-
-class GetNameObject(EvalStringObject):
- tagname = "getName"
-
-class PageNumberObject:
-
- def __init__(self, example="XXX"):
- self.example = example # XXX SHOULD ADD THE ABILITY TO PASS IN EXAMPLES
-
- def width(self, engine):
- from reportlab.pdfbase.pdfmetrics import stringWidth
- return stringWidth(self.example, engine.fontName, engine.fontSize)
-
- def execute(self, engine, textobject, canvas):
- n = canvas.getPageNumber()
- textobject.textOut(str(n))
-
-### this should be moved into rml2pdf
-def EmbedInRml2pdf():
- "make the para the default para implementation in rml2pdf"
- from rlextra.rml2pdf.rml2pdf import MapNode, Controller # may not need to use superclass?
- global paraMapper, theParaMapper, ulMapper
-
- class paraMapper(MapNode):
- #stylename = "para.defaultStyle"
- def translate(self, nodetuple, controller, context, overrides):
- (tagname, attdict, content, extra) = nodetuple
- stylename = tagname+".defaultStyle"
- stylename = attdict.get("style", stylename)
- style = context[stylename]
- mystyle = SimpleStyle(name="rml2pdf internal style", parent=style)
- mystyle.addAttributes(attdict)
- bulletText = attdict.get("bulletText", None)
- # can we use the fast implementation?
- result = None
- if not bulletText and len(content)==1:
- text = content[0]
- if isinstance(text,str) and "&" not in text:
- result = FastPara(mystyle, text)
- if result is None:
- result = Para(mystyle, content, context=context, bulletText=bulletText) # possible ref loop on context, break later
- return result
-
- theParaMapper = paraMapper()
-
- class ulMapper(MapNode):
- # wrap in a default para and let the para do it
- def translate(self, nodetuple, controller, context, overrides):
- thepara = ("para", {}, [nodetuple], None)
- return theParaMapper.translate(thepara, controller, context, overrides)
-
- # override rml2pdf interpreters (should be moved to rml2pdf)
- theListMapper = ulMapper()
- Controller["ul"] = theListMapper
- Controller["ol"] = theListMapper
- Controller["dl"] = theListMapper
- Controller["para"] = theParaMapper
- Controller["h1"] = theParaMapper
- Controller["h2"] = theParaMapper
- Controller["h3"] = theParaMapper
- Controller["title"] = theParaMapper
-
-def handleSpecialCharacters(engine, text, program=None):
- from reportlab.platypus.paraparser import greeks
- from string import whitespace
- standard={'lt':'<', 'gt':'>', 'amp':'&'}
- # add space prefix if space here
- if text[0:1] in whitespace:
- program.append(" ")
- #print "handling", repr(text)
- # shortcut
- if 0 and "&" not in text:
- result = []
- for x in text.split():
- result.append(x+" ")
- if result:
- last = result[-1]
- if text[-1:] not in whitespace:
- result[-1] = last.strip()
- program.extend(result)
- return program
- if program is None:
- program = []
- amptext = text.split("&")
- first = 1
- lastfrag = amptext[-1]
- for fragment in amptext:
- if not first:
- # check for special chars
- semi = fragment.find(";")
- if semi>0:
- name = fragment[:semi]
- if name[0]=='#':
- try:
- if name[1] == 'x':
- n = int(name[2:], 16)
- else:
- n = int(name[1:])
- except ValueError:
- n = -1
- if n>=0:
- fragment = chr(n).encode('utf8')+fragment[semi+1:]
- else:
- fragment = "&"+fragment
- elif name in standard:
- s = standard[name]
- if isinstance(fragment,str):
- s = s.decode('utf8')
- fragment = s+fragment[semi+1:]
- elif name in greeks:
- s = greeks[name]
- if isinstance(fragment,str):
- s = s.decode('utf8')
- fragment = s+fragment[semi+1:]
- else:
- # add back the &
- fragment = "&"+fragment
- else:
- # add back the &
- fragment = "&"+fragment
- # add white separated components of fragment followed by space
- sfragment = fragment.split()
- for w in sfragment[:-1]:
- program.append(w+" ")
- # does the last one need a space?
- if sfragment and fragment:
- # reader 3 used to go nuts if you don't special case the last frag, but it's fixed?
- if fragment[-1] in whitespace: # or fragment==lastfrag:
- program.append( sfragment[-1]+" " )
- else:
- last = sfragment[-1].strip()
- if last:
- #print "last is", repr(last)
- program.append( last )
- first = 0
- #print "HANDLED", program
- return program
-
-def Paragraph(text, style, bulletText=None, frags=None, context=None):
- """ Paragraph(text, style, bulletText=None)
- intended to be like a platypus Paragraph but better.
- """
- # if there is no & or < in text then use the fast paragraph
- if "&" not in text and "<" not in text:
- return FastPara(style, simpletext=text)
- else:
- # use the fully featured one.
- from reportlab.lib import rparsexml
- parsedpara = rparsexml.parsexmlSimple(text,entityReplacer=None)
- return Para(style, parsedText=parsedpara, bulletText=bulletText, state=None, context=context)
-
-class UnderLineHandler:
- def __init__(self, color=None):
- self.color = color
- def start_at(self, x,y, para, canvas, textobject):
- self.xStart = x
- self.yStart = y
- def end_at(self, x, y, para, canvas, textobject):
- offset = para.fontSize/8.0
- canvas.saveState()
- color = self.color
- if self.color is None:
- color = para.fontColor
- canvas.setStrokeColor(color)
- canvas.line(self.xStart, self.yStart-offset, x,y-offset)
- canvas.restoreState()
-
-UNDERLINE = UnderLineHandler()
-
-class HotLink(UnderLineHandler):
-
- def __init__(self, url):
- self.url = url
-
- def end_at(self, x, y, para, canvas, textobject):
- fontsize = para.fontSize
- rect = [self.xStart, self.yStart, x,y+fontsize]
- if debug:
- print("LINKING RECTANGLE", rect)
- #canvas.rect(self.xStart, self.yStart, x-self.xStart,y+fontsize-self.yStart, stroke=1)
- self.link(rect, canvas)
-
- def link(self, rect, canvas):
- canvas.linkURL(self.url, rect, relative=1)
-
-class InternalLink(HotLink):
-
- def link(self, rect, canvas):
- destinationname = self.url
- contents = ""
- canvas.linkRect(contents, destinationname, rect, Border="[0 0 0]")
-
-class DefDestination(HotLink):
-
- defined = 0
-
- def link(self, rect, canvas):
- destinationname = self.url
- if not self.defined:
- [x, y, x1, y1] = rect
- canvas.bookmarkHorizontal(destinationname, x, y1) # use the upper y
- self.defined = 1
-
-def splitspace(text):
- # split on spacing but include spaces at element ends
- stext = text.split()
- result = []
- for e in stext:
- result.append(e+" ")
- return result
-
-
-testparagraph = """
-This is Text.
-This is bold text.
-This is Text.
-This is italic text.
-
-
- - this is an element at 1
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-more text monospaced and back to normal
-
-
- - this is an element at 2
-
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-
-
- - this is an element at 3
-
-more text and even more text and on and on and so forth
-
-
-
- - frogs
- Little green slimy things. Delicious with garlic
- - kittens
- cute, furry, not edible
- - bunnies
- cute, furry,. Delicious with garlic
-
-
-more text and even more text and on and on and so forth
-
-
- - this is an element at 4
-more text and even more text and on and on and so forth
-
- - this is an element at4
-more text and even more text and on and on and so forth
-
-
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-
-
-
-more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-
-
-UNDERLINED more text and even more text and on and on and so forth
-more text and even more text and on and on and so forth
-
-
- - first element of the alpha list
-
-
- - first element of the square unnumberred list
-
- - second element of the unnumberred list
-
- - third element of the unnumberred list
- third element of the unnumberred list
- third element of the unnumberred list
- third element of the unnumberred list
- third element of the unnumberred list
- third element of the unnumberred list
- third element of the unnumberred list
-
-
- - fourth element of the unnumberred list
-
-
-
-
-
- - second element of the alpha list
-
- - third element of the alpha list
- third element of the unnumberred list ! --> !
- third element of the unnumberred list ∀ --> ∀
- third element of the unnumberred list ∃ --> ∃
- third element of the unnumberred list
- third element of the unnumberred list
- third element of the unnumberred list
-
-
- - fourth element of the alpha list
-
-
-
-
-
-
-"""
-
-testparagraph1 = """
-goto www.reportlab.com.
-
-
-
-Red letter. thisisareallylongword andsoisthis andthisislonger
-justified text paragraph example with a pound sign \xc2\xa3
-justified text paragraph example
-justified text paragraph example
-
-
-
-Green letter.
-centered text paragraph example
-centered text paragraph example
-centered text paragraph example
-
-
-Blue letter.
-right justified text paragraph example
-right justified text paragraph example
-right justified text paragraph example
-
-
-Yellow letter.
-left justified text paragraph example
-left justified text paragraph example
-left justified text paragraph example
-
-
-"""
-
-def test2(canv,testpara):
- #print test_program; return
- from reportlab.lib.units import inch
- from reportlab.lib.styles import ParagraphStyle
- from reportlab.lib import rparsexml
- parsedpara = rparsexml.parsexmlSimple(testpara,entityReplacer=None)
- S = ParagraphStyle("Normal", None)
- P = Para(S, parsedpara)
- (w, h) = P.wrap(5*inch, 10*inch)
- print("wrapped as", (h,w))
- canv.saveState()
- canv.translate(1*inch, 1*inch)
- canv.rect(0,0,5*inch,10*inch, fill=0, stroke=1)
- P.canv = canv
- canv.saveState()
- P.draw()
- canv.restoreState()
- canv.setStrokeColorRGB(1, 0, 0)
- #canv.translate(0, 3*inch)
- canv.rect(0,0,w,h, fill=0, stroke=1)
- canv.restoreState()
- canv.showPage()
-
-testlink = HotLink("http://www.reportlab.com")
-
-test_program = [
- ('push',),
- ('indent', 100),
- ('rightIndent', 200),
- ('bullet', 'very long bullet', 50, 'Courier', 14),
- ('align', TA_CENTER),
- ('face', _baseFontName),
- ('size', 12),
- ('leading', 14),
- ] + splitspace("This is the first segment of the first paragraph.") + [
- ('lineOperation', testlink),
- ]+splitspace("HOTLINK This is the first segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. ") + [
- ('endLineOperation', testlink),
- ('nextLine', 0),
- ('align', TA_LEFT),
- ('bullet', 'Bullet', 10, 'Courier', 8),
- ('face', _baseFontName),
- ('size', 12),
- ('leading', 14),
- ] + splitspace("This is the SECOND!!! segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. ") + [
- ('nextLine', 0),
- ('align', TA_JUSTIFY),
- ('bullet', 'Bullet not quite as long this time', 50, 'Courier', 8),
- ('face', "Helvetica-Oblique"),
- ('size', 12),
- ('leading', 14),
- ('push',),
- ('color', 'red'),
- ] + splitspace("This is the THIRD!!! segment of the first paragraph."
- ) + [
- ('lineOperation', UNDERLINE),
- ] + splitspace("This is the first segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. This is the first segment of the first paragraph. ") + [
- ('endLineOperation', UNDERLINE),
- ('rise', 5),
- "raised ", "text ",
- ('rise', -10),
- "lowered ", "text ",
- ('rise', 5),
- "normal ", "text ",
- ('pop',),
- ('indent', 100),
- ('rightIndent', 50),
- ('nextLine', 0),
- ('align', TA_RIGHT),
- ('bullet', 'O', 50, 'Courier', 14),
- ('face', "Helvetica"),
- ('size', 12),
- ('leading', 14),
- ] + splitspace("And this is the remainder of the paragraph indented further. a a a a a a a a And this is the remainder of the paragraph indented further. a a a a a a a a And this is the remainder of the paragraph indented further. a a a a a a a a And this is the remainder of the paragraph indented further. a a a a a a a a And this is the remainder of the paragraph indented further. a a a a a a a a And this is the remainder of the paragraph indented further. a a a a a a a a And this is the remainder of the paragraph indented further. a a a a a a a a ") + [
- ('pop',),
- ('nextLine', 0),]
-
-def test():
- from pprint import pprint
- #print test_program; return
- from reportlab.pdfgen import canvas
- from reportlab.lib.units import inch
- fn = "paratest0.pdf"
- c = canvas.Canvas(fn)
- test2(c,testparagraph)
- test2(c,testparagraph1)
- if 1:
- remainder = test_program + test_program + test_program
- laststate = {}
- while remainder:
- print("NEW PAGE")
- c.translate(inch, 8*inch)
- t = c.beginText()
- t.setTextOrigin(0,0)
- p = paragraphEngine()
- p.resetState(laststate)
- p.x = 0
- p.y = 0
- maxwidth = 7*inch
- maxheight = 500
- (formattedprogram, remainder, laststate, height) = p.format(maxwidth, maxheight, remainder)
- if debug:
- pprint( formattedprogram )#; return
- laststate = p.runOpCodes(formattedprogram, c, t)
- c.drawText(t)
- c.showPage()
- print("="*30, "x=", laststate["x"], "y=", laststate["y"])
- c.save()
- print(fn)
-
-if __name__=="__main__":
- test()
diff --git a/reportlab/platypus/paragraph.py b/reportlab/platypus/paragraph.py
deleted file mode 100644
index b5ad704b..00000000
--- a/reportlab/platypus/paragraph.py
+++ /dev/null
@@ -1,1957 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/paragraph.py
-__version__=''' $Id$ '''
-__doc__='''The standard paragraph implementation'''
-from string import whitespace
-from operator import truth
-from unicodedata import category
-from reportlab.pdfbase.pdfmetrics import stringWidth, getFont, getAscentDescent
-from reportlab.platypus.paraparser import ParaParser
-from reportlab.platypus.flowables import Flowable
-from reportlab.lib.colors import Color
-from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
-from reportlab.lib.geomutils import normalizeTRBL
-from reportlab.lib.textsplit import wordSplit, ALL_CANNOT_START
-from copy import deepcopy
-from reportlab.lib.abag import ABag
-from reportlab.rl_config import platypus_link_underline, decimalSymbol, _FUZZ, paraFontSizeHeightOffset
-from reportlab.lib.utils import _className, isBytes, unicodeT, bytesT, strTypes
-from reportlab.lib.rl_accel import sameFrag
-import re
-from types import MethodType
-
-#on UTF8/py33 branch, split and strip must be unicode-safe!
-#thanks to Dirk Holtwick for helpful discussions/insight
-#on this one
-_wsc = ''.join((
- u'\u0009', # HORIZONTAL TABULATION
- u'\u000A', # LINE FEED
- u'\u000B', # VERTICAL TABULATION
- u'\u000C', # FORM FEED
- u'\u000D', # CARRIAGE RETURN
- u'\u001C', # FILE SEPARATOR
- u'\u001D', # GROUP SEPARATOR
- u'\u001E', # RECORD SEPARATOR
- u'\u001F', # UNIT SEPARATOR
- u'\u0020', # SPACE
- u'\u0085', # NEXT LINE
- #u'\u00A0', # NO-BREAK SPACE
- u'\u1680', # OGHAM SPACE MARK
- u'\u2000', # EN QUAD
- u'\u2001', # EM QUAD
- u'\u2002', # EN SPACE
- u'\u2003', # EM SPACE
- u'\u2004', # THREE-PER-EM SPACE
- u'\u2005', # FOUR-PER-EM SPACE
- u'\u2006', # SIX-PER-EM SPACE
- u'\u2007', # FIGURE SPACE
- u'\u2008', # PUNCTUATION SPACE
- u'\u2009', # THIN SPACE
- u'\u200A', # HAIR SPACE
- u'\u200B', # ZERO WIDTH SPACE
- u'\u2028', # LINE SEPARATOR
- u'\u2029', # PARAGRAPH SEPARATOR
- u'\u202F', # NARROW NO-BREAK SPACE
- u'\u205F', # MEDIUM MATHEMATICAL SPACE
- u'\u3000', # IDEOGRAPHIC SPACE
- ))
-_wsc_re_split=re.compile('[%s]+'% re.escape(_wsc)).split
-_wsc_end_search=re.compile('[%s]+$'% re.escape(_wsc)).search
-
-def split(text, delim=None):
- if isBytes(text): text = text.decode('utf8')
- if delim is not None and isBytes(delim): delim = delim.decode('utf8')
- return [uword for uword in (_wsc_re_split(text) if delim is None and u'\xa0' in text else text.split(delim))]
-
-def strip(text):
- if isBytes(text): text = text.decode('utf8')
- return text.strip(_wsc)
-
-class ParaLines(ABag):
- """
- 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 FragLine(ABag):
- """
- 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.
- """
-
-def _lineClean(L):
- return ' '.join(list(filter(truth,split(strip(L)))))
-
-def 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."""
- L=list(filter(truth,list(map(_lineClean, split(text, '\n')))))
- return joiner.join(L)
-
-def setXPos(tx,dx):
- if dx>1e-6 or dx<-1e-6:
- tx.setXPos(dx)
-
-def _leftDrawParaLine( tx, offset, extraspace, words, last=0):
- setXPos(tx,offset)
- tx._textOut(' '.join(words),1)
- setXPos(tx,-offset)
- return offset
-
-def _centerDrawParaLine( tx, offset, extraspace, words, last=0):
- m = offset + 0.5 * extraspace
- setXPos(tx,m)
- tx._textOut(' '.join(words),1)
- setXPos(tx,-m)
- return m
-
-def _rightDrawParaLine( tx, offset, extraspace, words, last=0):
- m = offset + extraspace
- setXPos(tx,m)
- tx._textOut(' '.join(words),1)
- setXPos(tx,-m)
- return m
-
-def _nbspCount(w):
- if isBytes(w):
- return w.count(b'\xc2\xa0')
- else:
- return w.count(u'\xa0')
-
-def _justifyDrawParaLine( tx, offset, extraspace, words, last=0):
- setXPos(tx,offset)
- text = ' '.join(words)
- if last or extraspace<=1e-8:
- #last one, left align
- tx._textOut(text,1)
- else:
- nSpaces = len(words)+sum([_nbspCount(w) for w in words])-1
- if nSpaces:
- tx.setWordSpace(extraspace / float(nSpaces))
- tx._textOut(text,1)
- tx.setWordSpace(0)
- else:
- tx._textOut(text,1)
- setXPos(tx,-offset)
- return offset
-
-def imgVRange(h,va,fontSize):
- '''return bottom,top offsets relative to baseline(0)'''
- if va=='baseline':
- iyo = 0
- elif va in ('text-top','top'):
- iyo = fontSize-h
- elif va=='middle':
- iyo = fontSize - (1.2*fontSize+h)*0.5
- elif va in ('text-bottom','bottom'):
- iyo = fontSize - 1.2*fontSize
- elif va=='super':
- iyo = 0.5*fontSize
- elif va=='sub':
- iyo = -0.5*fontSize
- elif hasattr(va,'normalizedValue'):
- iyo = va.normalizedValue(fontSize)
- else:
- iyo = va
- return iyo,iyo+h
-
-def imgNormV(v,nv):
- if hasattr(v,'normalizedValue'):
- return v.normalizedValue(nv)
- else:
- return v
-
-def _getDotsInfo(style):
- dots = style.endDots
- if isinstance(dots,str):
- text = dots
- fontName = style.fontName
- fontSize = style.fontSize
- textColor = style.textColor
- backColor = style.backColor
- dy = 0
- else:
- text = getattr(dots,'text','.')
- fontName = getattr(dots,'fontName',style.fontName)
- fontSize = getattr(dots,'fontSize',style.fontSize)
- textColor = getattr(dots,'textColor',style.textColor)
- backColor = getattr(dots,'backColor',style.backColor)
- dy = getattr(dots,'dy',0)
- return text,fontName,fontSize,textColor,backColor,dy
-
-_56=5./6
-_16=1./6
-def _putFragLine(cur_x, tx, line, last, pKind):
- xs = tx.XtraState
- cur_y = xs.cur_y
- x0 = tx._x0
- autoLeading = xs.autoLeading
- leading = xs.leading
- cur_x += xs.leftIndent
- dal = autoLeading in ('min','max')
- if dal:
- if autoLeading=='max':
- ascent = max(_56*leading,line.ascent)
- descent = max(_16*leading,-line.descent)
- else:
- ascent = line.ascent
- descent = -line.descent
- leading = ascent+descent
- if tx._leading!=leading:
- tx.setLeading(leading)
- if dal:
- olb = tx._olb
- if olb is not None:
- xcy = olb-ascent
- if tx._oleading!=leading:
- cur_y += leading - tx._oleading
- if abs(xcy-cur_y)>1e-8:
- cur_y = xcy
- tx.setTextOrigin(x0,cur_y)
- xs.cur_y = cur_y
- tx._olb = cur_y - descent
- tx._oleading = leading
- ws = getattr(tx,'_wordSpace',0)
- nSpaces = 0
- words = line.words
- for i, f in enumerate(words):
- if hasattr(f,'cbDefn'):
- cbDefn = f.cbDefn
- kind = cbDefn.kind
- if kind=='img':
- #draw image cbDefn,cur_y,cur_x
- txfs = tx._fontsize
- if txfs is None:
- txfs = xs.style.fontSize
- w = imgNormV(cbDefn.width,None)
- h = imgNormV(cbDefn.height,txfs)
- iy0,iy1 = imgVRange(h,cbDefn.valign,txfs)
- cur_x_s = cur_x + nSpaces*ws
- tx._canvas.drawImage(cbDefn.image,cur_x_s,cur_y+iy0,w,h,mask='auto')
- cur_x += w
- cur_x_s += w
- setXPos(tx,cur_x_s-tx._x0)
- else:
- name = cbDefn.name
- if kind=='anchor':
- tx._canvas.bookmarkHorizontal(name,cur_x,cur_y+leading)
- else:
- func = getattr(tx._canvas,name,None)
- if not func:
- raise AttributeError("Missing %s callback attribute '%s'" % (kind,name))
- tx._canvas._curr_tx_info=dict(tx=tx,cur_x=cur_x,cur_y=cur_y,leading=leading,xs=tx.XtraState)
- try:
- func(tx._canvas,kind,cbDefn.label)
- finally:
- del tx._canvas._curr_tx_info
- if f is words[-1]:
- if not tx._fontname:
- tx.setFont(xs.style.fontName,xs.style.fontSize)
- tx._textOut('',1)
- else:
- cur_x_s = cur_x + nSpaces*ws
- end_x = cur_x_s
- if i > 0:
- end_x = cur_x_s - _trailingSpaceLength(words[i-1].text, tx)
- if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize):
- tx._setFont(f.fontName, f.fontSize)
- if xs.textColor!=f.textColor:
- xs.textColor = f.textColor
- tx.setFillColor(f.textColor)
- if xs.rise!=f.rise:
- xs.rise=f.rise
- tx.setRise(f.rise)
- text = f.text
- tx._textOut(text,f is words[-1]) # cheap textOut
- if not xs.underline and f.underline:
- xs.underline = 1
- xs.underline_x = cur_x_s
- xs.underlineColor = f.textColor
- elif xs.underline:
- if not f.underline:
- xs.underline = 0
- xs.underlines.append( (xs.underline_x, end_x, xs.underlineColor) )
- xs.underlineColor = None
- elif xs.textColor!=xs.underlineColor:
- xs.underlines.append( (xs.underline_x, end_x, xs.underlineColor) )
- xs.underlineColor = xs.textColor
- xs.underline_x = cur_x_s
- if not xs.strike and f.strike:
- xs.strike = 1
- xs.strike_x = cur_x_s
- xs.strikeColor = f.textColor
- elif xs.strike:
- if not f.strike:
- xs.strike = 0
- xs.strikes.append( (xs.strike_x, end_x, xs.strikeColor) )
- xs.strikeColor = None
- elif xs.textColor!=xs.strikeColor:
- xs.strikes.append( (xs.strike_x, end_x, xs.strikeColor) )
- xs.strikeColor = xs.textColor
- xs.strike_x = cur_x_s
- if f.link and not xs.link:
- if not xs.link:
- xs.link = f.link
- xs.link_x = cur_x_s
- xs.linkColor = xs.textColor
- elif xs.link:
- if not f.link:
- xs.links.append( (xs.link_x, end_x, xs.link, xs.linkColor) )
- xs.link = None
- xs.linkColor = None
- elif f.link!=xs.link or xs.textColor!=xs.linkColor:
- xs.links.append( (xs.link_x, end_x, xs.link, xs.linkColor) )
- xs.link = f.link
- xs.link_x = cur_x_s
- xs.linkColor = xs.textColor
- bg = getattr(f,'backColor',None)
- if bg and not xs.backColor:
- xs.backColor = bg
- xs.backColor_x = cur_x_s
- elif xs.backColor:
- if not bg:
- xs.backColors.append( (xs.backColor_x, end_x, xs.backColor) )
- xs.backColor = None
- elif f.backColor!=xs.backColor or xs.textColor!=xs.backColor:
- xs.backColors.append( (xs.backColor_x, end_x, xs.backColor) )
- xs.backColor = bg
- xs.backColor_x = cur_x_s
- txtlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize)
- cur_x += txtlen
- nSpaces += text.count(' ')+_nbspCount(text)
- cur_x_s = cur_x+(nSpaces-1)*ws
- if last and pKind!='right' and xs.style.endDots:
- _do_dots_frag(cur_x,cur_x_s,line.maxWidth,xs,tx)
- if xs.underline:
- xs.underlines.append( (xs.underline_x, cur_x_s, xs.underlineColor) )
- if xs.strike:
- xs.strikes.append( (xs.strike_x, cur_x_s, xs.strikeColor) )
- if xs.link:
- xs.links.append( (xs.link_x, cur_x_s, xs.link,xs.linkColor) )
- if xs.backColor:
- xs.backColors.append( (xs.backColor_x, cur_x_s, xs.backColor) )
- if tx._x0!=x0:
- setXPos(tx,x0-tx._x0)
-
-def _do_dots_frag(cur_x, cur_x_s, maxWidth, xs, tx):
- text,fontName,fontSize,textColor,backColor,dy = _getDotsInfo(xs.style)
- txtlen = tx._canvas.stringWidth(text, fontName, fontSize)
- if cur_x_s+txtlen<=maxWidth:
- if tx._fontname!=fontName or tx._fontsize!=fontSize:
- tx.setFont(fontName,fontSize)
- maxWidth += getattr(tx,'_dotsOffsetX',tx._x0)
- tx.setTextOrigin(0,xs.cur_y+dy)
- setXPos(tx,cur_x_s-cur_x)
- n = int((maxWidth-cur_x_s)/txtlen)
- setXPos(tx,maxWidth - txtlen*n)
- if xs.textColor!=textColor:
- tx.setFillColor(textColor)
- if backColor: xs.backColors.append((cur_x,maxWidth,backColor))
- tx._textOut(n*text,1)
- if dy: tx.setTextOrigin(tx._x0,xs.cur_y-dy)
-
-def _leftDrawParaLineX( tx, offset, line, last=0):
- setXPos(tx,offset)
- _putFragLine(offset, tx, line, last, 'left')
- setXPos(tx,-offset)
-
-def _centerDrawParaLineX( tx, offset, line, last=0):
- tx._dotsOffsetX = offset + tx._x0
- try:
- m = offset+0.5*line.extraSpace
- setXPos(tx,m)
- _putFragLine(m,tx, line, last,'center')
- setXPos(tx,-m)
- finally:
- del tx._dotsOffsetX
-
-def _rightDrawParaLineX( tx, offset, line, last=0):
- m = offset+line.extraSpace
- setXPos(tx,m)
- _putFragLine(m,tx, line, last, 'right')
- setXPos(tx,-m)
-
-def _justifyDrawParaLineX( tx, offset, line, last=0):
- setXPos(tx,offset)
- extraSpace = line.extraSpace
- simple = last or abs(extraSpace)<=1e-8 or line.lineBreak
- if not simple:
- nSpaces = line.wordCount+sum([_nbspCount(w.text) for w in line.words if not hasattr(w,'cbDefn')])-1
- simple = not nSpaces
- if not simple:
- tx.setWordSpace(extraSpace / float(nSpaces))
- _putFragLine(offset, tx, line, last, 'justify')
- tx.setWordSpace(0)
- else:
- _putFragLine(offset, tx, line, last, 'justify') #no space modification
- setXPos(tx,-offset)
-
-def _trailingSpaceLength(text, tx):
- ws = _wsc_end_search(text)
- return tx._canvas.stringWidth(ws.group(), tx._fontname, tx._fontsize) if ws else 0
-
-def _getFragWords(frags,maxWidth=None):
- ''' given a Parafrag list return a list of fragwords
- [[size, (f00,w00), ..., (f0n,w0n)],....,[size, (fm0,wm0), ..., (f0n,wmn)]]
- each pair f,w represents a style and some string
- each sublist represents a word
- '''
- R = []
- W = []
- n = 0
- hangingStrip = False
- for f in frags:
- text = f.text
- #del f.text # we can't do this until we sort out splitting
- # of paragraphs
- if text!='':
- if hangingStrip:
- hangingStrip = False
- text = text.lstrip()
- S = split(text)
- if S==[]: S = ['']
- if W!=[] and text[0] in whitespace:
- W.insert(0,n)
- R.append(W)
- W = []
- n = 0
-
- for w in S[:-1]:
- W.append((f,w))
- n += stringWidth(w, f.fontName, f.fontSize)
- W.insert(0,n)
- R.append(W)
- W = []
- n = 0
-
- w = S[-1]
- W.append((f,w))
- n += stringWidth(w, f.fontName, f.fontSize)
- if text and text[-1] in whitespace:
- W.insert(0,n)
- R.append(W)
- W = []
- n = 0
- elif hasattr(f,'cbDefn'):
- cb = f.cbDefn
- w = getattr(cb,'width',0)
- if w:
- if hasattr(w,'normalizedValue'):
- w._normalizer = maxWidth
- w = w.normalizedValue(maxWidth)
- if W!=[]:
- W.insert(0,n)
- R.append(W)
- W = []
- n = 0
- R.append([w,(f,'')])
- else:
- W.append((f,''))
- elif hasattr(f, 'lineBreak'):
- #pass the frag through. The line breaker will scan for it.
- if W!=[]:
- W.insert(0,n)
- R.append(W)
- W = []
- n = 0
- R.append([0,(f,'')])
- hangingStrip = True
-
- if W!=[]:
- W.insert(0,n)
- R.append(W)
-
- return R
-
-def _fragWordIter(w):
- for f, s in w[1:]:
- if hasattr(f,'cbDefn'):
- yield f, getattr(f,'width'), s
- elif s:
- if isBytes(s):
- s = s.decode('utf8') #only encoding allowed
- for c in s:
- yield f, stringWidth(c,f.fontName, f.fontSize), c
- else:
- yield f, 0, s
-
-class _SplitList(list):
- pass
-
-def _splitFragWord(w,maxWidth,maxWidths,lineno):
- '''given a frag word, w, as returned by getFragWords
- split it into frag words that fit in lines of length
- maxWidth
- maxWidths[lineno+1]
- .....
- maxWidths[lineno+n]
-
- return the new word list
- '''
- R = []
- maxlineno = len(maxWidths)-1
- W = []
- lineWidth = 0
- fragText = u''
- wordWidth = 0
- f = w[1][0]
- for g,cw,c in _fragWordIter(w):
- newLineWidth = lineWidth+cw
- tooLong = newLineWidth>maxWidth
- if g is not f or tooLong:
- f = f.clone()
- if hasattr(f,'text'):
- f.text = fragText
- W.append((f,fragText))
- if tooLong:
- W = _SplitList([wordWidth]+W)
- R.append(W)
- lineno += 1
- maxWidth = maxWidths[min(maxlineno,lineno)]
- W = []
- newLineWidth = wordWidth = cw
- fragText = u''
- f = g
- wordWidth = 0
- wordWidth += cw
- fragText += c
- lineWidth = newLineWidth
- W.append((f,fragText))
- W = _SplitList([wordWidth]+W)
- R.append(W)
- return R
-
-class _SplitText(unicodeT):
- pass
-
-def _splitWord(w,maxWidth,maxWidths,lineno,fontName,fontSize,encoding='utf8'):
- '''
- split w into words that fit in lines of length
- maxWidth
- maxWidths[lineno+1]
- .....
- maxWidths[lineno+n]
-
- then push those new words onto words
- '''
- #TODO fix this to use binary search for the split points
- R = []
- maxlineno = len(maxWidths)-1
- lineWidth = 0
- wordText = u''
- if isBytes(w):
- w = w.decode(encoding)
- for c in w:
- cw = stringWidth(c,fontName,fontSize,encoding)
- newLineWidth = lineWidth+cw
- if newLineWidth>maxWidth:
- R.append(_SplitText(wordText))
- lineno += 1
- maxWidth = maxWidths[min(maxlineno,lineno)]
- newLineWidth = cw
- wordText = u''
- wordText += c
- lineWidth = newLineWidth
- R.append(_SplitText(wordText))
- return R
-
-def _split_blParaSimple(blPara,start,stop):
- f = blPara.clone()
- for a in ('lines', 'kind', 'text'):
- if hasattr(f,a): delattr(f,a)
-
- f.words = []
- for l in blPara.lines[start:stop]:
- for w in l[1]:
- f.words.append(w)
- return [f]
-
-def _split_blParaHard(blPara,start,stop):
- f = []
- lines = blPara.lines[start:stop]
- for l in lines:
- for w in l.words:
- f.append(w)
- if l is not lines[-1]:
- i = len(f)-1
- while i>=0 and hasattr(f[i],'cbDefn') and not getattr(f[i].cbDefn,'width',0): i -= 1
- if i>=0:
- g = f[i]
- if not g.text: g.text = ' '
- elif g.text[-1]!=' ': g.text += ' '
- return f
-
-def _drawBullet(canvas, offset, cur_y, bulletText, style, rtl):
- '''draw a bullet text could be a simple string or a frag list'''
- bulletAnchor = style.bulletAnchor
- if rtl or style.bulletAnchor!='start':
- numeric = bulletAnchor=='numeric'
- if isinstance(bulletText,strTypes):
- t = bulletText
- q = numeric and decimalSymbol in t
- if q: t = t[:t.index(decimalSymbol)]
- bulletWidth = stringWidth(t, style.bulletFontName, style.bulletFontSize)
- if q: bulletWidth += 0.5 * stringWidth(decimalSymbol, style.bulletFontName, style.bulletFontSize)
- else:
- #it's a list of fragments
- bulletWidth = 0
- for f in bulletText:
- t = f.text
- q = numeric and decimalSymbol in t
- if q:
- t = t[:t.index(decimalSymbol)]
- bulletWidth += 0.5 * stringWidth(decimalSymbol, f.fontName, f.fontSize)
- bulletWidth += stringWidth(t, f.fontName, f.fontSize)
- if q:
- break
- else:
- bulletWidth = 0
- if bulletAnchor=='middle': bulletWidth *= 0.5
- cur_y += getattr(style,"bulletOffsetY",0)
- if not rtl:
- tx2 = canvas.beginText(style.bulletIndent-bulletWidth,cur_y)
- else:
- width = rtl[0]
- bulletStart = width+style.rightIndent-(style.bulletIndent+bulletWidth)
- tx2 = canvas.beginText(bulletStart, cur_y)
- tx2.setFont(style.bulletFontName, style.bulletFontSize)
- tx2.setFillColor(getattr(style,'bulletColor',style.textColor))
- if isinstance(bulletText,strTypes):
- tx2.textOut(bulletText)
- else:
- for f in bulletText:
- tx2.setFont(f.fontName, f.fontSize)
- tx2.setFillColor(f.textColor)
- tx2.textOut(f.text)
-
- canvas.drawText(tx2)
- if not rtl:
- #AR making definition lists a bit less ugly
- #bulletEnd = tx2.getX()
- bulletEnd = tx2.getX() + style.bulletFontSize * 0.6
- offset = max(offset,bulletEnd - style.leftIndent)
- return offset
-
-def _handleBulletWidth(bulletText,style,maxWidths):
- '''work out bullet width and adjust maxWidths[0] if neccessary
- '''
- if bulletText:
- if isinstance(bulletText,strTypes):
- bulletWidth = stringWidth( bulletText, style.bulletFontName, style.bulletFontSize)
- else:
- #it's a list of fragments
- bulletWidth = 0
- for f in bulletText:
- bulletWidth += stringWidth(f.text, f.fontName, f.fontSize)
- bulletLen = style.bulletIndent + bulletWidth + 0.6 * style.bulletFontSize
- if style.wordWrap=='RTL':
- indent = style.rightIndent+style.firstLineIndent
- else:
- indent = style.leftIndent+style.firstLineIndent
- if bulletLen > indent:
- #..then it overruns, and we have less space available on line 1
- maxWidths[0] -= (bulletLen - indent)
-
-def splitLines0(frags,widths):
- '''
- given a list of ParaFrags we return a list of ParaLines
-
- each ParaLine has
- 1) ExtraSpace
- 2) blankCount
- 3) [textDefns....]
- each text definition is a (ParaFrag, start, limit) triplet
- '''
- #initialise the algorithm
- lines = []
- lineNum = 0
- maxW = widths[lineNum]
- i = -1
- l = len(frags)
- lim = start = 0
- while 1:
- #find a non whitespace character
- while imaxW and line!=[]:
- cLen = cLen-w
- #this is the end of the line
- while g.text[lim]==' ':
- lim = lim - 1
- nSpaces = nSpaces-1
- break
- if j<0: j = lim
- if g[0] is f: g[2] = j #extend
- else:
- g = (f,start,j)
- line.append(g)
- if j==lim:
- i += 1
-
-def _old_do_line(tx, x1, y1, x2, y2):
- tx._canvas.line(x1, y1, x2, y2)
-
-def _do_line(tx, x1, y1, x2, y2):
- olw = tx._canvas._lineWidth
- nlw = tx._underlineProportion*tx._fontsize
- if nlw!=olw:
- tx._canvas.setLineWidth(nlw)
- tx._canvas.line(x1, y1, x2, y2)
- tx._canvas.setLineWidth(olw)
- else:
- tx._canvas.line(x1, y1, x2, y2)
-
-def _do_under_line(i, t_off, ws, tx, lm=-0.125):
- y = tx.XtraState.cur_y - i*tx.XtraState.style.leading + lm*tx.XtraState.f.fontSize
- textlen = tx._canvas.stringWidth(' '.join(tx.XtraState.lines[i][1]), tx._fontname, tx._fontsize)
- tx._do_line(t_off, y, t_off+textlen, y)
-
-_scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$')
-def _doLink(tx,link,rect):
- parts = link.split(':',1)
- scheme = len(parts)==2 and parts[0].lower() or ''
- if _scheme_re.match(scheme) and scheme!='document':
- kind=scheme.lower()=='pdf' and 'GoToR' or 'URI'
- if kind=='GoToR': link = parts[1]
- tx._canvas.linkURL(link, rect, relative=1, kind=kind)
- else:
- if link[0]=='#':
- link = link[1:]
- scheme=''
- tx._canvas.linkRect("", scheme!='document' and link or parts[1], rect, relative=1)
-
-def _do_link_line(i, t_off, ws, tx):
- xs = tx.XtraState
- leading = xs.style.leading
- y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py
- text = ' '.join(xs.lines[i][1])
- textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize)
- _doLink(tx, xs.link, (t_off, y, t_off+textlen, y+leading))
-
-def _do_post_text(tx):
- xs = tx.XtraState
- leading = xs.style.leading
- autoLeading = xs.autoLeading
- f = xs.f
- if autoLeading=='max':
- leading = max(leading,1.2*f.fontSize)
- elif autoLeading=='min':
- leading = 1.2*f.fontSize
- ff = 0.125*f.fontSize
- y0 = xs.cur_y
- y = y0 - ff
- csc = None
- for x1,x2,c in xs.underlines:
- if c!=csc:
- tx._canvas.setStrokeColor(c)
- csc = c
- tx._do_line(x1, y, x2, y)
- xs.underlines = []
- xs.underline=0
- xs.underlineColor=None
-
- ys = y0 + 2*ff
- for x1,x2,c in xs.strikes:
- if c!=csc:
- tx._canvas.setStrokeColor(c)
- csc = c
- tx._do_line(x1, ys, x2, ys)
- xs.strikes = []
- xs.strike=0
- xs.strikeColor=None
-
- yl = y0 + f.fontSize
- ydesc = yl - leading
- for x1,x2,link,c in xs.links:
- if platypus_link_underline:
- if c!=csc:
- tx._canvas.setStrokeColor(c)
- csc = c
- tx._do_line(x1, y, x2, y)
- _doLink(tx, link, (x1, ydesc, x2, yl))
- xs.links = []
- xs.link=None
- xs.linkColor=None
-
- for x1,x2,c in xs.backColors:
- tx._canvas.setFillColor(c)
- tx._canvas.rect(x1,ydesc,x2-x1,leading,stroke=0,fill=1)
-
- xs.backColors=[]
- xs.backColor=None
- xs.cur_y -= leading
-
-def textTransformFrags(frags,style):
- tt = style.textTransform
- if tt:
- tt=tt.lower()
- if tt=='lowercase':
- tt = unicodeT.lower
- elif tt=='uppercase':
- tt = unicodeT.upper
- elif tt=='capitalize':
- tt = unicodeT.title
- elif tt=='none':
- return
- else:
- raise ValueError('ParaStyle.textTransform value %r is invalid' % style.textTransform)
- n = len(frags)
- if n==1:
- #single fragment the easy case
- frags[0].text = tt(frags[0].text)
- elif tt is unicodeT.title:
- pb = True
- for f in frags:
- u = f.text
- if not u: continue
- if u.startswith(u' ') or pb:
- u = tt(u)
- else:
- i = u.find(u' ')
- if i>=0:
- u = u[:i]+tt(u[i:])
- pb = u.endswith(u' ')
- f.text = u
- else:
- for f in frags:
- u = f.text
- if not u: continue
- f.text = tt(u)
-
-class cjkU(unicodeT):
- '''simple class to hold the frag corresponding to a str'''
- def __new__(cls,value,frag,encoding):
- self = unicodeT.__new__(cls,value)
- self._frag = frag
- if hasattr(frag,'cbDefn'):
- w = getattr(frag.cbDefn,'width',0)
- self._width = w
- else:
- self._width = stringWidth(value,frag.fontName,frag.fontSize)
- return self
- frag = property(lambda self: self._frag)
- width = property(lambda self: self._width)
-
-def makeCJKParaLine(U,maxWidth,widthUsed,extraSpace,lineBreak,calcBounds):
- words = []
- CW = []
- f0 = FragLine()
- maxSize = maxAscent = minDescent = 0
- for u in U:
- f = u.frag
- fontSize = f.fontSize
- if calcBounds:
- cbDefn = getattr(f,'cbDefn',None)
- if getattr(cbDefn,'width',0):
- descent, ascent = imgVRange(imgNormV(cbDefn.height,fontSize),cbDefn.valign,fontSize)
- else:
- ascent, descent = getAscentDescent(f.fontName,fontSize)
- else:
- ascent, descent = getAscentDescent(f.fontName,fontSize)
- maxSize = max(maxSize,fontSize)
- maxAscent = max(maxAscent,ascent)
- minDescent = min(minDescent,descent)
- if not sameFrag(f0,f):
- f0=f0.clone()
- f0.text = u''.join(CW)
- words.append(f0)
- CW = []
- f0 = f
- CW.append(u)
- if CW:
- f0=f0.clone()
- f0.text = u''.join(CW)
- words.append(f0)
- return FragLine(kind=1,extraSpace=extraSpace,wordCount=1,words=words[1:],fontSize=maxSize,ascent=maxAscent,descent=minDescent,maxWidth=maxWidth,currentWidth=widthUsed,lineBreak=lineBreak)
-
-def cjkFragSplit(frags, maxWidths, calcBounds, encoding='utf8'):
- '''This attempts to be wordSplit for frags using the dumb algorithm'''
- U = [] #get a list of single glyphs with their widths etc etc
- for f in frags:
- text = f.text
- if isBytes(text):
- text = text.decode(encoding)
- if text:
- U.extend([cjkU(t,f,encoding) for t in text])
- else:
- U.append(cjkU(text,f,encoding))
- lines = []
- i = widthUsed = lineStartPos = 0
- maxWidth = maxWidths[0]
- nU = len(U)
- while imaxWidth + _FUZZ and widthUsed>0) or lineBreak
- if endLine:
- extraSpace = maxWidth - widthUsed
- if not lineBreak:
- if ord(u)<0x3000:
- # we appear to be inside a non-Asian script section.
- # (this is a very crude test but quick to compute).
- # This is likely to be quite rare so the speed of the
- # code below is hopefully not a big issue. The main
- # situation requiring this is that a document title
- # with an english product name in it got cut.
-
-
- # we count back and look for
- # - a space-like character
- # - reversion to Kanji (which would be a good split point)
- # - in the worst case, roughly half way back along the line
- limitCheck = (lineStartPos+i)>>1 #(arbitrary taste issue)
- for j in xrange(i-1,limitCheck,-1):
- uj = U[j]
- if uj and category(uj)=='Zs' or ord(uj)>=0x3000:
- k = j+1
- if k
- if u not in ALL_CANNOT_START and i>lineStartPos+1:
- #otherwise we need to push the character back
- #the i>lineStart+1 condition ensures progress
- i -= 1
- extraSpace += w
- lines.append(makeCJKParaLine(U[lineStartPos:i],maxWidth,widthUsed,extraSpace,lineBreak,calcBounds))
- try:
- maxWidth = maxWidths[len(lines)]
- except IndexError:
- maxWidth = maxWidths[-1] # use the last one
-
- lineStartPos = i
- widthUsed = 0
-
- #any characters left?
- if widthUsed > 0:
- lines.append(makeCJKParaLine(U[lineStartPos:],maxWidth,widthUsed,maxWidth-widthUsed,False,calcBounds))
-
- return ParaLines(kind=1,lines=lines)
-
-class Paragraph(Flowable):
- """ 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:
- ... - bold
- ... - italics
- ... - underline
- ... - strike through
- ... - superscript
- ... - subscript
-
-
-
-
- link text
- attributes of links
- size/fontSize=num
- name/face/fontName=name
- fg/textColor/color=color
- backcolor/backColor/bgcolor=color
- dest/destination/target/href/link=target
- anchor text
- attributes of anchors
- fontSize=num
- fontName=name
- fg/textColor/color=color
- backcolor/backColor/bgcolor=color
- href=href
-
-
-
-
- width="w%" --> fontSize*w/100 idea from Roberto Alsina
- height="h%" --> linewidth*h/100
-
- The whole may be surrounded by tags
-
- The and 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.
- """
- def __init__(self, text, style, bulletText = None, frags=None, caseSensitive=1, encoding='utf8'):
- self.caseSensitive = caseSensitive
- self.encoding = encoding
- self._setup(text, style, bulletText or getattr(style,'bulletText',None), frags, cleanBlockQuotedText)
-
-
- def __repr__(self):
- n = self.__class__.__name__
- L = [n+"("]
- keys = list(self.__dict__.keys())
- for k in keys:
- L.append('%s: %s' % (repr(k).replace("\n", " ").replace(" "," "),repr(getattr(self, k)).replace("\n", " ").replace(" "," ")))
- L.append(") #"+n)
- return '\n'.join(L)
-
- def _setup(self, text, style, bulletText, frags, cleaner):
-
- #This used to be a global parser to save overhead.
- #In the interests of thread safety it is being instantiated per paragraph.
- #On the next release, we'll replace with a cElementTree parser
-
- if frags is None:
- text = cleaner(text)
- _parser = ParaParser()
- _parser.caseSensitive = self.caseSensitive
- style, frags, bulletTextFrags = _parser.parse(text,style)
- if frags is None:
- raise ValueError("xml parser error (%s) in paragraph beginning\n'%s'"\
- % (_parser.errors[0],text[:min(30,len(text))]))
- textTransformFrags(frags,style)
- if bulletTextFrags: bulletText = bulletTextFrags
-
- #AR hack
- self.text = text
- self.frags = frags
- self.style = style
- self.bulletText = bulletText
- self.debug = 0 #turn this on to see a pretty one with all the margins etc.
-
- def wrap(self, availWidth, availHeight):
- # work out widths array for breaking
- self.width = availWidth
- style = self.style
- leftIndent = style.leftIndent
- first_line_width = availWidth - (leftIndent+style.firstLineIndent) - style.rightIndent
- later_widths = availWidth - leftIndent - style.rightIndent
- self._wrapWidths = [first_line_width, later_widths]
-
- if style.wordWrap == 'CJK':
- #use Asian text wrap algorithm to break characters
- blPara = self.breakLinesCJK(self._wrapWidths)
- else:
- blPara = self.breakLines(self._wrapWidths)
- self.blPara = blPara
- autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
- leading = style.leading
- if blPara.kind==1:
- if autoLeading not in ('','off'):
- height = 0
- if autoLeading=='max':
- for l in blPara.lines:
- height += max(l.ascent-l.descent,leading)
- elif autoLeading=='min':
- for l in blPara.lines:
- height += l.ascent - l.descent
- else:
- raise ValueError('invalid autoLeading value %r' % autoLeading)
- else:
- height = len(blPara.lines) * leading
- else:
- if autoLeading=='max':
- leading = max(leading,blPara.ascent-blPara.descent)
- elif autoLeading=='min':
- leading = blPara.ascent-blPara.descent
- height = len(blPara.lines) * leading
- self.height = height
- return self.width, height
-
- def minWidth(self):
- 'Attempt to determine a minimum sensible width'
- frags = self.frags
- nFrags= len(frags)
- if not nFrags: return 0
- if nFrags==1:
- f = frags[0]
- fS = f.fontSize
- fN = f.fontName
- words = hasattr(f,'text') and split(f.text, ' ') or f.words
- func = lambda w, fS=fS, fN=fN: stringWidth(w,fN,fS)
- else:
- words = _getFragWords(frags)
- func = lambda x: x[0]
- return max(list(map(func,words)))
-
- def _get_split_blParaFunc(self):
- return self.blPara.kind==0 and _split_blParaSimple or _split_blParaHard
-
- def split(self,availWidth, availHeight):
- if len(self.frags)<=0: return []
-
- #the split information is all inside self.blPara
- if not hasattr(self,'blPara'):
- self.wrap(availWidth,availHeight)
- blPara = self.blPara
- style = self.style
- autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
- leading = style.leading
- lines = blPara.lines
- if blPara.kind==1 and autoLeading not in ('','off'):
- s = height = 0
- if autoLeading=='max':
- for i,l in enumerate(blPara.lines):
- h = max(l.ascent-l.descent,leading)
- n = height+h
- if n>availHeight+1e-8:
- break
- height = n
- s = i+1
- elif autoLeading=='min':
- for i,l in enumerate(blPara.lines):
- n = height+l.ascent-l.descent
- if n>availHeight+1e-8:
- break
- height = n
- s = i+1
- else:
- raise ValueError('invalid autoLeading value %r' % autoLeading)
- else:
- l = leading
- if autoLeading=='max':
- l = max(leading,1.2*style.fontSize)
- elif autoLeading=='min':
- l = 1.2*style.fontSize
- s = int(availHeight/(l*1.0))
- height = s*l
-
- allowOrphans = getattr(self,'allowOrphans',getattr(style,'allowOrphans',0))
- if (not allowOrphans and s<=1) or s==0: #orphan or not enough room
- del self.blPara
- return []
- n = len(lines)
- allowWidows = getattr(self,'allowWidows',getattr(style,'allowWidows',1))
- if n<=s:
- return [self]
- if not allowWidows:
- if n==s+1: #widow?
- if (allowOrphans and n==3) or n>3:
- s -= 1 #give the widow some company
- else:
- del self.blPara #no room for adjustment; force the whole para onwards
- return []
- func = self._get_split_blParaFunc()
-
- if style.endDots:
- style1 = deepcopy(style)
- style1.endDots = None
- else:
- style1 = style
- P1=self.__class__(None,style1,bulletText=self.bulletText,frags=func(blPara,0,s))
- #this is a major hack
- P1.blPara = ParaLines(kind=1,lines=blPara.lines[0:s],aH=availHeight,aW=availWidth)
- P1._JustifyLast = 1
- P1._splitpara = 1
- P1.height = height
- P1.width = availWidth
- if style.firstLineIndent != 0:
- style = deepcopy(style)
- style.firstLineIndent = 0
- P2=self.__class__(None,style,bulletText=None,frags=func(blPara,s,n))
- #propagate attributes that might be on self; suggestion from Dirk Holtwick
- for a in ('autoLeading', #possible attributes that might be directly on self.
- ):
- if hasattr(self,a):
- setattr(P1,a,getattr(self,a))
- setattr(P2,a,getattr(self,a))
- return [P1,P2]
-
- def draw(self):
- #call another method for historical reasons. Besides, I
- #suspect I will be playing with alternate drawing routines
- #so not doing it here makes it easier to switch.
- self.drawPara(self.debug)
-
- def breakLines(self, width):
- """
- Returns a broken line structure. There are two cases
-
- A) 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
-
- B) 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
-
- 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."""
-
- if not isinstance(width,(tuple,list)): maxWidths = [width]
- else: maxWidths = width
- lines = []
- self.height = lineno = 0
- maxlineno = len(maxWidths)-1
- style = self.style
- splitLongWords = style.splitLongWords
-
- #for bullets, work out width and ensure we wrap the right amount onto line one
- _handleBulletWidth(self.bulletText,style,maxWidths)
-
- maxWidth = maxWidths[0]
-
- autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
- calcBounds = autoLeading not in ('','off')
- frags = self.frags
- nFrags= len(frags)
- if nFrags==1 and not (style.endDots or hasattr(frags[0],'cbDefn') or hasattr(frags[0],'backColor')):
- f = frags[0]
- fontSize = f.fontSize
- fontName = f.fontName
- ascent, descent = getAscentDescent(fontName,fontSize)
- if hasattr(f,'text'):
- text = strip(f.text)
- if not text:
- return f.clone(kind=0, lines=[],ascent=ascent,descent=descent,fontSize=fontSize)
- else:
- words = split(text)
- else:
- words = f.words[:]
- for w in words:
- if strip(w): break
- else:
- return f.clone(kind=0, lines=[],ascent=ascent,descent=descent,fontSize=fontSize)
- spaceWidth = stringWidth(' ', fontName, fontSize, self.encoding)
- cLine = []
- currentWidth = -spaceWidth # hack to get around extra space for word 1
- while words:
- word = words.pop(0)
- #this underscores my feeling that Unicode throughout would be easier!
- wordWidth = stringWidth(word, fontName, fontSize, self.encoding)
- newWidth = currentWidth + spaceWidth + wordWidth
- if newWidth>maxWidth:
- nmw = min(lineno,maxlineno)
- if wordWidth>max(maxWidths[nmw:nmw+1]) and not isinstance(word,_SplitText) and splitLongWords:
- #a long word
- words[0:0] = _splitWord(word,maxWidth-spaceWidth-currentWidth,maxWidths,lineno,fontName,fontSize,self.encoding)
- continue
- if newWidth <= maxWidth or not len(cLine):
- # fit one more on this line
- cLine.append(word)
- currentWidth = newWidth
- else:
- if currentWidth > self.width: self.width = currentWidth
- #end of line
- lines.append((maxWidth - currentWidth, cLine))
- cLine = [word]
- currentWidth = wordWidth
- lineno += 1
- maxWidth = maxWidths[min(maxlineno,lineno)]
-
- #deal with any leftovers on the final line
- if cLine!=[]:
- if currentWidth>self.width: self.width = currentWidth
- lines.append((maxWidth - currentWidth, cLine))
-
- return f.clone(kind=0, lines=lines,ascent=ascent,descent=descent,fontSize=fontSize)
- elif nFrags<=0:
- return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName,
- textColor=style.textColor, ascent=style.fontSize,descent=-0.2*style.fontSize,
- lines=[])
- else:
- if hasattr(self,'blPara') and getattr(self,'_splitpara',0):
- #NB this is an utter hack that awaits the proper information
- #preserving splitting algorithm
- return self.blPara
- n = 0
- words = []
- _words = _getFragWords(frags,maxWidth)
- while _words:
- w = _words.pop(0)
- f=w[-1][0]
- fontName = f.fontName
- fontSize = f.fontSize
- spaceWidth = stringWidth(' ',fontName, fontSize)
-
- if not words:
- currentWidth = -spaceWidth # hack to get around extra space for word 1
- maxSize = fontSize
- maxAscent, minDescent = getAscentDescent(fontName,fontSize)
-
- wordWidth = w[0]
- f = w[1][0]
- if wordWidth>0:
- newWidth = currentWidth + spaceWidth + wordWidth
- else:
- newWidth = currentWidth
-
- #test to see if this frag is a line break. If it is we will only act on it
- #if the current width is non-negative or the previous thing was a deliberate lineBreak
- lineBreak = hasattr(f,'lineBreak')
- if not lineBreak and newWidth>maxWidth and not isinstance(w,_SplitList) and splitLongWords:
- nmw = min(lineno,maxlineno)
- if wordWidth>max(maxWidths[nmw:nmw+1]):
- #a long word
- _words[0:0] = _splitFragWord(w,maxWidth-spaceWidth-currentWidth,maxWidths,lineno)
- continue
- endLine = (newWidth>maxWidth and n>0) or lineBreak
- if not endLine:
- if lineBreak: continue #throw it away
- nText = w[1][1]
- if nText: n += 1
- fontSize = f.fontSize
- if calcBounds:
- cbDefn = getattr(f,'cbDefn',None)
- if getattr(cbDefn,'width',0):
- descent,ascent = imgVRange(imgNormV(cbDefn.height,fontSize),cbDefn.valign,fontSize)
- else:
- ascent, descent = getAscentDescent(f.fontName,fontSize)
- else:
- ascent, descent = getAscentDescent(f.fontName,fontSize)
- maxSize = max(maxSize,fontSize)
- maxAscent = max(maxAscent,ascent)
- minDescent = min(minDescent,descent)
- if not words:
- g = f.clone()
- words = [g]
- g.text = nText
- elif not sameFrag(g,f):
- if currentWidth>0 and ((nText!='' and nText[0]!=' ') or hasattr(f,'cbDefn')):
- if hasattr(g,'cbDefn'):
- i = len(words)-1
- while i>=0:
- wi = words[i]
- cbDefn = getattr(wi,'cbDefn',None)
- if cbDefn:
- if not getattr(cbDefn,'width',0):
- i -= 1
- continue
- if not wi.text.endswith(' '):
- wi.text += ' '
- break
- else:
- if not g.text.endswith(' '):
- g.text += ' '
- g = f.clone()
- words.append(g)
- g.text = nText
- else:
- if nText and nText[0]!=' ':
- g.text += ' ' + nText
-
- ni = 0
- for i in w[2:]:
- g = i[0].clone()
- g.text=i[1]
- if g.text: ni = 1
- words.append(g)
- fontSize = g.fontSize
- if calcBounds:
- cbDefn = getattr(g,'cbDefn',None)
- if getattr(cbDefn,'width',0):
- descent,ascent = imgVRange(imgNormV(cbDefn.height,fontSize),cbDefn.valign,fontSize)
- else:
- ascent, descent = getAscentDescent(g.fontName,fontSize)
- else:
- ascent, descent = getAscentDescent(g.fontName,fontSize)
- maxSize = max(maxSize,fontSize)
- maxAscent = max(maxAscent,ascent)
- minDescent = min(minDescent,descent)
- if not nText and ni:
- #one bit at least of the word was real
- n+=1
-
- currentWidth = newWidth
- else: #either it won't fit, or it's a lineBreak tag
- if lineBreak:
- g = f.clone()
- #del g.lineBreak
- words.append(g)
-
- if currentWidth>self.width: self.width = currentWidth
- #end of line
- lines.append(FragLine(extraSpace=maxWidth-currentWidth, wordCount=n,
- lineBreak=lineBreak, words=words, fontSize=maxSize, ascent=maxAscent, descent=minDescent, maxWidth=maxWidth))
-
- #start new line
- lineno += 1
- maxWidth = maxWidths[min(maxlineno,lineno)]
-
- if lineBreak:
- n = 0
- words = []
- continue
-
- currentWidth = wordWidth
- n = 1
- g = f.clone()
- maxSize = g.fontSize
- if calcBounds:
- cbDefn = getattr(g,'cbDefn',None)
- if getattr(cbDefn,'width',0):
- minDescent,maxAscent = imgVRange(imgNormV(cbDefn.height,fontSize),cbDefn.valign,maxSize)
- else:
- maxAscent, minDescent = getAscentDescent(g.fontName,maxSize)
- else:
- maxAscent, minDescent = getAscentDescent(g.fontName,maxSize)
- words = [g]
- g.text = w[1][1]
-
- for i in w[2:]:
- g = i[0].clone()
- g.text=i[1]
- words.append(g)
- fontSize = g.fontSize
- if calcBounds:
- cbDefn = getattr(g,'cbDefn',None)
- if getattr(cbDefn,'width',0):
- descent,ascent = imgVRange(imgNormV(cbDefn.height,fontSize),cbDefn.valign,fontSize)
- else:
- ascent, descent = getAscentDescent(g.fontName,fontSize)
- else:
- ascent, descent = getAscentDescent(g.fontName,fontSize)
- maxSize = max(maxSize,fontSize)
- maxAscent = max(maxAscent,ascent)
- minDescent = min(minDescent,descent)
-
- #deal with any leftovers on the final line
- if words!=[]:
- if currentWidth>self.width: self.width = currentWidth
- lines.append(ParaLines(extraSpace=(maxWidth - currentWidth),wordCount=n,
- words=words, fontSize=maxSize,ascent=maxAscent,descent=minDescent,maxWidth=maxWidth))
- return ParaLines(kind=1, lines=lines)
-
- return lines
-
- def breakLinesCJK(self, maxWidths):
- """Initially, the dumbest possible wrapping algorithm.
- Cannot handle font variations."""
-
- if not isinstance(maxWidths,(list,tuple)): maxWidths = [maxWidths]
- style = self.style
- self.height = 0
-
- #for bullets, work out width and ensure we wrap the right amount onto line one
- _handleBulletWidth(self.bulletText, style, maxWidths)
- frags = self.frags
- nFrags = len(frags)
- if nFrags==1 and not hasattr(frags[0],'cbDefn') and not style.endDots:
- f = frags[0]
- if hasattr(self,'blPara') and getattr(self,'_splitpara',0):
- return f.clone(kind=0, lines=self.blPara.lines)
- #single frag case
- lines = []
- lineno = 0
- if hasattr(f,'text'):
- text = f.text
- else:
- text = ''.join(getattr(f,'words',[]))
-
- from reportlab.lib.textsplit import wordSplit
- lines = wordSplit(text, maxWidths, f.fontName, f.fontSize)
- #the paragraph drawing routine assumes multiple frags per line, so we need an
- #extra list like this
- # [space, [text]]
- #
- wrappedLines = [(sp, [line]) for (sp, line) in lines]
- return f.clone(kind=0, lines=wrappedLines, ascent=f.fontSize, descent=-0.2*f.fontSize)
- elif nFrags<=0:
- return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName,
- textColor=style.textColor, lines=[],ascent=style.fontSize,descent=-0.2*style.fontSize)
-
- #general case nFrags>1 or special
- if hasattr(self,'blPara') and getattr(self,'_splitpara',0):
- return self.blPara
- autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
- calcBounds = autoLeading not in ('','off')
- return cjkFragSplit(frags, maxWidths, calcBounds)
-
- def beginText(self, x, y):
- return self.canv.beginText(x, y)
-
- def drawPara(self,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."""
-
- #stash the key facts locally for speed
- canvas = self.canv
- style = self.style
- blPara = self.blPara
- lines = blPara.lines
- leading = style.leading
- autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
-
- #work out the origin for line 1
- leftIndent = style.leftIndent
- cur_x = leftIndent
-
- if debug:
- bw = 0.5
- bc = Color(1,1,0)
- bg = Color(0.9,0.9,0.9)
- else:
- bw = getattr(style,'borderWidth',None)
- bc = getattr(style,'borderColor',None)
- bg = style.backColor
-
- #if has a background or border, draw it
- if bg or (bc and bw):
- canvas.saveState()
- op = canvas.rect
- kwds = dict(fill=0,stroke=0)
- if bc and bw:
- canvas.setStrokeColor(bc)
- canvas.setLineWidth(bw)
- kwds['stroke'] = 1
- br = getattr(style,'borderRadius',0)
- if br and not debug:
- op = canvas.roundRect
- kwds['radius'] = br
- if bg:
- canvas.setFillColor(bg)
- kwds['fill'] = 1
- bp = getattr(style,'borderPadding',0)
- tbp, rbp, bbp, lbp = normalizeTRBL(bp)
- op(leftIndent - lbp,
- -bbp,
- self.width - (leftIndent+style.rightIndent) + lbp+rbp,
- self.height + tbp+bbp,
- **kwds)
- canvas.restoreState()
-
- nLines = len(lines)
- bulletText = self.bulletText
- if nLines > 0:
- _offsets = getattr(self,'_offsets',[0])
- _offsets += (nLines-len(_offsets))*[_offsets[-1]]
- canvas.saveState()
- #canvas.addLiteral('%% %s.drawPara' % _className(self))
- alignment = style.alignment
- offset = style.firstLineIndent+_offsets[0]
- lim = nLines-1
- noJustifyLast = not (hasattr(self,'_JustifyLast') and self._JustifyLast)
-
- if blPara.kind==0:
- if alignment == TA_LEFT:
- dpl = _leftDrawParaLine
- elif alignment == TA_CENTER:
- dpl = _centerDrawParaLine
- elif self.style.alignment == TA_RIGHT:
- dpl = _rightDrawParaLine
- elif self.style.alignment == TA_JUSTIFY:
- dpl = _justifyDrawParaLine
- f = blPara
- if paraFontSizeHeightOffset:
- cur_y = self.height - f.fontSize
- else:
- cur_y = self.height - getattr(f,'ascent',f.fontSize)
- if bulletText:
- offset = _drawBullet(canvas,offset,cur_y,bulletText,style,rtl=style.wordWrap=='RTL' and self._wrapWidths or False)
-
- #set up the font etc.
- canvas.setFillColor(f.textColor)
-
- tx = self.beginText(cur_x, cur_y)
- if style.underlineProportion:
- tx._underlineProportion = style.underlineProportion
- tx._do_line = _do_line
- else:
- tx._do_line = _old_do_line
- tx._do_line = MethodType(tx._do_line,tx)
- if autoLeading=='max':
- leading = max(leading,blPara.ascent-blPara.descent)
- elif autoLeading=='min':
- leading = blPara.ascent-blPara.descent
-
- # set the paragraph direction
- tx.direction = self.style.wordWrap
-
- #now the font for the rest of the paragraph
- tx.setFont(f.fontName, f.fontSize, leading)
- ws = lines[0][0]
- t_off = dpl( tx, offset, ws, lines[0][1], noJustifyLast and nLines==1)
- if f.underline or f.link or f.strike or style.endDots:
- xs = tx.XtraState = ABag()
- xs.cur_y = cur_y
- xs.f = f
- xs.style = style
- xs.lines = lines
- xs.underlines=[]
- xs.underlineColor=None
- xs.strikes=[]
- xs.strikeColor=None
- xs.links=[]
- xs.link=f.link
- xs.textColor = f.textColor
- xs.backColors = []
- canvas.setStrokeColor(f.textColor)
- dx = t_off+leftIndent
- if dpl!=_justifyDrawParaLine: ws = 0
- underline = f.underline or (f.link and platypus_link_underline)
- strike = f.strike
- link = f.link
- if underline: _do_under_line(0, dx, ws, tx)
- if strike: _do_under_line(0, dx, ws, tx, lm=0.125)
- if link: _do_link_line(0, dx, ws, tx)
- if noJustifyLast and nLines==1 and style.endDots and dpl!=_rightDrawParaLine: _do_dots(0, dx, ws, xs, tx, dpl)
-
- #now the middle of the paragraph, aligned with the left margin which is our origin.
- for i in xrange(1, nLines):
- ws = lines[i][0]
- t_off = dpl( tx, _offsets[i], ws, lines[i][1], noJustifyLast and i==lim)
- dx = t_off+leftIndent
- if dpl!=_justifyDrawParaLine: ws = 0
- if underline: _do_under_line(i, dx, ws, tx)
- if strike: _do_under_line(i, dx, ws, tx, lm=0.125)
- if link: _do_link_line(i, dx, ws, tx)
- if noJustifyLast and i==lim and style.endDots and dpl!=_rightDrawParaLine: _do_dots(i, dx, ws, xs, tx, dpl)
- else:
- for i in xrange(1, nLines):
- dpl( tx, _offsets[i], lines[i][0], lines[i][1], noJustifyLast and i==lim)
- else:
- if self.style.wordWrap == 'RTL':
- for line in lines:
- line.words = line.words[::-1]
- f = lines[0]
- if paraFontSizeHeightOffset:
- cur_y = self.height - f.fontSize
- else:
- cur_y = self.height - getattr(f,'ascent',f.fontSize)
- # default?
- dpl = _leftDrawParaLineX
- if bulletText:
- oo = offset
- offset = _drawBullet(canvas,offset,cur_y,bulletText,style, rtl=style.wordWrap=='RTL' and self._wrapWidths or False)
- if alignment == TA_LEFT:
- dpl = _leftDrawParaLineX
- elif alignment == TA_CENTER:
- dpl = _centerDrawParaLineX
- elif self.style.alignment == TA_RIGHT:
- dpl = _rightDrawParaLineX
- elif self.style.alignment == TA_JUSTIFY:
- dpl = _justifyDrawParaLineX
- else:
- raise ValueError("bad align %s" % repr(alignment))
-
- #set up the font etc.
- tx = self.beginText(cur_x, cur_y)
- if style.underlineProportion:
- tx._underlineProportion = style.underlineProportion
- tx._do_line = _do_line
- else:
- tx._do_line = _old_do_line
- tx._do_line = MethodType(tx._do_line,tx)
- # set the paragraph direction
- tx.direction = self.style.wordWrap
-
- xs = tx.XtraState=ABag()
- xs.textColor=None
- xs.backColor=None
- xs.rise=0
- xs.underline=0
- xs.underlines=[]
- xs.underlineColor=None
- xs.strike=0
- xs.strikes=[]
- xs.strikeColor=None
- xs.backColors=[]
- xs.links=[]
- xs.link=None
- xs.leading = style.leading
- xs.leftIndent = leftIndent
- tx._leading = None
- tx._olb = None
- xs.cur_y = cur_y
- xs.f = f
- xs.style = style
- xs.autoLeading = autoLeading
-
- tx._fontname,tx._fontsize = None, None
- dpl( tx, offset, lines[0], noJustifyLast and nLines==1)
- _do_post_text(tx)
-
- #now the middle of the paragraph, aligned with the left margin which is our origin.
- for i in xrange(1, nLines):
- f = lines[i]
- dpl( tx, _offsets[i], f, noJustifyLast and i==lim)
- _do_post_text(tx)
-
- canvas.drawText(tx)
- canvas.restoreState()
-
- def getPlainText(self,identify=None):
- """Convenience function for templates which want access
- to the raw text, without XML tags. """
- frags = getattr(self,'frags',None)
- if frags:
- plains = []
- for frag in frags:
- if hasattr(frag, 'text'):
- plains.append(frag.text)
- return ''.join(plains)
- elif identify:
- text = getattr(self,'text',None)
- if text is None: text = repr(self)
- return text
- else:
- return ''
-
- def getActualLineWidths0(self):
- """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."""
- assert hasattr(self, 'width'), "Cannot call this method before wrap()"
- if self.blPara.kind:
- func = lambda frag, w=self.width: w - frag.extraSpace
- else:
- func = lambda frag, w=self.width: w - frag[0]
- return list(map(func,self.blPara.lines))
-
-if __name__=='__main__': #NORUNTESTS
- def dumpParagraphLines(P):
- print('dumpParagraphLines()' % id(P))
- lines = P.blPara.lines
- outw = sys.stdout.write
- for l,line in enumerate(lines):
- line = lines[l]
- if hasattr(line,'words'):
- words = line.words
- else:
- words = line[1]
- nwords = len(words)
- outw('line%d: %d(%s)\n ' % (l,nwords,str(getattr(line,'wordCount','Unknown'))))
- for w in xrange(nwords):
- outw(" %d:'%s'"%(w,getattr(words[w],'text',words[w])))
- print()
-
- def fragDump(w):
- R= ["'%s'" % w[1]]
- for a in ('fontName', 'fontSize', 'textColor', 'rise', 'underline', 'strike', 'link', 'cbDefn','lineBreak'):
- if hasattr(w[0],a):
- R.append('%s=%r' % (a,getattr(w[0],a)))
- return ', '.join(R)
-
- def dumpParagraphFrags(P):
- print('dumpParagraphFrags() minWidth() = %.2f' % (id(P), P.minWidth()))
- frags = P.frags
- n =len(frags)
- for l in xrange(n):
- print("frag%d: '%s' %s" % (l, frags[l].text,' '.join(['%s=%s' % (k,getattr(frags[l],k)) for k in frags[l].__dict__ if k!=text])))
-
- outw = sys.stdout.write
- l = 0
- cum = 0
- for W in _getFragWords(frags,360):
- cum += W[0]
- outw("fragword%d: cum=%3d size=%d" % (l, cum, W[0]))
- for w in W[1:]:
- outw(' (%s)' % fragDump(w))
- print()
- l += 1
-
-
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
- from reportlab.lib.units import cm
- import sys
- TESTS = sys.argv[1:]
- if TESTS==[]: TESTS=['4']
- def flagged(i,TESTS=TESTS):
- return 'all' in TESTS or '*' in TESTS or str(i) in TESTS
-
- styleSheet = getSampleStyleSheet()
- B = styleSheet['BodyText']
- style = ParagraphStyle("discussiontext", parent=B)
- style.fontName= 'Helvetica'
- if flagged(1):
- text='''The CMYK or subtractive method follows the way a printer
-mixes three pigments (cyan, magenta, and yellow) to form colors.
-Because mixing chemicals is more difficult than combining light there
-is a fourth parameter for darkness. For example a chemical
-combination of the CMY pigments generally never makes a perfect
-black -- instead producing a muddy color -- so, to get black printers
-don't use the CMY pigments but use a direct black ink. Because
-CMYK maps more directly to the way printer hardware works it may
-be the case that &| & | colors specified in CMYK will provide better fidelity
-and better control when printed.
-'''
- P=Paragraph(text,style)
- dumpParagraphFrags(P)
- aW, aH = 456.0, 42.8
- w,h = P.wrap(aW, aH)
- dumpParagraphLines(P)
- S = P.split(aW,aH)
- for s in S:
- s.wrap(aW,aH)
- dumpParagraphLines(s)
- aH = 500
-
- if flagged(2):
- P=Paragraph("""Price*""", styleSheet['Normal'])
- dumpParagraphFrags(P)
- w,h = P.wrap(24, 200)
- dumpParagraphLines(P)
-
- if flagged(3):
- text = """Dieses Kapitel bietet eine schnelle Programme :: starten
-
-Eingabeaufforderung :: (>>>)
-
->>> (Eingabeaufforderung)
-
-Einführung in Python Python :: Einführung
-.
-Das Ziel ist, die grundlegenden Eigenschaften von Python darzustellen, ohne
-sich zu sehr in speziellen Regeln oder Details zu verstricken. Dazu behandelt
-dieses Kapitel kurz die wesentlichen Konzepte wie Variablen, Ausdrücke,
-Kontrollfluss, Funktionen sowie Ein- und Ausgabe. Es erhebt nicht den Anspruch,
-umfassend zu sein."""
- P=Paragraph(text, styleSheet['Code'])
- dumpParagraphFrags(P)
- w,h = P.wrap(6*72, 9.7*72)
- dumpParagraphLines(P)
-
- if flagged(4):
- text='''Die eingebaute Funktion range(i, j [, stride]) erzeugt eine Liste von Ganzzahlen und füllt sie mit Werten k, für die gilt: i <= k < j. Man kann auch eine optionale Schrittweite angeben. Die eingebaute Funktion xrange() erfüllt einen ähnlichen Zweck, gibt aber eine unveränderliche Sequenz vom Typ XRangeType zurück. Anstatt alle Werte in der Liste abzuspeichern, berechnet diese Liste ihre Werte, wann immer sie angefordert werden. Das ist sehr viel speicherschonender, wenn mit sehr langen Listen von Ganzzahlen gearbeitet wird. XRangeType kennt eine einzige Methode, s.tolist(), die seine Werte in eine Liste umwandelt.'''
- aW = 420
- aH = 64.4
- P=Paragraph(text, B)
- dumpParagraphFrags(P)
- w,h = P.wrap(aW,aH)
- print('After initial wrap',w,h)
- dumpParagraphLines(P)
- S = P.split(aW,aH)
- dumpParagraphFrags(S[0])
- w0,h0 = S[0].wrap(aW,aH)
- print('After split wrap',w0,h0)
- dumpParagraphLines(S[0])
-
- if flagged(5):
- text = ' %s & %s < >]]>' % (chr(163),chr(163))
- P=Paragraph(text, styleSheet['Code'])
- dumpParagraphFrags(P)
- w,h = P.wrap(6*72, 9.7*72)
- dumpParagraphLines(P)
-
- if flagged(6):
- for text in ['''Here comes Helvetica 14 with strong emphasis.''',
- '''Here comes Helvetica 14 with strong emphasis.''',
- '''Here comes Courier 3cm and normal again.''',
- ]:
- P=Paragraph(text, styleSheet['Normal'], caseSensitive=0)
- dumpParagraphFrags(P)
- w,h = P.wrap(6*72, 9.7*72)
- dumpParagraphLines(P)
-
- if flagged(7):
- text = """Generated by:Dilbert"""
- P=Paragraph(text, styleSheet['Code'])
- dumpParagraphFrags(P)
- w,h = P.wrap(6*72, 9.7*72)
- dumpParagraphLines(P)
-
- if flagged(8):
- text ="""- bullet 0
- bullet 1
- bullet 2
- bullet 3
- bullet 4
- bullet 5"""
- P=Paragraph(text, styleSheet['Normal'])
- dumpParagraphFrags(P)
- w,h = P.wrap(6*72, 9.7*72)
- dumpParagraphLines(P)
- S = P.split(6*72,h/2.0)
- print(len(S))
- dumpParagraphLines(S[0])
- dumpParagraphLines(S[1])
-
-
- if flagged(9):
- text="""Furthermore, the fundamental error of
-regarding
functional notions as
-categorial delimits a general
-convention regarding the forms of the
-grammar. I suggested that these results
-would follow from the assumption that"""
- P=Paragraph(text,ParagraphStyle('aaa',parent=styleSheet['Normal'],align=TA_JUSTIFY))
- dumpParagraphFrags(P)
- w,h = P.wrap(6*cm-12, 9.7*72)
- dumpParagraphLines(P)
-
- if flagged(10):
- text="""a b c\xc2\xa0d e f"""
- P=Paragraph(text,ParagraphStyle('aaa',parent=styleSheet['Normal'],align=TA_JUSTIFY))
- dumpParagraphFrags(P)
- w,h = P.wrap(6*cm-12, 9.7*72)
- dumpParagraphLines(P)
-
- if flagged(11):
- text="""This page tests out a number of attributes of the paraStyle tag.
-This paragraph is in a style we have called "style1". It should be a normal paragraph, set in Courier 12 pt.
-It should be a normal paragraph, set in Courier (not bold).
-It should be a normal paragraph, set in Courier 12 pt."""
- P=Paragraph(text,style=ParagraphStyle('style1',fontName="Courier",fontSize=10))
- dumpParagraphFrags(P)
- w,h = P.wrap(6.27*72-12,10000)
- dumpParagraphLines(P)
diff --git a/reportlab/platypus/paraparser.py b/reportlab/platypus/paraparser.py
deleted file mode 100644
index 994b1853..00000000
--- a/reportlab/platypus/paraparser.py
+++ /dev/null
@@ -1,1349 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/paraparser.py
-__version__=''' $Id$ '''
-__doc__='''The parser used to process markup within paragraphs'''
-import string
-import re
-import sys
-import os
-import copy
-import base64
-from pprint import pprint as pp
-
-try:
- import pickle as pickle
-except:
- import pickle
-import unicodedata
-import reportlab.lib.sequencer
-
-from reportlab.lib.abag import ABag
-from reportlab.lib.utils import ImageReader, isPy3, annotateException, encode_label, asUnicode, asBytes, uniChr
-from reportlab.lib.colors import toColor, white, black, red, Color
-from reportlab.lib.fonts import tt2ps, ps2tt
-from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
-from reportlab.lib.units import inch,mm,cm,pica
-if isPy3:
- from html.parser import HTMLParser
- from html.entities import name2codepoint
-else:
- from HTMLParser import HTMLParser
- from htmlentitydefs import name2codepoint
-
-_re_para = re.compile(r'^\s*<\s*para(?:\s+|>|/>)')
-
-sizeDelta = 2 # amount to reduce font size by for super and sub script
-subFraction = 0.5 # fraction of font size that a sub script should be lowered
-superFraction = 0.5 # fraction of font size that a super script should be raised
-
-DEFAULT_INDEX_NAME='_indexAdd'
-
-def _convnum(s, unit=1, allowRelative=True):
- if s[0] in ('+','-') and allowRelative:
- try:
- return ('relative',int(s)*unit)
- except ValueError:
- return ('relative',float(s)*unit)
- else:
- try:
- return int(s)*unit
- except ValueError:
- return float(s)*unit
-
-def _num(s, unit=1, allowRelative=True):
- """Convert a string like '10cm' to an int or float (in points).
- The default unit is point, but optionally you can use other
- default units like mm.
- """
- if s.endswith('cm'):
- unit=cm
- s = s[:-2]
- if s.endswith('in'):
- unit=inch
- s = s[:-2]
- if s.endswith('pt'):
- unit=1
- s = s[:-2]
- if s.endswith('i'):
- unit=inch
- s = s[:-1]
- if s.endswith('mm'):
- unit=mm
- s = s[:-2]
- if s.endswith('pica'):
- unit=pica
- s = s[:-4]
- return _convnum(s,unit,allowRelative)
-
-def _numpct(s,unit=1,allowRelative=False):
- if s.endswith('%'):
- return _PCT(_convnum(s[:-1],allowRelative=allowRelative))
- else:
- return _num(s,unit,allowRelative)
-
-class _PCT:
- def __init__(self,v):
- self._value = v*0.01
-
- def normalizedValue(self,normalizer):
- normalizer = normalizer or getattr(self,'_normalizer')
- return normalizer*self._value
-
-def _valignpc(s):
- s = s.lower()
- if s in ('baseline','sub','super','top','text-top','middle','bottom','text-bottom'):
- return s
- if s.endswith('%'):
- n = _convnum(s[:-1])
- if isinstance(n,tuple):
- n = n[1]
- return _PCT(n)
- n = _num(s)
- if isinstance(n,tuple):
- n = n[1]
- return n
-
-def _autoLeading(x):
- x = x.lower()
- if x in ('','min','max','off'):
- return x
- raise ValueError('Invalid autoLeading=%r' % x )
-
-def _align(s):
- s = s.lower()
- if s=='left': return TA_LEFT
- elif s=='right': return TA_RIGHT
- elif s=='justify': return TA_JUSTIFY
- elif s in ('centre','center'): return TA_CENTER
- else: raise ValueError('illegal alignment %r' % s)
-
-def _bAnchor(s):
- s = s.lower()
- if not s in ('start','middle','end','numeric'):
- raise ValueError('illegal bullet anchor %r' % s)
- return s
-
-_paraAttrMap = {'font': ('fontName', None),
- 'face': ('fontName', None),
- 'fontsize': ('fontSize', _num),
- 'size': ('fontSize', _num),
- 'leading': ('leading', _num),
- 'autoleading': ('autoLeading', _autoLeading),
- 'lindent': ('leftIndent', _num),
- 'rindent': ('rightIndent', _num),
- 'findent': ('firstLineIndent', _num),
- 'align': ('alignment', _align),
- 'spaceb': ('spaceBefore', _num),
- 'spacea': ('spaceAfter', _num),
- 'bfont': ('bulletFontName', None),
- 'bfontsize': ('bulletFontSize',_num),
- 'boffsety': ('bulletOffsetY',_num),
- 'bindent': ('bulletIndent',_num),
- 'bcolor': ('bulletColor',toColor),
- 'banchor': ('bulletAnchor',_bAnchor),
- 'color':('textColor',toColor),
- 'backcolor':('backColor',toColor),
- 'bgcolor':('backColor',toColor),
- 'bg':('backColor',toColor),
- 'fg': ('textColor',toColor),
- }
-
-_bulletAttrMap = {
- 'font': ('bulletFontName', None),
- 'face': ('bulletFontName', None),
- 'size': ('bulletFontSize',_num),
- 'fontsize': ('bulletFontSize',_num),
- 'offsety': ('bulletOffsetY',_num),
- 'indent': ('bulletIndent',_num),
- 'color': ('bulletColor',toColor),
- 'fg': ('bulletColor',toColor),
- 'anchor': ('bulletAnchor',_bAnchor),
- }
-
-#things which are valid font attributes
-_fontAttrMap = {'size': ('fontSize', _num),
- 'face': ('fontName', None),
- 'name': ('fontName', None),
- 'fg': ('textColor', toColor),
- 'color':('textColor', toColor),
- 'backcolor':('backColor',toColor),
- 'bgcolor':('backColor',toColor),
- }
-#things which are valid span attributes
-_spanAttrMap = {'size': ('fontSize', _num),
- 'face': ('fontName', None),
- 'name': ('fontName', None),
- 'fg': ('textColor', toColor),
- 'color':('textColor', toColor),
- 'backcolor':('backColor',toColor),
- 'bgcolor':('backColor',toColor),
- 'style': ('style',None),
- }
-#things which are valid font attributes
-_linkAttrMap = {'size': ('fontSize', _num),
- 'face': ('fontName', None),
- 'name': ('fontName', None),
- 'fg': ('textColor', toColor),
- 'color':('textColor', toColor),
- 'backcolor':('backColor',toColor),
- 'bgcolor':('backColor',toColor),
- 'dest': ('link', None),
- 'destination': ('link', None),
- 'target': ('link', None),
- 'href': ('link', None),
- }
-_anchorAttrMap = {'fontSize': ('fontSize', _num),
- 'fontName': ('fontName', None),
- 'name': ('name', None),
- 'fg': ('textColor', toColor),
- 'color':('textColor', toColor),
- 'backcolor':('backColor',toColor),
- 'bgcolor':('backColor',toColor),
- 'href': ('href', None),
- }
-_imgAttrMap = {
- 'src': ('src', None),
- 'width': ('width',_numpct),
- 'height':('height',_numpct),
- 'valign':('valign',_valignpc),
- }
-_indexAttrMap = {
- 'name': ('name',None),
- 'item': ('item',None),
- 'offset': ('offset',None),
- 'format': ('format',None),
- }
-
-def _addAttributeNames(m):
- K = list(m.keys())
- for k in K:
- n = m[k][0]
- if n not in m: m[n] = m[k]
- n = n.lower()
- if n not in m: m[n] = m[k]
-
-_addAttributeNames(_paraAttrMap)
-_addAttributeNames(_fontAttrMap)
-_addAttributeNames(_spanAttrMap)
-_addAttributeNames(_bulletAttrMap)
-_addAttributeNames(_anchorAttrMap)
-_addAttributeNames(_linkAttrMap)
-
-def _applyAttributes(obj, attr):
- for k, v in attr.items():
- if isinstance(v,(list,tuple)) and v[0]=='relative':
- if hasattr(obj, k):
- v = v[1]+getattr(obj,k)
- else:
- v = v[1]
- setattr(obj,k,v)
-
-#Named character entities intended to be supported from the special font
-#with additions suggested by Christoph Zwerschke who also suggested the
-#numeric entity names that follow.
-greeks = {
- 'Aacute': u'\xc1',
- 'aacute': u'\xe1',
- 'Acirc': u'\xc2',
- 'acirc': u'\xe2',
- 'acute': u'\xb4',
- 'AElig': u'\xc6',
- 'aelig': u'\xe6',
- 'Agrave': u'\xc0',
- 'agrave': u'\xe0',
- 'alefsym': u'\u2135',
- 'Alpha': u'\u0391',
- 'alpha': u'\u03b1',
- 'and': u'\u2227',
- 'ang': u'\u2220',
- 'Aring': u'\xc5',
- 'aring': u'\xe5',
- 'asymp': u'\u2248',
- 'Atilde': u'\xc3',
- 'atilde': u'\xe3',
- 'Auml': u'\xc4',
- 'auml': u'\xe4',
- 'bdquo': u'\u201e',
- 'Beta': u'\u0392',
- 'beta': u'\u03b2',
- 'brvbar': u'\xa6',
- 'bull': u'\u2022',
- 'cap': u'\u2229',
- 'Ccedil': u'\xc7',
- 'ccedil': u'\xe7',
- 'cedil': u'\xb8',
- 'cent': u'\xa2',
- 'Chi': u'\u03a7',
- 'chi': u'\u03c7',
- 'circ': u'\u02c6',
- 'clubs': u'\u2663',
- 'cong': u'\u2245',
- 'copy': u'\xa9',
- 'crarr': u'\u21b5',
- 'cup': u'\u222a',
- 'curren': u'\xa4',
- 'dagger': u'\u2020',
- 'Dagger': u'\u2021',
- 'darr': u'\u2193',
- 'dArr': u'\u21d3',
- 'deg': u'\xb0',
- 'delta': u'\u03b4',
- 'Delta': u'\u2206',
- 'diams': u'\u2666',
- 'divide': u'\xf7',
- 'Eacute': u'\xc9',
- 'eacute': u'\xe9',
- 'Ecirc': u'\xca',
- 'ecirc': u'\xea',
- 'Egrave': u'\xc8',
- 'egrave': u'\xe8',
- 'empty': u'\u2205',
- 'emsp': u'\u2003',
- 'ensp': u'\u2002',
- 'Epsilon': u'\u0395',
- 'epsilon': u'\u03b5',
- 'epsiv': u'\u03b5',
- 'equiv': u'\u2261',
- 'Eta': u'\u0397',
- 'eta': u'\u03b7',
- 'ETH': u'\xd0',
- 'eth': u'\xf0',
- 'Euml': u'\xcb',
- 'euml': u'\xeb',
- 'euro': u'\u20ac',
- 'exist': u'\u2203',
- 'fnof': u'\u0192',
- 'forall': u'\u2200',
- 'frac12': u'\xbd',
- 'frac14': u'\xbc',
- 'frac34': u'\xbe',
- 'frasl': u'\u2044',
- 'Gamma': u'\u0393',
- 'gamma': u'\u03b3',
- 'ge': u'\u2265',
- 'harr': u'\u2194',
- 'hArr': u'\u21d4',
- 'hearts': u'\u2665',
- 'hellip': u'\u2026',
- 'Iacute': u'\xcd',
- 'iacute': u'\xed',
- 'Icirc': u'\xce',
- 'icirc': u'\xee',
- 'iexcl': u'\xa1',
- 'Igrave': u'\xcc',
- 'igrave': u'\xec',
- 'image': u'\u2111',
- 'infin': u'\u221e',
- 'int': u'\u222b',
- 'Iota': u'\u0399',
- 'iota': u'\u03b9',
- 'iquest': u'\xbf',
- 'isin': u'\u2208',
- 'Iuml': u'\xcf',
- 'iuml': u'\xef',
- 'Kappa': u'\u039a',
- 'kappa': u'\u03ba',
- 'Lambda': u'\u039b',
- 'lambda': u'\u03bb',
- 'lang': u'\u2329',
- 'laquo': u'\xab',
- 'larr': u'\u2190',
- 'lArr': u'\u21d0',
- 'lceil': u'\uf8ee',
- 'ldquo': u'\u201c',
- 'le': u'\u2264',
- 'lfloor': u'\uf8f0',
- 'lowast': u'\u2217',
- 'loz': u'\u25ca',
- 'lrm': u'\u200e',
- 'lsaquo': u'\u2039',
- 'lsquo': u'\u2018',
- 'macr': u'\xaf',
- 'mdash': u'\u2014',
- 'micro': u'\xb5',
- 'middot': u'\xb7',
- 'minus': u'\u2212',
- 'mu': u'\xb5',
- 'Mu': u'\u039c',
- 'nabla': u'\u2207',
- 'nbsp': u'\xa0',
- 'ndash': u'\u2013',
- 'ne': u'\u2260',
- 'ni': u'\u220b',
- 'notin': u'\u2209',
- 'not': u'\xac',
- 'nsub': u'\u2284',
- 'Ntilde': u'\xd1',
- 'ntilde': u'\xf1',
- 'Nu': u'\u039d',
- 'nu': u'\u03bd',
- 'Oacute': u'\xd3',
- 'oacute': u'\xf3',
- 'Ocirc': u'\xd4',
- 'ocirc': u'\xf4',
- 'OElig': u'\u0152',
- 'oelig': u'\u0153',
- 'Ograve': u'\xd2',
- 'ograve': u'\xf2',
- 'oline': u'\uf8e5',
- 'omega': u'\u03c9',
- 'Omega': u'\u2126',
- 'Omicron': u'\u039f',
- 'omicron': u'\u03bf',
- 'oplus': u'\u2295',
- 'ordf': u'\xaa',
- 'ordm': u'\xba',
- 'or': u'\u2228',
- 'Oslash': u'\xd8',
- 'oslash': u'\xf8',
- 'Otilde': u'\xd5',
- 'otilde': u'\xf5',
- 'otimes': u'\u2297',
- 'Ouml': u'\xd6',
- 'ouml': u'\xf6',
- 'para': u'\xb6',
- 'part': u'\u2202',
- 'permil': u'\u2030',
- 'perp': u'\u22a5',
- 'phis': u'\u03c6',
- 'Phi': u'\u03a6',
- 'phi': u'\u03d5',
- 'piv': u'\u03d6',
- 'Pi': u'\u03a0',
- 'pi': u'\u03c0',
- 'plusmn': u'\xb1',
- 'pound': u'\xa3',
- 'prime': u'\u2032',
- 'Prime': u'\u2033',
- 'prod': u'\u220f',
- 'prop': u'\u221d',
- 'Psi': u'\u03a8',
- 'psi': u'\u03c8',
- 'radic': u'\u221a',
- 'rang': u'\u232a',
- 'raquo': u'\xbb',
- 'rarr': u'\u2192',
- 'rArr': u'\u21d2',
- 'rceil': u'\uf8f9',
- 'rdquo': u'\u201d',
- 'real': u'\u211c',
- 'reg': u'\xae',
- 'rfloor': u'\uf8fb',
- 'Rho': u'\u03a1',
- 'rho': u'\u03c1',
- 'rlm': u'\u200f',
- 'rsaquo': u'\u203a',
- 'rsquo': u'\u2019',
- 'sbquo': u'\u201a',
- 'Scaron': u'\u0160',
- 'scaron': u'\u0161',
- 'sdot': u'\u22c5',
- 'sect': u'\xa7',
- 'shy': u'\xad',
- 'sigmaf': u'\u03c2',
- 'sigmav': u'\u03c2',
- 'Sigma': u'\u03a3',
- 'sigma': u'\u03c3',
- 'sim': u'\u223c',
- 'spades': u'\u2660',
- 'sube': u'\u2286',
- 'sub': u'\u2282',
- 'sum': u'\u2211',
- 'sup1': u'\xb9',
- 'sup2': u'\xb2',
- 'sup3': u'\xb3',
- 'supe': u'\u2287',
- 'sup': u'\u2283',
- 'szlig': u'\xdf',
- 'Tau': u'\u03a4',
- 'tau': u'\u03c4',
- 'there4': u'\u2234',
- 'thetasym': u'\u03d1',
- 'thetav': u'\u03d1',
- 'Theta': u'\u0398',
- 'theta': u'\u03b8',
- 'thinsp': u'\u2009',
- 'THORN': u'\xde',
- 'thorn': u'\xfe',
- 'tilde': u'\u02dc',
- 'times': u'\xd7',
- 'trade': u'\uf8ea',
- 'Uacute': u'\xda',
- 'uacute': u'\xfa',
- 'uarr': u'\u2191',
- 'uArr': u'\u21d1',
- 'Ucirc': u'\xdb',
- 'ucirc': u'\xfb',
- 'Ugrave': u'\xd9',
- 'ugrave': u'\xf9',
- 'uml': u'\xa8',
- 'upsih': u'\u03d2',
- 'Upsilon': u'\u03a5',
- 'upsilon': u'\u03c5',
- 'Uuml': u'\xdc',
- 'uuml': u'\xfc',
- 'weierp': u'\u2118',
- 'Xi': u'\u039e',
- 'xi': u'\u03be',
- 'Yacute': u'\xdd',
- 'yacute': u'\xfd',
- 'yen': u'\xa5',
- 'yuml': u'\xff',
- 'Yuml': u'\u0178',
- 'Zeta': u'\u0396',
- 'zeta': u'\u03b6',
- 'zwj': u'\u200d',
- 'zwnj': u'\u200c',
- }
-
-known_entities = dict([(k,uniChr(v)) for k,v in name2codepoint.items()])
-for k in greeks:
- if k not in known_entities:
- known_entities[k] = greeks[k]
-f = isPy3 and asBytes or asUnicode
-K = list(known_entities.keys())
-for k in K:
- known_entities[f(k)] = known_entities[k]
-del k, f, K
-
-#------------------------------------------------------------------------
-class ParaFrag(ABag):
- """class ParaFrag contains the intermediate representation of string
- segments as they are being parsed by the ParaParser.
- fontname, fontSize, rise, textColor, cbDefn
- """
-
-_greek2Utf8=None
-def _greekConvert(data):
- global _greek2Utf8
- if not _greek2Utf8:
- from reportlab.pdfbase.rl_codecs import RL_Codecs
- import codecs
- #our decoding map
- dm = codecs.make_identity_dict(range(32,256))
- for k in range(0,32):
- dm[k] = None
- dm.update(RL_Codecs._RL_Codecs__rl_codecs_data['symbol'][0])
- _greek2Utf8 = {}
- for k,v in dm.items():
- if not v:
- u = '\0'
- else:
- if isPy3:
- u = chr(v)
- else:
- u = unichr(v).encode('utf8')
- _greek2Utf8[chr(k)] = u
- return ''.join(map(_greek2Utf8.__getitem__,data))
-
-#------------------------------------------------------------------
-# !!! NOTE !!! THIS TEXT IS NOW REPLICATED IN PARAGRAPH.PY !!!
-# The ParaFormatter will be able to format the following
-# tags:
-# < /b > - bold
-# < /i > - italics
-# < u > < /u > - underline
-# < strike > < /strike > - strike through
-# < super > < /super > - superscript
-# < sup > < /sup > - superscript
-# < sub > < /sub > - subscript
-#
-#
-# < bullet > - bullet text (at head of para only)
-#
-#
-# link text
-# attributes of links
-# size/fontSize=num
-# name/face/fontName=name
-# fg/textColor/color=color
-# backcolor/backColor/bgcolor=color
-# dest/destination/target/href/link=target
-# anchor text
-# attributes of anchors
-# fontSize=num
-# fontName=name
-# fg/textColor/color=color
-# backcolor/backColor/bgcolor=color
-# href=href
-#
-#
-#
-#
-# width="w%" --> fontSize*w/100 idea from Roberto Alsina
-# height="h%" --> linewidth*h/100
-# -
-#
-# The whole may be surrounded by tags
-#
-# It will also be able to handle any MathML specified Greek characters.
-#------------------------------------------------------------------
-class ParaParser(HTMLParser):
-
- #----------------------------------------------------------
- # First we will define all of the xml tag handler functions.
- #
- # start_(attributes)
- # end_()
- #
- # While parsing the xml ParaFormatter will call these
- # functions to handle the string formatting tags.
- # At the start of each tag the corresponding field will
- # be set to 1 and at the end tag the corresponding field will
- # be set to 0. Then when handle_data is called the options
- # for that data will be aparent by the current settings.
- #----------------------------------------------------------
-
- def __getattr__( self, attrName ):
- """This way we can handle the same way as (ignoring case)."""
- if attrName!=attrName.lower() and attrName!="caseSensitive" and not self.caseSensitive and \
- (attrName.startswith("start_") or attrName.startswith("end_")):
- return getattr(self,attrName.lower())
- raise AttributeError(attrName)
-
- #### bold
- def start_b( self, attributes ):
- self._push('b',bold=1)
-
- def end_b( self ):
- self._pop('b')
-
- def start_strong( self, attributes ):
- self._push('strong',bold=1)
-
- def end_strong( self ):
- self._pop('strong')
-
- #### italics
- def start_i( self, attributes ):
- self._push('i',italic=1)
-
- def end_i( self ):
- self._pop('i')
-
- def start_em( self, attributes ):
- self._push('em', italic=1)
-
- def end_em( self ):
- self._pop('em')
-
- #### underline
- def start_u( self, attributes ):
- self._push('u',underline=1)
-
- def end_u( self ):
- self._pop('u')
-
- #### strike
- def start_strike( self, attributes ):
- self._push('strike',strike=1)
-
- def end_strike( self ):
- self._pop('strike')
-
- #### link
- def start_link(self, attributes):
- self._push('link',**self.getAttributes(attributes,_linkAttrMap))
-
- def end_link(self):
- if self._pop('link').link is None:
- raise ValueError(' has no target or href')
-
- #### anchor
- def start_a(self, attributes):
- A = self.getAttributes(attributes,_anchorAttrMap)
- name = A.get('name',None)
- if name is not None:
- name = name.strip()
- if not name:
- self._syntax_error(' anchor variant requires non-blank name')
- if len(A)>1:
- self._syntax_error(' anchor variant only allows name attribute')
- A = dict(name=A['name'])
- A['_selfClosingTag'] = 'anchor'
- else:
- href = A.get('href','').strip()
- A['link'] = href #convert to our link form
- A.pop('href',None)
- self._push('a',**A)
-
- def end_a(self):
- frag = self._stack[-1]
- sct = getattr(frag,'_selfClosingTag','')
- if sct:
- if not (sct=='anchor' and frag.name):
- raise ValueError('Parser failure in ')
- defn = frag.cbDefn = ABag()
- defn.label = defn.kind = 'anchor'
- defn.name = frag.name
- del frag.name, frag._selfClosingTag
- self.handle_data('')
- self._pop('a')
- else:
- if self._pop('a').link is None:
- raise ValueError(' has no href')
-
- def start_img(self,attributes):
- A = self.getAttributes(attributes,_imgAttrMap)
- if not A.get('src'):
- self._syntax_error('
needs src attribute')
- A['_selfClosingTag'] = 'img'
- self._push('img',**A)
-
- def end_img(self):
- frag = self._stack[-1]
- if not getattr(frag,'_selfClosingTag',''):
- raise ValueError('Parser failure in
')
- defn = frag.cbDefn = ABag()
- defn.kind = 'img'
- defn.src = getattr(frag,'src',None)
- defn.image = ImageReader(defn.src)
- size = defn.image.getSize()
- defn.width = getattr(frag,'width',size[0])
- defn.height = getattr(frag,'height',size[1])
- defn.valign = getattr(frag,'valign','bottom')
- del frag._selfClosingTag
- self.handle_data('')
- self._pop('img')
-
- #### super script
- def start_super( self, attributes ):
- self._push('super',super=1)
-
- def end_super( self ):
- self._pop('super')
-
- def start_sup( self, attributes ):
- self._push('sup',super=1)
-
- def end_sup( self ):
- self._pop('sup')
-
- #### sub script
- def start_sub( self, attributes ):
- self._push('sub',sub=1)
-
- def end_sub( self ):
- self._pop('sub')
-
- #### greek script
- #### add symbol encoding
- def handle_charref(self, name):
- try:
- if name[0]=='x':
- n = int(name[1:],16)
- else:
- n = int(name)
- except ValueError:
- self.unknown_charref(name)
- return
- self.handle_data(uniChr(n)) #.encode('utf8'))
-
- def syntax_error(self,lineno,message):
- self._syntax_error(message)
-
- def _syntax_error(self,message):
- if message[:10]=="attribute " and message[-17:]==" value not quoted": return
- self.errors.append(message)
-
- def start_greek(self, attr):
- self._push('greek',greek=1)
-
- def end_greek(self):
- self._pop('greek')
-
- def start_unichar(self, attr):
- if 'name' in attr:
- if 'code' in attr:
- self._syntax_error(' invalid with both name and code attributes')
- try:
- v = unicodedata.lookup(attr['name'])
- except KeyError:
- self._syntax_error(' invalid name attribute\n"%s"' % ascii(attr['name']))
- v = '\0'
- elif 'code' in attr:
- try:
- v = int(eval(attr['code']))
- v = chr(v) if isPy3 else unichr(v)
- except:
- self._syntax_error(' invalid code attribute %s' % ascii(attr['code']))
- v = '\0'
- else:
- v = None
- if attr:
- self._syntax_error(' invalid attribute %s' % list(attr.keys())[0])
-
- if v is not None:
- self.handle_data(v)
- self._push('unichar',_selfClosingTag='unichar')
-
- def end_unichar(self):
- self._pop('unichar')
-
- def start_font(self,attr):
- A = self.getAttributes(attr,_spanAttrMap)
- if 'fontName' in A:
- A['fontName'], A['bold'], A['italic'] = ps2tt(A['fontName'])
- self._push('font',**A)
-
- def end_font(self):
- self._pop('font')
-
- def start_span(self,attr):
- A = self.getAttributes(attr,_spanAttrMap)
- if 'style' in A:
- style = self.findSpanStyle(A.pop('style'))
- D = {}
- for k in 'fontName fontSize textColor backColor'.split():
- v = getattr(style,k,self)
- if v is self: continue
- D[k] = v
- D.update(A)
- A = D
- if 'fontName' in A:
- A['fontName'], A['bold'], A['italic'] = ps2tt(A['fontName'])
- self._push('span',**A)
-
- def end_span(self):
- self._pop('span')
-
- def start_br(self, attr):
- self._push('br',_selfClosingTag='br',lineBreak=True,text='')
-
- def end_br(self):
- #print('\nend_br called, %d frags in list' % len(self.fragList))
- frag = self._stack[-1]
- if not (frag._selfClosingTag=='br' and frag.lineBreak):
- raise ValueError('Parser failure in
')
- del frag._selfClosingTag
- self.handle_data('')
- self._pop('br')
-
- def _initial_frag(self,attr,attrMap,bullet=0):
- style = self._style
- if attr!={}:
- style = copy.deepcopy(style)
- _applyAttributes(style,self.getAttributes(attr,attrMap))
- self._style = style
-
- # initialize semantic values
- frag = ParaFrag()
- frag.sub = 0
- frag.super = 0
- frag.rise = 0
- frag.underline = 0
- frag.strike = 0
- frag.greek = 0
- frag.link = None
- if bullet:
- frag.fontName, frag.bold, frag.italic = ps2tt(style.bulletFontName)
- frag.fontSize = style.bulletFontSize
- frag.textColor = hasattr(style,'bulletColor') and style.bulletColor or style.textColor
- else:
- frag.fontName, frag.bold, frag.italic = ps2tt(style.fontName)
- frag.fontSize = style.fontSize
- frag.textColor = style.textColor
- return frag
-
- def start_para(self,attr):
- frag = self._initial_frag(attr,_paraAttrMap)
- frag.__tag__ = 'para'
- self._stack = [frag]
-
- def end_para(self):
- self._pop('para')
-
- def start_bullet(self,attr):
- if hasattr(self,'bFragList'):
- self._syntax_error('only one tag allowed')
- self.bFragList = []
- frag = self._initial_frag(attr,_bulletAttrMap,1)
- frag.isBullet = 1
- frag.__tag__ = 'bullet'
- self._stack.append(frag)
-
- def end_bullet(self):
- self._pop('bullet')
-
- #---------------------------------------------------------------
- def start_seqdefault(self, attr):
- try:
- default = attr['id']
- except KeyError:
- default = None
- self._seq.setDefaultCounter(default)
-
- def end_seqdefault(self):
- pass
-
- def start_seqreset(self, attr):
- try:
- id = attr['id']
- except KeyError:
- id = None
- try:
- base = int(attr['base'])
- except:
- base=0
- self._seq.reset(id, base)
-
- def end_seqreset(self):
- pass
-
- def start_seqchain(self, attr):
- try:
- order = attr['order']
- except KeyError:
- order = ''
- order = order.split()
- seq = self._seq
- for p,c in zip(order[:-1],order[1:]):
- seq.chain(p, c)
- end_seqchain = end_seqreset
-
- def start_seqformat(self, attr):
- try:
- id = attr['id']
- except KeyError:
- id = None
- try:
- value = attr['value']
- except KeyError:
- value = '1'
- self._seq.setFormat(id,value)
- end_seqformat = end_seqreset
-
- # AR hacking in aliases to allow the proper casing for RML.
- # the above ones should be deprecated over time. 2001-03-22
- start_seqDefault = start_seqdefault
- end_seqDefault = end_seqdefault
- start_seqReset = start_seqreset
- end_seqReset = end_seqreset
- start_seqChain = start_seqchain
- end_seqChain = end_seqchain
- start_seqFormat = start_seqformat
- end_seqFormat = end_seqformat
-
- def start_seq(self, attr):
- #if it has a template, use that; otherwise try for id;
- #otherwise take default sequence
- if 'template' in attr:
- templ = attr['template']
- self.handle_data(templ % self._seq)
- return
- elif 'id' in attr:
- id = attr['id']
- else:
- id = None
- increment = attr.get('inc', None)
- if not increment:
- output = self._seq.nextf(id)
- else:
- #accepts "no" for do not increment, or an integer.
- #thus, 0 and 1 increment by the right amounts.
- if increment.lower() == 'no':
- output = self._seq.thisf(id)
- else:
- incr = int(increment)
- output = self._seq.thisf(id)
- self._seq.reset(id, self._seq._this() + incr)
- self.handle_data(output)
-
- def end_seq(self):
- pass
-
- def start_ondraw(self,attr):
- defn = ABag()
- if 'name' in attr: defn.name = attr['name']
- else: self._syntax_error(' needs at least a name attribute')
-
- if 'label' in attr: defn.label = attr['label']
- defn.kind='onDraw'
- self._push('ondraw',cbDefn=defn)
- self.handle_data('')
- self._pop('ondraw')
- start_onDraw=start_ondraw
- end_onDraw=end_ondraw=end_seq
-
- def start_index(self,attr):
- attr=self.getAttributes(attr,_indexAttrMap)
- defn = ABag()
- if 'item' in attr:
- label = attr['item']
- else:
- self._syntax_error(' needs at least an item attribute')
- if 'name' in attr:
- name = attr['name']
- else:
- name = DEFAULT_INDEX_NAME
- format = attr.get('format',None)
- if format is not None and format not in ('123','I','i','ABC','abc'):
- raise ValueError('index tag format is %r not valid 123 I i ABC or abc' % offset)
- offset = attr.get('offset',None)
- if offset is not None:
- try:
- offset = int(offset)
- except:
- raise ValueError('index tag offset is %r not an int' % offset)
- defn.label = encode_label((label,format,offset))
- defn.name = name
- defn.kind='index'
- self._push('index',cbDefn=defn)
- self.handle_data('')
- self._pop('index',)
- end_index=end_seq
-
- def start_unknown(self,attr):
- pass
- end_unknown=end_seq
-
- #---------------------------------------------------------------
- def _push(self,tag,**attr):
- frag = copy.copy(self._stack[-1])
- frag.__tag__ = tag
- _applyAttributes(frag,attr)
- self._stack.append(frag)
-
- def _pop(self,tag):
- frag = self._stack.pop()
- if tag==frag.__tag__: return frag
- raise ValueError('Parse error: saw %s> instead of expected %s>' % (tag,frag.__tag__))
-
- def getAttributes(self,attr,attrMap):
- A = {}
- for k, v in attr.items():
- if not self.caseSensitive:
- k = k.lower()
- if k in list(attrMap.keys()):
- j = attrMap[k]
- func = j[1]
- try:
- A[j[0]] = v if func is None else func(v)
- except:
- self._syntax_error('%s: invalid value %s'%(k,v))
- else:
- self._syntax_error('invalid attribute name %s'%k)
- return A
-
- #----------------------------------------------------------------
-
- def __init__(self,verbose=0, caseSensitive=0, ignoreUnknownTags=1):
- HTMLParser.__init__(self,
- **(dict(convert_charrefs=False) if sys.version_info>=(3,4) else {}))
- self.verbose = verbose
- #HTMLParser is case insenstive anyway, but the rml interface still needs this
- #all start/end_ methods should have a lower case version for HMTMParser
- self.caseSensitive = caseSensitive
- self.ignoreUnknownTags = ignoreUnknownTags
-
- def _iReset(self):
- self.fragList = []
- if hasattr(self, 'bFragList'): delattr(self,'bFragList')
-
- def _reset(self, style):
- '''reset the parser'''
-
- HTMLParser.reset(self)
- # initialize list of string segments to empty
- self.errors = []
- self._style = style
- self._iReset()
-
- #----------------------------------------------------------------
- def handle_data(self,data):
- "Creates an intermediate representation of string segments."
-
- #The old parser would only 'see' a string after all entities had
- #been processed. Thus, 'Hello ™ World' would emerge as one
- #fragment. HTMLParser processes these separately. We want to ensure
- #that successive calls like this are concatenated, to prevent too many
- #fragments being created.
-
- frag = copy.copy(self._stack[-1])
- if hasattr(frag,'cbDefn'):
- kind = frag.cbDefn.kind
- if data: self._syntax_error('Only empty <%s> tag allowed' % kind)
- elif hasattr(frag,'_selfClosingTag'):
- if data!='': self._syntax_error('No content allowed in %s tag' % frag._selfClosingTag)
- return
- else:
- # if sub and super are both on they will cancel each other out
- if frag.sub == 1 and frag.super == 1:
- frag.sub = 0
- frag.super = 0
-
- if frag.sub:
- frag.rise = -frag.fontSize*subFraction
- frag.fontSize = max(frag.fontSize-sizeDelta,3)
- elif frag.super:
- frag.rise = frag.fontSize*superFraction
- frag.fontSize = max(frag.fontSize-sizeDelta,3)
-
- if frag.greek:
- frag.fontName = 'symbol'
- data = _greekConvert(data)
-
- # bold, italic, and underline
- frag.fontName = tt2ps(frag.fontName,frag.bold,frag.italic)
-
- #save our data
- frag.text = data
-
- if hasattr(frag,'isBullet'):
- delattr(frag,'isBullet')
- self.bFragList.append(frag)
- else:
- self.fragList.append(frag)
-
- def handle_cdata(self,data):
- self.handle_data(data)
-
- def _setup_for_parse(self,style):
- self._seq = reportlab.lib.sequencer.getSequencer()
- self._reset(style) # reinitialise the parser
-
- def _complete_parse(self):
- "Reset after parsing, to be ready for next paragraph"
- del self._seq
- style = self._style
- del self._style
- if len(self.errors)==0:
- fragList = self.fragList
- bFragList = hasattr(self,'bFragList') and self.bFragList or None
- self._iReset()
- else:
- fragList = bFragList = None
-
- return style, fragList, bFragList
-
- def _tt_handle(self,tt):
- "Iterate through a pre-parsed tuple tree (e.g. from pyRXP)"
- #import pprint
- #pprint.pprint(tt)
- #find the corresponding start_tagname and end_tagname methods.
- #These must be defined.
- tag = tt[0]
- try:
- start = getattr(self,'start_'+tag)
- end = getattr(self,'end_'+tag)
- except AttributeError:
- if not self.ignoreUnknownTags:
- raise ValueError('Invalid tag "%s"' % tag)
- start = self.start_unknown
- end = self.end_unknown
-
- #call the start_tagname method
- start(tt[1] or {})
- #if tree node has any children, they will either be further nodes,
- #or text. Accordingly, call either this function, or handle_data.
- C = tt[2]
- if C:
- M = self._tt_handlers
- for c in C:
- M[isinstance(c,(list,tuple))](c)
-
- #call the end_tagname method
- end()
-
- def _tt_start(self,tt):
- self._tt_handlers = self.handle_data,self._tt_handle
- self._tt_handle(tt)
-
- def tt_parse(self,tt,style):
- '''parse from tupletree form'''
- self._setup_for_parse(style)
- self._tt_start(tt)
- return self._complete_parse()
-
- def findSpanStyle(self,style):
- raise ValueError('findSpanStyle not implemented in this parser')
-
- #HTMLParser interface
- def parse(self, text, style):
- "attempt replacement for parse"
- self._setup_for_parse(style)
- text = asUnicode(text)
- if not(len(text)>=6 and text[0]=='<' and _re_para.match(text)):
- text = u""+text+u""
- try:
- self.feed(text)
- except:
- annotateException('\nparagraph text %s caused exception' % ascii(text))
- return self._complete_parse()
-
- def handle_starttag(self, tag, attrs):
- "Called by HTMLParser when a tag starts"
-
- #tuple tree parser used to expect a dict. HTML parser
- #gives list of two-element tuples
- if isinstance(attrs, list):
- d = {}
- for (k, v) in attrs:
- d[k] = v
- attrs = d
- if not self.caseSensitive: tag = tag.lower()
- try:
- start = getattr(self,'start_'+tag)
- except AttributeError:
- if not self.ignoreUnknownTags:
- raise ValueError('Invalid tag "%s"' % tag)
- start = self.start_unknown
- #call it
- start(attrs or {})
-
- def handle_endtag(self, tag):
- "Called by HTMLParser when a tag ends"
- #find the existing end_tagname method
- if not self.caseSensitive: tag = tag.lower()
- try:
- end = getattr(self,'end_'+tag)
- except AttributeError:
- if not self.ignoreUnknownTags:
- raise ValueError('Invalid tag "%s"' % tag)
- end = self.end_unknown
- #call it
- end()
-
- def handle_entityref(self, name):
- "Handles a named entity. "
- try:
- v = known_entities[name]
- except:
- v = u'&%s;' % name
- self.handle_data(v)
-
-if __name__=='__main__':
- from reportlab.platypus import cleanBlockQuotedText
- from reportlab.lib.styles import _baseFontName
- _parser=ParaParser()
- def check_text(text,p=_parser):
- print('##########')
- text = cleanBlockQuotedText(text)
- l,rv,bv = p.parse(text,style)
- if rv is None:
- for l in _parser.errors:
- print(l)
- else:
- print('ParaStyle', l.fontName,l.fontSize,l.textColor)
- for l in rv:
- sys.stdout.write(l.fontName,l.fontSize,l.textColor,l.bold, l.rise, '|%s|'%l.text[:25])
- if hasattr(l,'cbDefn'):
- print('cbDefn',getattr(l.cbDefn,'name',''),getattr(l.cbDefn,'label',''),l.cbDefn.kind)
- else: print()
-
- style=ParaFrag()
- style.fontName=_baseFontName
- style.fontSize = 12
- style.textColor = black
- style.bulletFontName = black
- style.bulletFontName=_baseFontName
- style.bulletFontSize=12
-
- text='''
- aDβ
-
- Tell me, O muse, of that ingenious hero who travelled far and wide
- after he had sacked the famous town of Troy. Many cities did he visit,
- and many were the nations with whose manners and customs he was acquainted;
- moreover he suffered much by sea while trying to save his own life
- and bring his men safely home; but do what he might he could not save
- his men, for they perished through their own sheer folly in eating
- the cattle of the Sun-god Hyperion; so the god prevented them from
- ever reaching home. Tell me, too, about all these things, O daughter
- of Jove, from whatsoever source you1 may know them.
- '''
- check_text(text)
- check_text(' ')
- check_text('ReportLab -- Reporting for the Internet Age'%_baseFontName)
- check_text('''
- τTell me, O muse, of that ingenious hero who travelled far and wide
- after he had sacked the famous town of Troy. Many cities did he visit,
- and many were the nations with whose manners and customs he was acquainted;
- moreover he suffered much by sea while trying to save his own life
- and bring his men safely home; but do what he might he could not save
- his men, for they perished through their own sheer folly in eating
- the cattle of the Sun-god Hyperion; so the god prevented them from
- ever reaching home. Tell me, too, about all these things, O daughter
- of Jove, from whatsoever source you may know them.''')
- check_text('''
- Telemachus took this speech as of good omen and rose at once, for
- he was bursting with what he had to say. He stood in the middle of
- the assembly and the good herald Pisenor brought him his staff. Then,
- turning to Aegyptius, "Sir," said he, "it is I, as you will shortly
- learn, who have convened you, for it is I who am the most aggrieved.
- I have not got wind of any host approaching about which I would warn
- you, nor is there any matter of public moment on which I would speak.
- My grieveance is purely personal, and turns on two great misfortunes
- which have fallen upon my house. The first of these is the loss of
- my excellent father, who was chief among all you here present, and
- was like a father to every one of you; the second is much more serious,
- and ere long will be the utter ruin of my estate. The sons of all
- the chief men among you are pestering my mother to marry them against
- her will. They are afraid to go to her father Icarius, asking him
- to choose the one he likes best, and to provide marriage gifts for
- his daughter, but day by day they keep hanging about my father's house,
- sacrificing our oxen, sheep, and fat goats for their banquets, and
- never giving so much as a thought to the quantity of wine they drink.
- No estate can stand such recklessness; we have now no Ulysses to ward
- off harm from our doors, and I cannot hold my own against them. I
- shall never all my days be as good a man as he was, still I would
- indeed defend myself if I had power to do so, for I cannot stand such
- treatment any longer; my house is being disgraced and ruined. Have
- respect, therefore, to your own consciences and to public opinion.
- Fear, too, the wrath of heaven, lest the gods should be displeased
- and turn upon you. I pray you by Jove and Themis, who is the beginning
- and the end of councils, [do not] hold back, my friends, and leave
- me singlehanded- unless it be that my brave father Ulysses did some
- wrong to the Achaeans which you would now avenge on me, by aiding
- and abetting these suitors. Moreover, if I am to be eaten out of house
- and home at all, I had rather you did the eating yourselves, for I
- could then take action against you to some purpose, and serve you
- with notices from house to house till I got paid in full, whereas
- now I have no remedy."''')
-
- check_text('''
-But as the sun was rising from the fair sea into the firmament of
-heaven to shed light on mortals and immortals, they reached Pylos
-the city of Neleus. Now the people of Pylos were gathered on the sea
-shore to offer sacrifice of black bulls to Neptune lord of the Earthquake.
-There were nine guilds with five hundred men in each, and there were
-nine bulls to each guild. As they were eating the inward meats and
-burning the thigh bones [on the embers] in the name of Neptune, Telemachus
-and his crew arrived, furled their sails, brought their ship to anchor,
-and went ashore. ''')
- check_text('''
-So the neighbours and kinsmen of Menelaus were feasting and making
-merry in his house. There was a bard also to sing to them and play
-his lyre, while two tumblers went about performing in the midst of
-them when the man struck up with his tune.]''')
- check_text('''
-"When we had passed the [Wandering] rocks, with Scylla and terrible
-Charybdis, we reached the noble island of the sun-god, where were
-the goodly cattle and sheep belonging to the sun Hyperion. While still
-at sea in my ship I could bear the cattle lowing as they came home
-to the yards, and the sheep bleating. Then I remembered what the blind
-Theban prophet Teiresias had told me, and how carefully Aeaean Circe
-had warned me to shun the island of the blessed sun-god. So being
-much troubled I said to the men, 'My men, I know you are hard pressed,
-but listen while I tell you the prophecy that Teiresias made me, and
-how carefully Aeaean Circe warned me to shun the island of the blessed
-sun-god, for it was here, she said, that our worst danger would lie.
-Head the ship, therefore, away from the island.''')
- check_text('''A<B>C&D"E'F''')
- check_text('''A< B> C& D" E' F''')
- check_text('''&'"]]>''')
- check_text('''+
-There was a bard also to sing to them and play
-his lyre, while two tumblers went about performing in the midst of
-them when the man struck up with his tune.]''')
- check_text('''A paragraph''')
- check_text('''B paragraph''')
- # HVB, 30.05.2003: Test for new features
- _parser.caseSensitive=0
- check_text('''Here comes Helvetica 14 with strong emphasis.''')
- check_text('''Here comes Helvetica 14 with strong emphasis.''')
- check_text('''Here comes Courier 3cm and normal again.''')
- check_text('''Before the break
the middle line
and the last line.''')
- check_text('''This should be an inline image
!''')
- check_text('''aaa bbbb underline cccc''')
diff --git a/reportlab/platypus/tableofcontents.py b/reportlab/platypus/tableofcontents.py
deleted file mode 100644
index 53ed64a4..00000000
--- a/reportlab/platypus/tableofcontents.py
+++ /dev/null
@@ -1,553 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/tableofcontents.py
-
-__version__=''' $Id$ '''
-__doc__="""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 moultiBuild0() method must be called.
-
-The levelParaStyle 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.
-"""
-
-from reportlab.lib import enums
-from reportlab.lib.units import cm
-from reportlab.lib.utils import commasplit, escapeOnce, encode_label, decode_label, strTypes
-from reportlab.lib.styles import ParagraphStyle, _baseFontName
-from reportlab.platypus.paragraph import Paragraph
-from reportlab.platypus.doctemplate import IndexingFlowable
-from reportlab.platypus.tables import TableStyle, Table
-from reportlab.platypus.flowables import Spacer, Flowable
-from reportlab.pdfbase.pdfmetrics import stringWidth
-from reportlab.pdfgen import canvas
-
-def unquote(txt):
- from xml.sax.saxutils import unescape
- return unescape(txt, {"'": "'", """: '"'})
-
-try:
- set
-except:
- class set(list):
- def add(self,x):
- if x not in self:
- list.append(self,x)
-
-def drawPageNumbers(canvas, style, pages, availWidth, availHeight, dot=' . '):
- '''
- 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.
- '''
- pagestr = ', '.join([str(p) for p, _ in pages])
- x, y = canvas._curr_tx_info['cur_x'], canvas._curr_tx_info['cur_y']
-
- fontSize = style.fontSize
- pagestrw = stringWidth(pagestr, style.fontName, fontSize)
-
- #if it's too long to fit, we need to shrink to fit in 10% increments.
- #it would be very hard to output multiline entries.
- #however, we impose a minimum size of 1 point as we don't want an
- #infinite loop. Ultimately we should allow a TOC entry to spill
- #over onto a second line if needed.
- freeWidth = availWidth-x
- while pagestrw > freeWidth and fontSize >= 1.0:
- fontSize = 0.9 * fontSize
- pagestrw = stringWidth(pagestr, style.fontName, fontSize)
-
-
- if isinstance(dot, strTypes):
- if dot:
- dotw = stringWidth(dot, style.fontName, fontSize)
- dotsn = int((availWidth-x-pagestrw)/dotw)
- else:
- dotsn = dotw = 0
- text = '%s%s' % (dotsn * dot, pagestr)
- newx = availWidth - dotsn*dotw - pagestrw
- pagex = availWidth - pagestrw
- elif dot is None:
- text = ', ' + pagestr
- newx = x
- pagex = newx
- else:
- raise TypeError('Argument dot should either be None or an instance of basestring.')
-
- tx = canvas.beginText(newx, y)
- tx.setFont(style.fontName, fontSize)
- tx.setFillColor(style.textColor)
- tx.textLine(text)
- canvas.drawText(tx)
-
- commaw = stringWidth(', ', style.fontName, fontSize)
- for p, key in pages:
- if not key:
- continue
- w = stringWidth(str(p), style.fontName, fontSize)
- canvas.linkRect('', key, (pagex, y, pagex+w, y+style.leading), relative=1)
- pagex += w + commaw
-
-# Default paragraph styles for tables of contents.
-# (This could also be generated automatically or even
-# on-demand if it is not known how many levels the
-# TOC will finally need to display...)
-
-delta = 1*cm
-epsilon = 0.5*cm
-
-defaultLevelStyles = [
- ParagraphStyle(
- name='Level 0',
- fontName=_baseFontName,
- fontSize=10,
- leading=11,
- firstLineIndent = 0,
- leftIndent = epsilon)]
-
-defaultTableStyle = \
- TableStyle([
- ('VALIGN', (0,0), (-1,-1), 'TOP'),
- ('RIGHTPADDING', (0,0), (-1,-1), 0),
- ('LEFTPADDING', (0,0), (-1,-1), 0),
- ])
-
-class TableOfContents(IndexingFlowable):
- """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.
- """
-
- def __init__(self):
- self.rightColumnWidth = 72
- self.levelStyles = defaultLevelStyles
- self.tableStyle = defaultTableStyle
- self.dotsMinLevel = 1
- self._table = None
- self._entries = []
- self._lastEntries = []
-
- def beforeBuild(self):
- # keep track of the last run
- self._lastEntries = self._entries[:]
- self.clearEntries()
-
- def isIndexing(self):
- return 1
-
- def isSatisfied(self):
- return (self._entries == self._lastEntries)
-
- def notify(self, kind, stuff):
- """The notification hook called to register all kinds of events.
-
- Here we are interested in 'TOCEntry' events only.
- """
- if kind == 'TOCEntry':
- self.addEntry(*stuff)
-
- def clearEntries(self):
- self._entries = []
-
- def getLevelStyle(self, n):
- '''Returns the style for level n, generating and caching styles on demand if not present.'''
- try:
- return self.levelStyles[n]
- except IndexError:
- prevstyle = self.getLevelStyle(n-1)
- self.levelStyles.append(ParagraphStyle(
- name='%s-%d-indented' % (prevstyle.name, n),
- parent=prevstyle,
- firstLineIndent = prevstyle.firstLineIndent+delta,
- leftIndent = prevstyle.leftIndent+delta))
- return self.levelStyles[n]
-
- def addEntry(self, 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."""
-
- assert type(level) == type(1), "Level must be an integer"
- self._entries.append((level, text, pageNum, key))
-
-
- def addEntries(self, 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."""
-
- for entryargs in listOfEntries:
- self.addEntry(*entryargs)
-
-
- def wrap(self, availWidth, availHeight):
- "All table properties should be known by now."
-
- # makes an internal table which does all the work.
- # we draw the LAST RUN's entries! If there are
- # none, we make some dummy data to keep the table
- # from complaining
- if len(self._lastEntries) == 0:
- _tempEntries = [(0,'Placeholder for table of contents',0,None)]
- else:
- _tempEntries = self._lastEntries
-
- def drawTOCEntryEnd(canvas, kind, label):
- '''Callback to draw dots and page numbers after each entry.'''
- label = label.split(',')
- page, level, key = int(label[0]), int(label[1]), eval(label[2],{})
- style = self.getLevelStyle(level)
- if self.dotsMinLevel >= 0 and level >= self.dotsMinLevel:
- dot = ' . '
- else:
- dot = ''
- drawPageNumbers(canvas, style, [(page, key)], availWidth, availHeight, dot)
- self.canv.drawTOCEntryEnd = drawTOCEntryEnd
-
- tableData = []
- for (level, text, pageNum, key) in _tempEntries:
- style = self.getLevelStyle(level)
- if key:
- text = '%s' % (key, text)
- keyVal = repr(key).replace(',','\\x2c').replace('"','\\x2c')
- else:
- keyVal = None
- para = Paragraph('%s' % (text, pageNum, level, keyVal), style)
- if style.spaceBefore:
- tableData.append([Spacer(1, style.spaceBefore),])
- tableData.append([para,])
-
- self._table = Table(tableData, colWidths=(availWidth,), style=self.tableStyle)
-
- self.width, self.height = self._table.wrapOn(self.canv,availWidth, availHeight)
- return (self.width, self.height)
-
-
- def split(self, 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.
- """
- return self._table.splitOn(self.canv,availWidth, availHeight)
-
-
- def drawOn(self, 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.
- """
- self._table.drawOn(canvas, x, y, _sW)
-
-def makeTuple(x):
- if hasattr(x, '__iter__'):
- return tuple(x)
- return (x,)
-
-class SimpleIndex(IndexingFlowable):
- """Creates multi level indexes.
- The styling can be cutomized and alphabetic headers turned on and off.
- """
-
- def __init__(self, **kwargs):
- """
- Constructor of SimpleIndex.
- Accepts the same arguments as the setup method.
- """
- #keep stuff in a dictionary while building
- self._entries = {}
- self._lastEntries = {}
- self._flowable = None
- self.setup(**kwargs)
-
- def getFormatFunc(self,format):
- try:
- D = {}
- exec('from reportlab.lib.sequencer import _format_%s as formatFunc' % format, D)
- return D['formatFunc']
- except ImportError:
- raise ValueError('Unknown format %r' % format)
-
- def setup(self, 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:
-
-
-
- format can be 'I', 'i', '123', 'ABC', 'abc'
- """
-
- if style is None:
- style = ParagraphStyle(name='index',
- fontName=_baseFontName,
- fontSize=11)
- self.textStyle = style
- self.tableStyle = tableStyle or defaultTableStyle
- self.dot = dot
- self.headers = headers
- if name is None:
- from reportlab.platypus.paraparser import DEFAULT_INDEX_NAME as name
- self.name = name
- self.formatFunc = self.getFormatFunc(format)
- self.offset = offset
-
- def __call__(self,canv,kind,label):
- try:
- terms, format, offset = decode_label(label)
- except:
- terms = label
- format = offset = None
- if format is None:
- formatFunc = self.formatFunc
- else:
- formatFunc = self.getFormatFunc(format)
- if offset is None:
- offset = self.offset
-
- terms = commasplit(terms)
- cPN = canv.getPageNumber()
- pns = formatFunc(cPN-offset)
- key = 'ix_%s_%s_p_%s' % (self.name, label, pns)
-
- info = canv._curr_tx_info
- canv.bookmarkHorizontal(key, info['cur_x'], info['cur_y'] + info['leading'])
- self.addEntry(terms, (cPN,pns), key)
-
- def getCanvasMaker(self, canvasmaker=canvas.Canvas):
-
- def newcanvasmaker(*args, **kwargs):
- from reportlab.pdfgen import canvas
- c = canvasmaker(*args, **kwargs)
- setattr(c,self.name,self)
- return c
-
- return newcanvasmaker
-
- def isIndexing(self):
- return 1
-
- def isSatisfied(self):
- return (self._entries == self._lastEntries)
-
- def beforeBuild(self):
- # keep track of the last run
- self._lastEntries = self._entries.copy()
- self.clearEntries()
-
- def clearEntries(self):
- self._entries = {}
-
- def notify(self, kind, stuff):
- """The notification hook called to register all kinds of events.
-
- Here we are interested in 'IndexEntry' events only.
- """
- if kind == 'IndexEntry':
- text, pageNum = stuff
- self.addEntry(text, (self._canv.getPageNumber(),pageNum))
-
- def addEntry(self, text, pageNum, key=None):
- """Allows incremental buildup"""
- self._entries.setdefault(makeTuple(text),set([])).add((pageNum, key))
-
- def split(self, 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.
- """
- return self._flowable.splitOn(self.canv,availWidth, availHeight)
-
- def _getlastEntries(self, dummy=[(['Placeholder for index'],enumerate((None,)*3))]):
- '''Return the last run's entries! If there are none, returns dummy.'''
- if not self._lastEntries:
- if self._entries:
- return list(self._entries.items())
- return dummy
- return list(self._lastEntries.items())
-
- def _build(self,availWidth,availHeight):
- _tempEntries = self._getlastEntries()
- def getkey(seq):
- return [x.upper() for x in seq[0]]
- _tempEntries.sort(key=getkey)
- leveloffset = self.headers and 1 or 0
-
- def drawIndexEntryEnd(canvas, kind, label):
- '''Callback to draw dots and page numbers after each entry.'''
- style = self.getLevelStyle(leveloffset)
- pages = [(p[1],k) for p,k in sorted(decode_label(label))]
- drawPageNumbers(canvas, style, pages, availWidth, availHeight, self.dot)
- self.canv.drawIndexEntryEnd = drawIndexEntryEnd
-
- alpha = ''
- tableData = []
- lastTexts = []
- alphaStyle = self.getLevelStyle(0)
- for texts, pageNumbers in _tempEntries:
- texts = list(texts)
- #track when the first character changes; either output some extra
- #space, or the first letter on a row of its own. We cannot do
- #widow/orphan control, sadly.
- nalpha = texts[0][0].upper()
- if alpha != nalpha:
- alpha = nalpha
- if self.headers:
- header = alpha
- else:
- header = ' '
- tableData.append([Spacer(1, alphaStyle.spaceBefore),])
- tableData.append([Paragraph(header, alphaStyle),])
- tableData.append([Spacer(1, alphaStyle.spaceAfter),])
-
-
- i, diff = listdiff(lastTexts, texts)
- if diff:
- lastTexts = texts
- texts = texts[i:]
- label = encode_label(list(pageNumbers))
- texts[-1] = '%s' % (texts[-1], label)
- for text in texts:
- #Platypus and RML differ on how parsed XML attributes are escaped.
- #e.g. . The only place this seems to bite us is in
- #the index entries so work around it here.
- text = escapeOnce(text)
-
- style = self.getLevelStyle(i+leveloffset)
- para = Paragraph(text, style)
- if style.spaceBefore:
- tableData.append([Spacer(1, style.spaceBefore),])
- tableData.append([para,])
- i += 1
-
- self._flowable = Table(tableData, colWidths=[availWidth], style=self.tableStyle)
-
- def wrap(self, availWidth, availHeight):
- "All table properties should be known by now."
- self._build(availWidth,availHeight)
- self.width, self.height = self._flowable.wrapOn(self.canv,availWidth, availHeight)
- return self.width, self.height
-
- def drawOn(self, 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.
- """
- self._flowable.drawOn(canvas, x, y, _sW)
-
- def draw(self):
- t = self._flowable
- ocanv = getattr(t,'canv',None)
- if not ocanv:
- t.canv = self.canv
- try:
- t.draw()
- finally:
- if not ocanv:
- del t.canv
-
- def getLevelStyle(self, n):
- '''Returns the style for level n, generating and caching styles on demand if not present.'''
- if not hasattr(self.textStyle, '__iter__'):
- self.textStyle = [self.textStyle]
- try:
- return self.textStyle[n]
- except IndexError:
- self.textStyle = list(self.textStyle)
- prevstyle = self.getLevelStyle(n-1)
- self.textStyle.append(ParagraphStyle(
- name='%s-%d-indented' % (prevstyle.name, n),
- parent=prevstyle,
- firstLineIndent = prevstyle.firstLineIndent+.2*cm,
- leftIndent = prevstyle.leftIndent+.2*cm))
- return self.textStyle[n]
-
-AlphabeticIndex = SimpleIndex
-
-def listdiff(l1, l2):
- m = min(len(l1), len(l2))
- for i in range(m):
- if l1[i] != l2[i]:
- return i, l2[i:]
- return m, l2[m:]
-
-class ReferenceText(IndexingFlowable):
- """Fakery to illustrate how a reference would work if we could
- put it in a paragraph."""
- def __init__(self, textPattern, targetKey):
- self.textPattern = textPattern
- self.target = targetKey
- self.paraStyle = ParagraphStyle('tmp')
- self._lastPageNum = None
- self._pageNum = -999
- self._para = None
-
- def beforeBuild(self):
- self._lastPageNum = self._pageNum
-
- def notify(self, kind, stuff):
- if kind == 'Target':
- (key, pageNum) = stuff
- if key == self.target:
- self._pageNum = pageNum
-
- def wrap(self, availWidth, availHeight):
- text = self.textPattern % self._lastPageNum
- self._para = Paragraph(text, self.paraStyle)
- return self._para.wrap(availWidth, availHeight)
-
- def drawOn(self, canvas, x, y, _sW=0):
- self._para.drawOn(canvas, x, y, _sW)
diff --git a/reportlab/platypus/tables.py b/reportlab/platypus/tables.py
deleted file mode 100644
index 3f3529cb..00000000
--- a/reportlab/platypus/tables.py
+++ /dev/null
@@ -1,1612 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/tables.py
-__version__=''' $Id$ '''
-
-__doc__="""
-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.
-"""
-from reportlab.platypus.flowables import Flowable, Preformatted, Spacer
-from reportlab import rl_config
-from reportlab.lib.styles import PropertySet, ParagraphStyle, _baseFontName
-from reportlab.lib import colors
-from reportlab.lib.utils import annotateException, IdentStr, flatten, isStr, asNative, strTypes
-from reportlab.lib.rl_accel import fp_str
-from reportlab.lib.abag import ABag as CellFrame
-from reportlab.pdfbase.pdfmetrics import stringWidth
-from reportlab.platypus.doctemplate import Indenter
-from reportlab.platypus.flowables import LIIndenter
-
-LINECAPS={None: None, 'butt':0,'round':1,'projecting':2,'squared':2}
-LINEJOINS={None: None, 'miter':0, 'mitre':0, 'round':1,'bevel':2}
-
-class CellStyle(PropertySet):
- fontname = _baseFontName
- fontsize = 10
- leading = 12
- leftPadding = 6
- rightPadding = 6
- topPadding = 3
- bottomPadding = 3
- firstLineIndent = 0
- color = 'black'
- alignment = 'LEFT'
- background = 'white'
- valign = "BOTTOM"
- href = None
- destination = None
- def __init__(self, name, parent=None):
- self.name = name
- if parent is not None:
- parent.copy(self)
- def copy(self, result=None):
- if result is None:
- result = CellStyle()
- for name in dir(self):
- setattr(result, name, getattr(self, name))
- return result
-
-class TableStyle:
- def __init__(self, cmds=None, parent=None, **kw):
- #handle inheritance from parent first.
- commands = []
- if parent:
- # copy the parents list at construction time
- commands = commands + parent.getCommands()
- self._opts = parent._opts
- for a in ('spaceBefore','spaceAfter'):
- if hasattr(parent,a):
- setattr(self,a,getattr(parent,a))
- if cmds:
- commands = commands + list(cmds)
- self._cmds = commands
- self._opts={}
- self._opts.update(kw)
-
- def add(self, *cmd):
- self._cmds.append(cmd)
- def __repr__(self):
- return "TableStyle(\n%s\n) # end TableStyle" % " \n".join(map(repr, self._cmds))
- def getCommands(self):
- return self._cmds
-
-def _rowLen(x):
- return not isinstance(x,(tuple,list)) and 1 or len(x)
-
-def _calc_pc(V,avail):
- '''check list V for percentage or * values
- 1) absolute values go through unchanged
- 2) percentages are used as weights for unconsumed space
- 3) if no None values were seen '*' weights are
- set equally with unclaimed space
- otherwise * weights are assigned as None'''
- R = []
- r = R.append
- I = []
- i = I.append
- J = []
- j = J.append
- s = avail
- w = n = 0.
- for v in V:
- if isinstance(v,strTypes):
- v = str(v).strip()
- if not v:
- v = None
- n += 1
- elif v.endswith('%'):
- v = float(v[:-1])
- w += v
- i(len(R))
- elif v=='*':
- j(len(R))
- else:
- v = float(v)
- s -= v
- elif v is None:
- n += 1
- else:
- s -= v
- r(v)
- s = max(0.,s)
- f = s/max(100.,w)
- for i in I:
- R[i] *= f
- s -= R[i]
- s = max(0.,s)
- m = len(J)
- if m:
- v = n==0 and s/m or None
- for j in J:
- R[j] = v
- return R
-
-def _hLine(canvLine, scp, ecp, y, hBlocks, FUZZ=rl_config._FUZZ):
- '''
- Draw horizontal lines; do not draw through regions specified in hBlocks
- This also serves for vertical lines with a suitable canvLine
- '''
- if hBlocks: hBlocks = hBlocks.get(y,None)
- if not hBlocks or scp>=hBlocks[-1][1]-FUZZ or ecp<=hBlocks[0][0]+FUZZ:
- canvLine(scp,y,ecp,y)
- else:
- i = 0
- n = len(hBlocks)
- while scp=ecp-FUZZ:
- i += 1
- continue
- i0 = max(scp,x0)
- i1 = min(ecp,x1)
- if i0>scp: canvLine(scp,y,i0,y)
- scp = i1
- if scp=lim: continue
- x1 += 1
- t = sum([V[x]+M.get(x,0) for x in xrange(x0,x1)])
- if t>=v-FUZZ: continue #already good enough
- X = [x for x in xrange(x0,x1) if V0[x] is None] #variable candidates
- if not X: continue #something wrong here mate
- v -= t
- v /= float(len(X))
- for x in X:
- M[x] = M.get(x,0)+v
- for x,v in M.items():
- V[x] += v
-
-class _ExpandedCellTuple(tuple):
- pass
-
-class Table(Flowable):
- def __init__(self, data, colWidths=None, rowHeights=None, style=None,
- repeatRows=0, repeatCols=0, splitByRow=1, emptyTableAction=None, ident=None,
- hAlign=None,vAlign=None, normalizedData=0, cellStyles=None):
- self.ident = ident
- self.hAlign = hAlign or 'CENTER'
- self.vAlign = vAlign or 'MIDDLE'
- if not isinstance(data,(tuple,list)):
- raise ValueError("%s invalid data type" % self.identity())
- self._nrows = nrows = len(data)
- self._cellvalues = []
- _seqCW = isinstance(colWidths,(tuple,list))
- _seqRH = isinstance(rowHeights,(tuple,list))
- if nrows: self._ncols = ncols = max(list(map(_rowLen,data)))
- elif colWidths and _seqCW: ncols = len(colWidths)
- else: ncols = 0
- if not emptyTableAction: emptyTableAction = rl_config.emptyTableAction
- self._longTableOptimize = getattr(self,'_longTableOptimize',rl_config.longTableOptimize)
- if not (nrows and ncols):
- if emptyTableAction=='error':
- raise ValueError("%s must have at least a row and column" % self.identity())
- elif emptyTableAction=='indicate':
- self.__class__ = Preformatted
- global _emptyTableStyle
- if '_emptyTableStyle' not in list(globals().keys()):
- _emptyTableStyle = ParagraphStyle('_emptyTableStyle')
- _emptyTableStyle.textColor = colors.red
- _emptyTableStyle.backColor = colors.yellow
- Preformatted.__init__(self,'%s(%d,%d)' % (self.__class__.__name__,nrows,ncols), _emptyTableStyle)
- elif emptyTableAction=='ignore':
- self.__class__ = Spacer
- Spacer.__init__(self,0,0)
- else:
- raise ValueError('%s bad emptyTableAction: "%s"' % (self.identity(),emptyTableAction))
- return
-
- # we need a cleanup pass to ensure data is strings - non-unicode and non-null
- if normalizedData:
- self._cellvalues = data
- else:
- self._cellvalues = data = self.normalizeData(data)
- if not _seqCW: colWidths = ncols*[colWidths]
- elif len(colWidths)!=ncols:
- if rl_config.allowShortTableRows and isinstance(colWidths,list):
- n = len(colWidths)
- if n...':
- break
- if r and r[-4:]!='>...':
- ix, jx, vx, b = i, j, r, 1
- else:
- v = v is None and '' or str(v)
- ix, jx, vx = i, j, v
- b = (vx and isinstance(v,strTypes)) and 1 or 0
- if maxLen: vx = vx[:maxLen]
- if b: break
- if b: break
- if rh: #find tallest row, it's of great interest'
- tallest = '(tallest row %d)' % int(max(rh))
- else:
- tallest = ''
- if vx:
- vx = ' with cell(%d,%d) containing\n%s' % (ix,jx,repr(vx))
- else:
- vx = '...'
-
- return "<%s@0x%8.8X %s rows x %s cols%s>%s" % (self.__class__.__name__, id(self), nr, nc, tallest, vx)
-
- def _cellListIter(self,C,aW,aH):
- canv = getattr(self,'canv',None)
- for c in C:
- if getattr(c,'__split_only__',None):
- for d in c.splitOn(canv,aW,aH):
- yield d
- else:
- yield c
-
- def _cellListProcess(self,C,aW,aH):
- if not isinstance(C,_ExpandedCellTuple):
- frame = None
- R = [].append
- for c in self._cellListIter(C,aW,aH):
- if isinstance(c,Indenter):
- if not frame:
- frame = CellFrame(_leftExtraIndent=0,_rightExtraIndent=0)
- c.frameAction(frame)
- if frame._leftExtraIndent<1e-8 and frame._rightExtraIndent<1e-8:
- frame = None
- continue
- if frame:
- R(LIIndenter(c,leftIndent=frame._leftExtraIndent,rightIndent=frame._rightExtraIndent))
- else:
- R(c)
- C = _ExpandedCellTuple(R.__self__)
- return C
-
- def _listCellGeom(self, V,w,s,W=None,H=None,aH=72000):
- if not V: return 0,0
- aW = w - s.leftPadding - s.rightPadding
- aH = aH - s.topPadding - s.bottomPadding
- t = 0
- w = 0
- canv = getattr(self,'canv',None)
- sb0 = None
- for v in V:
- vw, vh = v.wrapOn(canv, aW, aH)
- sb = v.getSpaceBefore()
- sa = v.getSpaceAfter()
- if W is not None: W.append(vw)
- if H is not None: H.append(vh)
- w = max(w,vw)
- t += vh + sa + sb
- if sb0 is None:
- sb0 = sb
- return w, t - sb0 - sa
-
- def _listValueWidth(self,V,aH=72000,aW=72000):
- if not V: return 0,0
- t = 0
- w = 0
- canv = getattr(self,'canv',None)
- return max([v.wrapOn(canv,aW,aH)[0] for v in V])
-
- def _calc_width(self,availWidth,W=None):
- if getattr(self,'_width_calculated_once',None): return
- #comments added by Andy to Robin's slightly terse variable names
- if not W: W = _calc_pc(self._argW,availWidth) #widths array
- if None in W: #some column widths are not given
- canv = getattr(self,'canv',None)
- saved = None
- if self._spanCmds:
- colSpanCells = self._colSpanCells
- spanRanges = self._spanRanges
- else:
- colSpanCells = ()
- spanRanges = {}
- spanCons = {}
- if W is self._argW:
- W0 = W
- W = W[:]
- else:
- W0 = W[:]
- V = self._cellvalues
- S = self._cellStyles
- while None in W:
- j = W.index(None) #find first unspecified column
- w = 0
- for i,Vi in enumerate(V):
- v = Vi[j]
- s = S[i][j]
- ji = j,i
- span = spanRanges.get(ji,None)
- if ji in colSpanCells and not span: #if the current cell is part of a spanned region,
- t = 0.0 #assume a zero size.
- else:#work out size
- t = self._elementWidth(v,s)
- if t is None:
- raise ValueError("Flowable %s in cell(%d,%d) can't have auto width\n%s" % (v.identity(30),i,j,self.identity(30)))
- t += s.leftPadding+s.rightPadding
- if span:
- c0 = span[0]
- c1 = span[2]
- if c0!=c1:
- x = c0,c1
- spanCons[x] = max(spanCons.get(x,t),t)
- t = 0
- if t>w: w = t #record a new maximum
-
- W[j] = w
-
- if spanCons:
- try:
- spanFixDim(W0,W,spanCons)
- except:
- annotateException('\nspanning problem in %s\nW0=%r W=%r\nspanCons=%r' % (self.identity(),W0,W,spanCons))
-
- self._colWidths = W
- width = 0
- self._colpositions = [0] #index -1 is right side boundary; we skip when processing cells
- for w in W:
- width = width + w
- self._colpositions.append(width)
-
- self._width = width
- self._width_calculated_once = 1
-
- def _elementWidth(self,v,s):
- if isinstance(v,(list,tuple)):
- w = 0
- for e in v:
- ew = self._elementWidth(e,s)
- if ew is None: return None
- w = max(w,ew)
- return w
- elif isinstance(v,Flowable) and v._fixedWidth:
- if hasattr(v, 'width') and isinstance(v.width,(int,float)): return v.width
- if hasattr(v, 'drawWidth') and isinstance(v.drawWidth,(int,float)): return v.drawWidth
- # Even if something is fixedWidth, the attribute to check is not
- # necessarily consistent (cf. Image.drawWidth). Therefore, we'll
- # be extra-careful and fall through to this code if necessary.
- if hasattr(v, 'minWidth'):
- try:
- w = v.minWidth() # should be all flowables
- if isinstance(w,(float,int)): return w
- except AttributeError:
- pass
- if v is None:
- return 0
- else:
- try:
- v = str(v).split("\n")
- except:
- return 0
- fontName = s.fontname
- fontSize = s.fontsize
- return max([stringWidth(x,fontName,fontSize) for x in v])
-
- def _calc_height(self, availHeight, availWidth, H=None, W=None):
- H = self._argH
- if not W: W = _calc_pc(self._argW,availWidth) #widths array
-
- hmax = lim = len(H)
- longTable = self._longTableOptimize
-
- if None in H:
- canv = getattr(self,'canv',None)
- saved = None
- #get a handy list of any cells which span rows. should be ignored for sizing
- if self._spanCmds:
- rowSpanCells = self._rowSpanCells
- colSpanCells = self._colSpanCells
- spanRanges = self._spanRanges
- colpositions = self._colpositions
- else:
- rowSpanCells = colSpanCells = ()
- spanRanges = {}
- if canv: saved = canv._fontname, canv._fontsize, canv._leading
- H0 = H
- H = H[:] #make a copy as we'll change it
- self._rowHeights = H
- spanCons = {}
- FUZZ = rl_config._FUZZ
- while None in H:
- i = H.index(None)
- V = self._cellvalues[i] # values for row i
- S = self._cellStyles[i] # styles for row i
- h = 0
- j = 0
- for j,(v, s, w) in enumerate(list(zip(V, S, W))): # value, style, width (lengths must match)
- ji = j,i
- span = spanRanges.get(ji,None)
- if ji in rowSpanCells and not span:
- continue # don't count it, it's either occluded or unreliable
- else:
- if isinstance(v,(tuple,list,Flowable)):
- if isinstance(v,Flowable): v = (v,)
- else: v = flatten(v)
- v = V[j] = self._cellListProcess(v,w,None)
- if w is None and not self._canGetWidth(v):
- raise ValueError("Flowable %s in cell(%d,%d) can't have auto width in\n%s" % (v[0].identity(30),i,j,self.identity(30)))
- if canv: canv._fontname, canv._fontsize, canv._leading = s.fontname, s.fontsize, s.leading or 1.2*s.fontsize
- if ji in colSpanCells:
- if not span: continue
- w = max(colpositions[span[2]+1]-colpositions[span[0]],w)
- dW,t = self._listCellGeom(v,w or self._listValueWidth(v),s)
- if canv: canv._fontname, canv._fontsize, canv._leading = saved
- dW = dW + s.leftPadding + s.rightPadding
- if not rl_config.allowTableBoundsErrors and dW>w:
- from reportlab.platypus.doctemplate import LayoutError
- raise LayoutError("Flowable %s (%sx%s points) too wide for cell(%d,%d) (%sx* points) in\n%s" % (v[0].identity(30),fp_str(dW),fp_str(t),i,j, fp_str(w), self.identity(30)))
- else:
- v = (v is not None and str(v) or '').split("\n")
- t = (s.leading or 1.2*s.fontsize)*len(v)
- t += s.bottomPadding+s.topPadding
- if span:
- r0 = span[1]
- r1 = span[3]
- if r0!=r1:
- x = r0,r1
- spanCons[x] = max(spanCons.get(x,t),t)
- t = 0
- if t>h: h = t #record a new maximum
- H[i] = h
- # we can stop if we have filled up all available room
- if longTable:
- hmax = i
- height = sum(H[:i])
- if height > availHeight:
- #we can terminate if all spans are complete in H[:i]
- if spanCons:
- msr = max([x[1] for x in spanCons.keys()]) #RS=[endrowspan,.....]
- if hmax>=msr:
- break
- if None not in H: hmax = lim
-
- if spanCons:
- try:
- spanFixDim(H0,H,spanCons,lim=hmax)
- except:
- annotateException('\nspanning problem in %s hmax=%s lim=%s avail=%s x %s\nH0=%r H=%r\nspanCons=%r' % (self.identity(),hmax,lim,availWidth,availHeight,H0,H,spanCons))
-
- height = self._height = sum(H[:hmax])
- self._rowpositions = [height] # index 0 is actually topline; we skip when processing cells
- for h in H[:hmax]:
- height -= h
- self._rowpositions.append(height)
- assert abs(height)<1e-8, '!!!!!%s\ninternal height error height=%r hmax=%d Sum(H[:%d])=%r\nH=%r\nrowPositions=%r' % (self.identity(),height,hmax,hmax,self._height,H[:hmax],self._rowpositions)
- self._hmax = hmax
-
- def _calc(self, availWidth, availHeight):
- #if hasattr(self,'_width'): return
-
- #in some cases there are unsizable things in
- #cells. If so, apply a different algorithm
- #and assign some withs in a less (thanks to Gary Poster) dumb way.
- #this CHANGES the widths array.
- if (None in self._colWidths or '*' in self._colWidths) and self._hasVariWidthElements():
- W = self._calcPreliminaryWidths(availWidth) #widths
- else:
- W = None
-
- # need to know which cells are part of spanned
- # ranges, so _calc_height and _calc_width can ignore them
- # in sizing
- if self._spanCmds:
- self._calcSpanRanges()
- if None in self._argH:
- self._calc_width(availWidth,W=W)
-
- if self._nosplitCmds:
- self._calcNoSplitRanges()
-
- # calculate the full table height
- self._calc_height(availHeight,availWidth,W=W)
-
- # calculate the full table width
- self._calc_width(availWidth,W=W)
-
- if self._spanCmds:
- #now work out the actual rect for each spanned cell from the underlying grid
- self._calcSpanRects()
-
- def _culprit(self):
- """Return a string describing the tallest element.
-
- Usually this is what causes tables to fail to split. Currently
- tables are the only items to have a '_culprit' method. Doctemplate
- checks for it.
- """
- rh = self._rowHeights
- tallest = max(rh)
- rowNum = rh.index(tallest)
- #rowNum of limited interest as usually it's a split one
- #and we see row #1. Text might be a nice addition.
-
- return 'tallest cell %0.1f points' % tallest
-
-
-
- def _hasVariWidthElements(self, upToRow=None):
- """Check for flowables in table cells and warn up front.
-
- Allow a couple which we know are fixed size such as
- images and graphics."""
- if upToRow is None: upToRow = self._nrows
- for row in xrange(min(self._nrows, upToRow)):
- for col in xrange(self._ncols):
- value = self._cellvalues[row][col]
- if not self._canGetWidth(value):
- return 1
- return 0
-
- def _canGetWidth(self, thing):
- "Can we work out the width quickly?"
- if isinstance(thing,(list, tuple)):
- for elem in thing:
- if not self._canGetWidth(elem):
- return 0
- return 1
- elif isinstance(thing, Flowable):
- return thing._fixedWidth # must loosen this up
- else: #str, number, None etc.
- #anything else gets passed to str(...)
- # so should be sizable
- return 1
-
- def _calcPreliminaryWidths(self, availWidth):
- """Fallback algorithm for when main one fails.
-
- Where exact width info not given but things like
- paragraphs might be present, do a preliminary scan
- and assign some best-guess values."""
-
- W = list(self._argW) # _calc_pc(self._argW,availWidth)
- verbose = 0
- totalDefined = 0.0
- percentDefined = 0
- percentTotal = 0
- numberUndefined = 0
- numberGreedyUndefined = 0
- for w in W:
- if w is None:
- numberUndefined += 1
- elif w == '*':
- numberUndefined += 1
- numberGreedyUndefined += 1
- elif _endswith(w,'%'):
- percentDefined += 1
- percentTotal += float(w[:-1])
- else:
- assert isinstance(w,(int,float))
- totalDefined = totalDefined + w
- if verbose: print('prelim width calculation. %d columns, %d undefined width, %0.2f units remain' % (
- self._ncols, numberUndefined, availWidth - totalDefined))
-
- #check columnwise in each None column to see if they are sizable.
- given = []
- sizeable = []
- unsizeable = []
- minimums = {}
- totalMinimum = 0
- elementWidth = self._elementWidth
- for colNo in xrange(self._ncols):
- w = W[colNo]
- if w is None or w=='*' or _endswith(w,'%'):
- siz = 1
- final = 0
- for rowNo in xrange(self._nrows):
- value = self._cellvalues[rowNo][colNo]
- style = self._cellStyles[rowNo][colNo]
- pad = style.leftPadding+style.rightPadding
- new = elementWidth(value,style)
- if new:
- new += pad
- else:
- new = pad
- new += style.leftPadding+style.rightPadding
- final = max(final, new)
- siz = siz and self._canGetWidth(value) # irrelevant now?
- if siz:
- sizeable.append(colNo)
- else:
- unsizeable.append(colNo)
- minimums[colNo] = final
- totalMinimum += final
- else:
- given.append(colNo)
- if len(given) == self._ncols:
- return
- if verbose: print('predefined width: ',given)
- if verbose: print('uncomputable width: ',unsizeable)
- if verbose: print('computable width: ',sizeable)
-
- # how much width is left:
- remaining = availWidth - (totalMinimum + totalDefined)
- if remaining > 0:
- # we have some room left; fill it.
- definedPercentage = (totalDefined/availWidth)*100
- percentTotal += definedPercentage
- if numberUndefined and percentTotal < 100:
- undefined = numberGreedyUndefined or numberUndefined
- defaultWeight = (100-percentTotal)/undefined
- percentTotal = 100
- defaultDesired = (defaultWeight/percentTotal)*availWidth
- else:
- defaultWeight = defaultDesired = 1
- # we now calculate how wide each column wanted to be, and then
- # proportionately shrink that down to fit the remaining available
- # space. A column may not shrink less than its minimum width,
- # however, which makes this a bit more complicated.
- desiredWidths = []
- totalDesired = 0
- effectiveRemaining = remaining
- for colNo, minimum in minimums.items():
- w = W[colNo]
- if _endswith(w,'%'):
- desired = (float(w[:-1])/percentTotal)*availWidth
- elif w == '*':
- desired = defaultDesired
- else:
- desired = not numberGreedyUndefined and defaultDesired or 1
- if desired <= minimum:
- W[colNo] = minimum
- else:
- desiredWidths.append(
- (desired-minimum, minimum, desired, colNo))
- totalDesired += desired
- effectiveRemaining += minimum
- if desiredWidths: # else we're done
- # let's say we have two variable columns. One wanted
- # 88 points, and one wanted 264 points. The first has a
- # minWidth of 66, and the second of 55. We have 71 points
- # to divide up in addition to the totalMinimum (i.e.,
- # remaining==71). Our algorithm tries to keep the proportion
- # of these variable columns.
- #
- # To do this, we add up the minimum widths of the variable
- # columns and the remaining width. That's 192. We add up the
- # totalDesired width. That's 352. That means we'll try to
- # shrink the widths by a proportion of 192/352--.545454.
- # That would make the first column 48 points, and the second
- # 144 points--adding up to the desired 192.
- #
- # Unfortunately, that's too small for the first column. It
- # must be 66 points. Therefore, we go ahead and save that
- # column width as 88 points. That leaves (192-88==) 104
- # points remaining. The proportion to shrink the remaining
- # column is (104/264), which, multiplied by the desired
- # width of 264, is 104: the amount assigned to the remaining
- # column.
- proportion = effectiveRemaining/totalDesired
- # we sort the desired widths by difference between desired and
- # and minimum values, a value called "disappointment" in the
- # code. This means that the columns with a bigger
- # disappointment will have a better chance of getting more of
- # the available space.
- desiredWidths.sort()
- finalSet = []
- for disappointment, minimum, desired, colNo in desiredWidths:
- adjusted = proportion * desired
- if adjusted < minimum:
- W[colNo] = minimum
- totalDesired -= desired
- effectiveRemaining -= minimum
- if totalDesired:
- proportion = effectiveRemaining/totalDesired
- else:
- finalSet.append((minimum, desired, colNo))
- for minimum, desired, colNo in finalSet:
- adjusted = proportion * desired
- assert adjusted >= minimum
- W[colNo] = adjusted
- else:
- for colNo, minimum in minimums.items():
- W[colNo] = minimum
- if verbose: print('new widths are:', W)
- self._argW = self._colWidths = W
- return W
-
- def minWidth(self):
- W = list(self._argW)
- width = 0
- elementWidth = self._elementWidth
- rowNos = xrange(self._nrows)
- values = self._cellvalues
- styles = self._cellStyles
- for colNo in xrange(len(W)):
- w = W[colNo]
- if w is None or w=='*' or _endswith(w,'%'):
- final = 0
- for rowNo in rowNos:
- value = values[rowNo][colNo]
- style = styles[rowNo][colNo]
- new = (elementWidth(value,style)+
- style.leftPadding+style.rightPadding)
- final = max(final, new)
- width += final
- else:
- width += float(w)
- return width # XXX + 1/2*(left and right border widths)
-
- def _calcSpanRanges(self):
- """Work out rects for tables which do row and column spanning.
-
- This creates some mappings to let the later code determine
- if a cell is part of a "spanned" range.
- self._spanRanges shows the 'coords' in integers of each
- 'cell range', or None if it was clobbered:
- (col, row) -> (col0, row0, col1, row1)
-
- Any cell not in the key is not part of a spanned region
- """
- self._spanRanges = spanRanges = {}
- for x in xrange(self._ncols):
- for y in xrange(self._nrows):
- spanRanges[x,y] = (x, y, x, y)
- self._colSpanCells = []
- self._rowSpanCells = []
- csa = self._colSpanCells.append
- rsa = self._rowSpanCells.append
- for (cmd, start, stop) in self._spanCmds:
- x0, y0 = start
- x1, y1 = stop
-
- #normalize
- if x0 < 0: x0 = x0 + self._ncols
- if x1 < 0: x1 = x1 + self._ncols
- if y0 < 0: y0 = y0 + self._nrows
- if y1 < 0: y1 = y1 + self._nrows
- if x0 > x1: x0, x1 = x1, x0
- if y0 > y1: y0, y1 = y1, y0
-
- if x0!=x1 or y0!=y1:
- if x0!=x1: #column span
- for y in xrange(y0, y1+1):
- for x in xrange(x0,x1+1):
- csa((x,y))
- if y0!=y1: #row span
- for y in xrange(y0, y1+1):
- for x in xrange(x0,x1+1):
- rsa((x,y))
-
- for y in xrange(y0, y1+1):
- for x in xrange(x0,x1+1):
- spanRanges[x,y] = None
- # set the main entry
- spanRanges[x0,y0] = (x0, y0, x1, y1)
-
- def _calcNoSplitRanges(self):
- """
- This creates some mappings to let the later code determine
- if a cell is part of a "nosplit" range.
- self._nosplitRanges shows the 'coords' in integers of each
- 'cell range', or None if it was clobbered:
- (col, row) -> (col0, row0, col1, row1)
-
- Any cell not in the key is not part of a spanned region
- """
- self._nosplitRanges = nosplitRanges = {}
- for x in xrange(self._ncols):
- for y in xrange(self._nrows):
- nosplitRanges[x,y] = (x, y, x, y)
- self._colNoSplitCells = []
- self._rowNoSplitCells = []
- csa = self._colNoSplitCells.append
- rsa = self._rowNoSplitCells.append
- for (cmd, start, stop) in self._nosplitCmds:
- x0, y0 = start
- x1, y1 = stop
-
- #normalize
- if x0 < 0: x0 = x0 + self._ncols
- if x1 < 0: x1 = x1 + self._ncols
- if y0 < 0: y0 = y0 + self._nrows
- if y1 < 0: y1 = y1 + self._nrows
- if x0 > x1: x0, x1 = x1, x0
- if y0 > y1: y0, y1 = y1, y0
-
- if x0!=x1 or y0!=y1:
- #column span
- if x0!=x1:
- for y in xrange(y0, y1+1):
- for x in xrange(x0,x1+1):
- csa((x,y))
- #row span
- if y0!=y1:
- for y in xrange(y0, y1+1):
- for x in xrange(x0,x1+1):
- rsa((x,y))
-
- for y in xrange(y0, y1+1):
- for x in xrange(x0,x1+1):
- nosplitRanges[x,y] = None
- # set the main entry
- nosplitRanges[x0,y0] = (x0, y0, x1, y1)
-
- def _calcSpanRects(self):
- """Work out rects for tables which do row and column spanning.
-
- Based on self._spanRanges, which is already known,
- and the widths which were given or previously calculated,
- self._spanRects shows the real coords for drawing:
-
- (col, row) -> (x, y, width, height)
-
- for each cell. Any cell which 'does not exist' as another
- has spanned over it will get a None entry on the right
- """
- spanRects = getattr(self,'_spanRects',{})
- hmax = getattr(self,'_hmax',None)
- longTable = self._longTableOptimize
- if spanRects and (longTable and hmax==self._hmax_spanRects or not longTable):
- return
- colpositions = self._colpositions
- rowpositions = self._rowpositions
- vBlocks = {}
- hBlocks = {}
- rlim = len(rowpositions)-1
- for (coord, value) in self._spanRanges.items():
- if value is None:
- spanRects[coord] = None
- else:
- col0, row0, col1, row1 = value
- if row1>=rlim: continue
- col,row = coord
- if col1-col0>0:
- for _ in xrange(col0+1,col1+1):
- vBlocks.setdefault(colpositions[_],[]).append((rowpositions[row1+1],rowpositions[row0]))
- if row1-row0>0:
- for _ in xrange(row0+1,row1+1):
- hBlocks.setdefault(rowpositions[_],[]).append((colpositions[col0],colpositions[col1+1]))
- x = colpositions[col0]
- y = rowpositions[row1+1]
- width = colpositions[col1+1] - x
- height = rowpositions[row0] - y
- spanRects[coord] = (x, y, width, height)
-
- for _ in hBlocks, vBlocks:
- for value in _.values():
- value.sort()
- self._spanRects = spanRects
- self._vBlocks = vBlocks
- self._hBlocks = hBlocks
- self._hmax_spanRects = hmax
-
- def setStyle(self, tblstyle):
- if not isinstance(tblstyle,TableStyle):
- tblstyle = TableStyle(tblstyle)
- for cmd in tblstyle.getCommands():
- self._addCommand(cmd)
- for k,v in tblstyle._opts.items():
- setattr(self,k,v)
- for a in ('spaceBefore','spaceAfter'):
- if not hasattr(self,a) and hasattr(tblstyle,a):
- setattr(self,a,getattr(tblstyle,a))
-
- def _addCommand(self,cmd):
- if cmd[0] in ('BACKGROUND','ROWBACKGROUNDS','COLBACKGROUNDS'):
- self._bkgrndcmds.append(cmd)
- elif cmd[0] == 'SPAN':
- self._spanCmds.append(cmd)
- elif cmd[0] == 'NOSPLIT':
- # we expect op, start, stop
- self._nosplitCmds.append(cmd)
- elif _isLineCommand(cmd):
- # we expect op, start, stop, weight, colour, cap, dashes, join
- cmd = list(cmd)
- if len(cmd)<5: raise ValueError('bad line command '+ascii(cmd))
-
- #determine line cap value at position 5. This can be str or numeric.
- if len(cmd)<6:
- cmd.append(1)
- else:
- cap = _convert2int(cmd[5], LINECAPS, 0, 2, 'cap', cmd)
- cmd[5] = cap
-
- #dashes at index 6 - this is a dash array:
- if len(cmd)<7: cmd.append(None)
-
- #join mode at index 7 - can be str or numeric, look up as for caps
- if len(cmd)<8: cmd.append(1)
- else:
- join = _convert2int(cmd[7], LINEJOINS, 0, 2, 'join', cmd)
- cmd[7] = join
-
- #linecount at index 8. Default is 1, set to 2 for double line.
- if len(cmd)<9: cmd.append(1)
- else:
- lineCount = cmd[8]
- if lineCount is None:
- lineCount = 1
- cmd[8] = lineCount
- assert lineCount >= 1
- #linespacing at index 9. Not applicable unless 2+ lines, defaults to line
- #width so you get a visible gap between centres
- if len(cmd)<10: cmd.append(cmd[3])
- else:
- space = cmd[9]
- if space is None:
- space = cmd[3]
- cmd[9] = space
- assert len(cmd) == 10
-
- self._linecmds.append(tuple(cmd))
- else:
- (op, (sc, sr), (ec, er)), values = cmd[:3] , cmd[3:]
- if sc < 0: sc = sc + self._ncols
- if ec < 0: ec = ec + self._ncols
- if sr < 0: sr = sr + self._nrows
- if er < 0: er = er + self._nrows
- for i in xrange(sr, er+1):
- for j in xrange(sc, ec+1):
- _setCellStyle(self._cellStyles, i, j, op, values)
-
- def _drawLines(self):
- ccap, cdash, cjoin = None, None, None
- self.canv.saveState()
- for op, (sc,sr), (ec,er), weight, color, cap, dash, join, count, space in self._linecmds:
- if isinstance(sr,strTypes) and sr.startswith('split'): continue
- if sc < 0: sc = sc + self._ncols
- if ec < 0: ec = ec + self._ncols
- if sr < 0: sr = sr + self._nrows
- if er < 0: er = er + self._nrows
- if cap!=None and ccap!=cap:
- self.canv.setLineCap(cap)
- ccap = cap
- if dash is None or dash == []:
- if cdash is not None:
- self.canv.setDash()
- cdash = None
- elif dash != cdash:
- self.canv.setDash(dash)
- cdash = dash
- if join is not None and cjoin!=join:
- self.canv.setLineJoin(join)
- cjoin = join
- getattr(self,_LineOpMap.get(op, '_drawUnknown' ))( (sc, sr), (ec, er), weight, color, count, space)
- self.canv.restoreState()
- self._curcolor = None
-
- def _drawUnknown(self, start, end, weight, color, count, space):
- #we are only called from _drawLines which is one level up
- import sys
- op = sys._getframe(1).f_locals['op']
- raise ValueError("Unknown line command '%s'" % op)
-
- def _drawGrid(self, start, end, weight, color, count, space):
- self._drawBox( start, end, weight, color, count, space)
- self._drawInnerGrid( start, end, weight, color, count, space)
-
- def _drawBox(self, start, end, weight, color, count, space):
- sc,sr = start
- ec,er = end
- self._drawHLines((sc, sr), (ec, sr), weight, color, count, space)
- self._drawHLines((sc, er+1), (ec, er+1), weight, color, count, space)
- self._drawVLines((sc, sr), (sc, er), weight, color, count, space)
- self._drawVLines((ec+1, sr), (ec+1, er), weight, color, count, space)
-
- def _drawInnerGrid(self, start, end, weight, color, count, space):
- sc,sr = start
- ec,er = end
- self._drawHLines((sc, sr+1), (ec, er), weight, color, count, space)
- self._drawVLines((sc+1, sr), (ec, er), weight, color, count, space)
-
- def _prepLine(self, weight, color):
- if color != self._curcolor:
- self.canv.setStrokeColor(color)
- self._curcolor = color
- if weight != self._curweight:
- self.canv.setLineWidth(weight)
- self._curweight = weight
-
- def _drawHLines(self, start, end, weight, color, count, space):
- sc,sr = start
- ec,er = end
- ecp = self._colpositions[sc:ec+2]
- rp = self._rowpositions[sr:er+1]
- if len(ecp)<=1 or len(rp)<1: return
- self._prepLine(weight, color)
- scp = ecp[0]
- ecp = ecp[-1]
- hBlocks = getattr(self,'_hBlocks',{})
- canvLine = self.canv.line
- if count == 1:
- for y in rp:
- _hLine(canvLine, scp, ecp, y, hBlocks)
- else:
- lf = lambda x0,y0,x1,y1,canvLine=canvLine, ws=weight+space, count=count: _multiLine(x0,x1,y0,canvLine,ws,count)
- for y in rp:
- _hLine(lf, scp, ecp, y, hBlocks)
-
- def _drawHLinesB(self, start, end, weight, color, count, space):
- sc,sr = start
- ec,er = end
- self._drawHLines((sc, sr+1), (ec, er+1), weight, color, count, space)
-
- def _drawVLines(self, start, end, weight, color, count, space):
- sc,sr = start
- ec,er = end
- erp = self._rowpositions[sr:er+2]
- cp = self._colpositions[sc:ec+1]
- if len(erp)<=1 or len(cp)<1: return
- self._prepLine(weight, color)
- srp = erp[0]
- erp = erp[-1]
- vBlocks = getattr(self,'_vBlocks',{})
- canvLine = lambda y0, x0, y1, x1, _line=self.canv.line: _line(x0,y0,x1,y1)
- if count == 1:
- for x in cp:
- _hLine(canvLine, erp, srp, x, vBlocks)
- else:
- lf = lambda x0,y0,x1,y1,canvLine=canvLine, ws=weight+space, count=count: _multiLine(x0,x1,y0,canvLine,ws,count)
- for x in cp:
- _hLine(lf, erp, srp, x, vBlocks)
-
- def _drawVLinesA(self, start, end, weight, color, count, space):
- sc,sr = start
- ec,er = end
- self._drawVLines((sc+1, sr), (ec+1, er), weight, color, count, space)
-
- def wrap(self, availWidth, availHeight):
- self._calc(availWidth, availHeight)
- self.availWidth = availWidth
- return (self._width, self._height)
-
- def onSplit(self,T,byRow=1):
- '''
- This method will be called when the Table is split.
- Special purpose tables can override to do special stuff.
- '''
- pass
-
- def _cr_0(self,n,cmds):
- for c in cmds:
- c = tuple(c)
- (sc,sr), (ec,er) = c[1:3]
- if isinstance(sr,strTypes) or sr>=n: continue
- if er>=n: er = n-1
- self._addCommand((c[0],)+((sc, sr), (ec, er))+c[3:])
-
- def _cr_1_1(self,n,repeatRows, cmds):
- for c in cmds:
- c = tuple(c)
- (sc,sr), (ec,er) = c[1:3]
- if sr in ('splitfirst','splitlast'): self._addCommand(c)
- else:
- if sr>=0 and sr>=repeatRows and sr=0 and er=repeatRows and sr=repeatRows and sr>=n: sr=sr+repeatRows-n
- if er>=repeatRows and er=repeatRows and er>=n: er=er+repeatRows-n
- self._addCommand((c[0],)+((sc, sr), (ec, er))+c[3:])
-
- def _cr_1_0(self,n,cmds):
- for c in cmds:
- c = tuple(c)
- (sc,sr), (ec,er) = c[1:3]
- if sr in ('splitfirst','splitlast'): self._addCommand(c)
- else:
- if er>=0 and er=0 and sr=n: sr = sr-n
- if er>=n: er = er-n
- self._addCommand((c[0],)+((sc, sr), (ec, er))+c[3:])
-
- def _splitRows(self,availHeight):
- n=self._getFirstPossibleSplitRowPosition(availHeight)
- if n<=self.repeatRows: return []
- lim = len(self._rowHeights)
- if n==lim: return [self]
-
- repeatRows = self.repeatRows
- repeatCols = self.repeatCols
- splitByRow = self.splitByRow
- data = self._cellvalues
-
- #we're going to split into two superRows
- ident = self.ident
- if ident: ident = IdentStr(ident)
- R0 = self.__class__( data[:n], colWidths=self._colWidths, rowHeights=self._argH[:n],
- repeatRows=repeatRows, repeatCols=repeatCols,
- splitByRow=splitByRow, normalizedData=1, cellStyles=self._cellStyles[:n],
- ident=ident)
-
- #copy the commands
-
- A = []
- # hack up the line commands
- for op, (sc,sr), (ec,er), weight, color, cap, dash, join, count, space in self._linecmds:
- if isinstance(sr,strTypes) and sr.startswith('split'):
- A.append((op,(sc,sr), (ec,sr), weight, color, cap, dash, join, count, space))
- if sr=='splitlast':
- sr = er = n-1
- elif sr=='splitfirst':
- sr = n
- er = n
-
- if sc < 0: sc = sc + self._ncols
- if ec < 0: ec = ec + self._ncols
- if sr < 0: sr = sr + self._nrows
- if er < 0: er = er + self._nrows
-
- if op in ('BOX','OUTLINE','GRID'):
- if sr=n:
- # we have to split the BOX
- A.append(('LINEABOVE',(sc,sr), (ec,sr), weight, color, cap, dash, join, count, space))
- A.append(('LINEBEFORE',(sc,sr), (sc,er), weight, color, cap, dash, join, count, space))
- A.append(('LINEAFTER',(ec,sr), (ec,er), weight, color, cap, dash, join, count, space))
- A.append(('LINEBELOW',(sc,er), (ec,er), weight, color, cap, dash, join, count, space))
- if op=='GRID':
- A.append(('LINEBELOW',(sc,n-1), (ec,n-1), weight, color, cap, dash, join, count, space))
- A.append(('LINEABOVE',(sc,n), (ec,n), weight, color, cap, dash, join, count, space))
- A.append(('INNERGRID',(sc,sr), (ec,er), weight, color, cap, dash, join, count, space))
- else:
- A.append((op,(sc,sr), (ec,er), weight, color, cap, dash, join, count, space))
- elif op in ('INNERGRID','LINEABOVE'):
- if sr=n:
- A.append(('LINEBELOW',(sc,n-1), (ec,n-1), weight, color, cap, dash, join, count, space))
- A.append(('LINEABOVE',(sc,n), (ec,n), weight, color, cap, dash, join, count, space))
- A.append((op,(sc,sr), (ec,er), weight, color, cap, dash, join, count, space))
- elif op == 'LINEBELOW':
- if sr=(n-1):
- A.append(('LINEABOVE',(sc,n), (ec,n), weight, color, cap, dash, join, count, space))
- A.append((op,(sc,sr), (ec,er), weight, color))
- elif op == 'LINEABOVE':
- if sr<=n and er>=n:
- A.append(('LINEBELOW',(sc,n-1), (ec,n-1), weight, color, cap, dash, join, count, space))
- A.append((op,(sc,sr), (ec,er), weight, color, cap, dash, join, count, space))
- else:
- A.append((op,(sc,sr), (ec,er), weight, color, cap, dash, join, count, space))
-
- R0._cr_0(n,A)
- R0._cr_0(n,self._bkgrndcmds)
- R0._cr_0(n,self._spanCmds)
- R0._cr_0(n,self._nosplitCmds)
-
- if ident: ident = IdentStr(ident)
- if repeatRows:
- #R1 = slelf.__class__(data[:repeatRows]+data[n:],self._argW,
- R1 = self.__class__(data[:repeatRows]+data[n:],colWidths=self._colWidths,
- rowHeights=self._argH[:repeatRows]+self._argH[n:],
- repeatRows=repeatRows, repeatCols=repeatCols,
- splitByRow=splitByRow, normalizedData=1,
- cellStyles=self._cellStyles[:repeatRows]+self._cellStyles[n:],
- ident=ident,
- )
- R1._cr_1_1(n,repeatRows,A)
- R1._cr_1_1(n,repeatRows,self._bkgrndcmds)
- R1._cr_1_1(n,repeatRows,self._spanCmds)
- R1._cr_1_1(n,repeatRows,self._nosplitCmds)
- else:
- #R1 = slelf.__class__(data[n:], self._argW, self._argH[n:],
- R1 = self.__class__(data[n:], colWidths=self._colWidths, rowHeights=self._argH[n:],
- repeatRows=repeatRows, repeatCols=repeatCols,
- splitByRow=splitByRow, normalizedData=1, cellStyles=self._cellStyles[n:],
- ident=ident,
- )
- R1._cr_1_0(n,A)
- R1._cr_1_0(n,self._bkgrndcmds)
- R1._cr_1_0(n,self._spanCmds)
- R1._cr_1_0(n,self._nosplitCmds)
-
- R0.hAlign = R1.hAlign = self.hAlign
- R0.vAlign = R1.vAlign = self.vAlign
- self.onSplit(R0)
- self.onSplit(R1)
- return [R0,R1]
-
- def _getRowImpossible(impossible,cells,ranges):
- for xy in cells:
- r=ranges[xy]
- if r!=None:
- y1,y2=r[1],r[3]
- if y1!=y2:
- ymin=min(y1,y2) #normalize
- ymax=max(y1,y2) #normalize
- y=ymin+1
- while 1:
- if y>ymax: break
- impossible[y]=None #split at position y is impossible because of overlapping rowspan
- y+=1
- _getRowImpossible=staticmethod(_getRowImpossible)
-
- def _getFirstPossibleSplitRowPosition(self,availHeight):
- impossible={}
- if self._spanCmds:
- self._getRowImpossible(impossible,self._rowSpanCells,self._spanRanges)
- if self._nosplitCmds:
- self._getRowImpossible(impossible,self._rowNoSplitCells,self._nosplitRanges)
- h = 0
- n = 1
- split_at = 0 # from this point of view 0 is the first position where the table may *always* be splitted
- for rh in self._rowHeights:
- if h+rh>availHeight:
- break
- if n not in impossible:
- split_at=n
- h=h+rh
- n=n+1
- return split_at
-
- def split(self, availWidth, availHeight):
- self._calc(availWidth, availHeight)
- if self.splitByRow:
- if not rl_config.allowTableBoundsErrors and self._width>availWidth: return []
- return self._splitRows(availHeight)
- else:
- raise NotImplementedError
-
- def draw(self):
- self._curweight = self._curcolor = self._curcellstyle = None
- self._drawBkgrnd()
- if not self._spanCmds:
- # old fashioned case, no spanning, steam on and do each cell
- for row, rowstyle, rowpos, rowheight in zip(self._cellvalues, self._cellStyles, self._rowpositions[1:], self._rowHeights):
- for cellval, cellstyle, colpos, colwidth in zip(row, rowstyle, self._colpositions[:-1], self._colWidths):
- self._drawCell(cellval, cellstyle, (colpos, rowpos), (colwidth, rowheight))
- else:
- # we have some row or col spans, need a more complex algorithm
- # to find the rect for each
- for rowNo in xrange(self._nrows):
- for colNo in xrange(self._ncols):
- cellRect = self._spanRects[colNo, rowNo]
- if cellRect is not None:
- (x, y, width, height) = cellRect
- cellval = self._cellvalues[rowNo][colNo]
- cellstyle = self._cellStyles[rowNo][colNo]
- self._drawCell(cellval, cellstyle, (x, y), (width, height))
- self._drawLines()
-
- def _drawBkgrnd(self):
- nrows = self._nrows
- ncols = self._ncols
- canv = self.canv
- colpositions = self._colpositions
- rowpositions = self._rowpositions
- rowHeights = self._rowHeights
- colWidths = self._colWidths
- spanRects = getattr(self,'_spanRects',None)
- for cmd, (sc, sr), (ec, er), arg in self._bkgrndcmds:
- if sc < 0: sc = sc + ncols
- if ec < 0: ec = ec + ncols
- if sr < 0: sr = sr + nrows
- if er < 0: er = er + nrows
- x0 = colpositions[sc]
- y0 = rowpositions[sr]
- x1 = colpositions[min(ec+1,ncols)]
- y1 = rowpositions[min(er+1,nrows)]
- w, h = x1-x0, y1-y0
- if hasattr(arg,'__call__'):
- arg(self,canv, x0, y0, w, h)
- elif cmd == 'ROWBACKGROUNDS':
- #Need a list of colors to cycle through. The arguments
- #might be already colours, or convertible to colors, or
- # None, or the str 'None'.
- #It's very common to alternate a pale shade with None.
- colorCycle = list(map(colors.toColorOrNone, arg))
- count = len(colorCycle)
- rowCount = er - sr + 1
- for i in xrange(rowCount):
- color = colorCycle[i%count]
- h = rowHeights[sr + i]
- if color:
- canv.setFillColor(color)
- canv.rect(x0, y0, w, -h, stroke=0,fill=1)
- y0 = y0 - h
- elif cmd == 'COLBACKGROUNDS':
- #cycle through colours columnwise
- colorCycle = list(map(colors.toColorOrNone, arg))
- count = len(colorCycle)
- colCount = ec - sc + 1
- for i in xrange(colCount):
- color = colorCycle[i%count]
- w = colWidths[sc + i]
- if color:
- canv.setFillColor(color)
- canv.rect(x0, y0, w, h, stroke=0,fill=1)
- x0 = x0 +w
- else: #cmd=='BACKGROUND'
- color = colors.toColorOrNone(arg)
- if color:
- if ec==sc and er==sr and spanRects:
- xywh = spanRects.get((sc,sr))
- if xywh:
- #it's a single cell
- x0, y0, w, h = xywh
- canv.setFillColor(color)
- canv.rect(x0, y0, w, h, stroke=0,fill=1)
-
- def _drawCell(self, cellval, cellstyle, pos, size):
- colpos, rowpos = pos
- colwidth, rowheight = size
- if self._curcellstyle is not cellstyle:
- cur = self._curcellstyle
- if cur is None or cellstyle.color != cur.color:
- self.canv.setFillColor(cellstyle.color)
- if cur is None or cellstyle.leading != cur.leading or cellstyle.fontname != cur.fontname or cellstyle.fontsize != cur.fontsize:
- self.canv.setFont(cellstyle.fontname, cellstyle.fontsize, cellstyle.leading)
- self._curcellstyle = cellstyle
-
- just = cellstyle.alignment
- valign = cellstyle.valign
- if isinstance(cellval,(tuple,list,Flowable)):
- if not isinstance(cellval,(tuple,list)): cellval = (cellval,)
- # we assume it's a list of Flowables
- W = []
- H = []
- w, h = self._listCellGeom(cellval,colwidth,cellstyle,W=W, H=H,aH=rowheight)
- if valign=='TOP':
- y = rowpos + rowheight - cellstyle.topPadding
- elif valign=='BOTTOM':
- y = rowpos+cellstyle.bottomPadding + h
- else:
- y = rowpos+(rowheight+cellstyle.bottomPadding-cellstyle.topPadding+h)/2.0
- if cellval: y += cellval[0].getSpaceBefore()
- for v, w, h in zip(cellval,W,H):
- if just=='LEFT': x = colpos+cellstyle.leftPadding
- elif just=='RIGHT': x = colpos+colwidth-cellstyle.rightPadding - w
- elif just in ('CENTRE', 'CENTER'):
- x = colpos+(colwidth+cellstyle.leftPadding-cellstyle.rightPadding-w)/2.0
- else:
- raise ValueError('Invalid justification %s' % just)
- y -= v.getSpaceBefore()
- y -= h
- v.drawOn(self.canv,x,y)
- y -= v.getSpaceAfter()
- else:
- if just == 'LEFT':
- draw = self.canv.drawString
- x = colpos + cellstyle.leftPadding
- elif just in ('CENTRE', 'CENTER'):
- draw = self.canv.drawCentredString
- x = colpos+(colwidth+cellstyle.leftPadding-cellstyle.rightPadding)*0.5
- elif just == 'RIGHT':
- draw = self.canv.drawRightString
- x = colpos + colwidth - cellstyle.rightPadding
- elif just == 'DECIMAL':
- draw = self.canv.drawAlignedString
- x = colpos + colwidth - cellstyle.rightPadding
- else:
- raise ValueError('Invalid justification %s' % just)
- vals = str(cellval).split("\n")
- n = len(vals)
- leading = cellstyle.leading
- fontsize = cellstyle.fontsize
- if valign=='BOTTOM':
- y = rowpos + cellstyle.bottomPadding+n*leading-fontsize
- elif valign=='TOP':
- y = rowpos + rowheight - cellstyle.topPadding - fontsize
- elif valign=='MIDDLE':
- #tim roberts pointed out missing fontsize correction 2004-10-04
- y = rowpos + (cellstyle.bottomPadding + rowheight-cellstyle.topPadding+n*leading)/2.0 - fontsize
- else:
- raise ValueError("Bad valign: '%s'" % str(valign))
-
- for v in vals:
- draw(x, y, v)
- y -= leading
- onDraw = getattr(cellval,'onDraw',None)
- if onDraw:
- onDraw(self.canv,cellval.kind,cellval.label)
-
- if cellstyle.href:
- #external hyperlink
- self.canv.linkURL(cellstyle.href, (colpos, rowpos, colpos + colwidth, rowpos + rowheight), relative=1)
- if cellstyle.destination:
- #external hyperlink
- self.canv.linkRect("", cellstyle.destination, Rect=(colpos, rowpos, colpos + colwidth, rowpos + rowheight), relative=1)
-
-_LineOpMap = { 'GRID':'_drawGrid',
- 'BOX':'_drawBox',
- 'OUTLINE':'_drawBox',
- 'INNERGRID':'_drawInnerGrid',
- 'LINEBELOW':'_drawHLinesB',
- 'LINEABOVE':'_drawHLines',
- 'LINEBEFORE':'_drawVLines',
- 'LINEAFTER':'_drawVLinesA', }
-
-class LongTable(Table):
- '''Henning von Bargen's changes will be active'''
- _longTableOptimize = 1
-
-LINECOMMANDS = list(_LineOpMap.keys())
-
-def _isLineCommand(cmd):
- return cmd[0] in LINECOMMANDS
-
-def _setCellStyle(cellStyles, i, j, op, values):
- #new = CellStyle('<%d, %d>' % (i,j), cellStyles[i][j])
- #cellStyles[i][j] = new
- ## modify in place!!!
- new = cellStyles[i][j]
- if op == 'FONT':
- n = len(values)
- new.fontname = values[0]
- if n>1:
- new.fontsize = values[1]
- if n>2:
- new.leading = values[2]
- else:
- new.leading = new.fontsize*1.2
- elif op in ('FONTNAME', 'FACE'):
- new.fontname = values[0]
- elif op in ('SIZE', 'FONTSIZE'):
- new.fontsize = values[0]
- elif op == 'LEADING':
- new.leading = values[0]
- elif op == 'TEXTCOLOR':
- new.color = colors.toColor(values[0], colors.Color(0,0,0))
- elif op in ('ALIGN', 'ALIGNMENT'):
- new.alignment = values[0]
- elif op == 'VALIGN':
- new.valign = values[0]
- elif op == 'LEFTPADDING':
- new.leftPadding = values[0]
- elif op == 'RIGHTPADDING':
- new.rightPadding = values[0]
- elif op == 'TOPPADDING':
- new.topPadding = values[0]
- elif op == 'BOTTOMPADDING':
- new.bottomPadding = values[0]
- elif op == 'HREF':
- new.href = values[0]
- elif op == 'DESTINATION':
- new.destination = values[0]
-
-GRID_STYLE = TableStyle(
- [('GRID', (0,0), (-1,-1), 0.25, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
-BOX_STYLE = TableStyle(
- [('BOX', (0,0), (-1,-1), 0.50, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
-LABELED_GRID_STYLE = TableStyle(
- [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
- ('BOX', (0,0), (-1,-1), 2, colors.black),
- ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
- ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
-COLORED_GRID_STYLE = TableStyle(
- [('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
- ('BOX', (0,0), (-1,-1), 2, colors.red),
- ('LINEBELOW', (0,0), (-1,0), 2, colors.black),
- ('LINEAFTER', (0,0), (0,-1), 2, colors.black),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
-LIST_STYLE = TableStyle(
- [('LINEABOVE', (0,0), (-1,0), 2, colors.green),
- ('LINEABOVE', (0,1), (-1,-1), 0.25, colors.black),
- ('LINEBELOW', (0,-1), (-1,-1), 2, colors.green),
- ('ALIGN', (1,1), (-1,-1), 'RIGHT')]
- )
-
-# experimental iterator which can apply a sequence
-# of colors e.g. Blue, None, Blue, None as you move
-# down.
-if __name__ == '__main__':
- from tests.test_platypus_tables import old_tables_test
- old_tables_test()
diff --git a/reportlab/platypus/xpreformatted.py b/reportlab/platypus/xpreformatted.py
deleted file mode 100644
index 3af9730d..00000000
--- a/reportlab/platypus/xpreformatted.py
+++ /dev/null
@@ -1,338 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2012
-#see license.txt for license details
-#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/xpreformatted.py
-__version__=''' $Id$ '''
-__doc__='''A 'rich preformatted text' widget allowing internal markup'''
-from reportlab.lib import PyFontify
-from reportlab.platypus.paragraph import Paragraph, cleanBlockQuotedText, _handleBulletWidth, \
- ParaLines, _getFragWords, stringWidth, getAscentDescent, imgVRange, imgNormV
-from reportlab.lib.utils import isSeq
-from reportlab.platypus.flowables import _dedenter
-
-def _getFragLines(frags):
- lines = []
- cline = []
- W = frags[:]
- while W != []:
- w = W[0]
- t = w.text
- del W[0]
- i = t.find('\n')
- if i>=0:
- tleft = t[i+1:]
- cline.append(w.clone(text=t[:i]))
- lines.append(cline)
- cline = []
- if tleft!='':
- W.insert(0,w.clone(text=tleft))
- else:
- cline.append(w)
- if cline!=[]:
- lines.append(cline)
- return lines
-
-def _split_blPara(blPara,start,stop):
- f = blPara.clone()
- for a in ('lines', 'text'):
- if hasattr(f,a): delattr(f,a)
- f.lines = blPara.lines[start:stop]
- return [f]
-
-# Will be removed shortly.
-def _countSpaces(text):
- return text.count(' ')
-## i = 0
-## s = 0
-## while 1:
-## j = text.find(' ',i)
-## if j<0: return s
-## s = s + 1
-## i = j + 1
-
-def _getFragWord(frags,maxWidth):
- ''' given a fragment list return a list of lists
- [size, spaces, (f00,w00), ..., (f0n,w0n)]
- each pair f,w represents a style and some string
- '''
- W = []
- n = 0
- s = 0
- for f in frags:
- text = f.text[:]
- W.append((f,text))
- cb = getattr(f,'cbDefn',None)
- if cb:
- _w = getattr(cb,'width',0)
- if hasattr(_w,'normalizedValue'):
- _w._normalizer = maxWidth
- n = n + stringWidth(text, f.fontName, f.fontSize)
-
- #s = s + _countSpaces(text)
- s = s + text.count(' ') # much faster for many blanks
-
- #del f.text # we can't do this until we sort out splitting
- # of paragraphs
- return n, s, W
-
-class XPreformatted(Paragraph):
- def __init__(self, text, style, bulletText = None, frags=None, caseSensitive=1, dedent=0):
- self.caseSensitive = caseSensitive
- cleaner = lambda text, dedent=dedent: '\n'.join(_dedenter(text or '',dedent))
- self._setup(text, style, bulletText, frags, cleaner)
-
- def breakLines(self, width):
- """
- Returns a broken line structure. There are two cases
-
- A) 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
-
- B) 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."""
-
- if not isSeq(width): maxWidths = [width]
- else: maxWidths = width
- lines = []
- lineno = 0
- maxWidth = maxWidths[lineno]
- style = self.style
- fFontSize = float(style.fontSize)
- requiredWidth = 0
-
- #for bullets, work out width and ensure we wrap the right amount onto line one
- _handleBulletWidth(self.bulletText,style,maxWidths)
-
- self.height = 0
- autoLeading = getattr(self,'autoLeading',getattr(style,'autoLeading',''))
- calcBounds = autoLeading not in ('','off')
- frags = self.frags
- nFrags= len(frags)
- if nFrags==1:
- f = frags[0]
- if hasattr(f,'text'):
- fontSize = f.fontSize
- fontName = f.fontName
- ascent, descent = getAscentDescent(fontName,fontSize)
- kind = 0
- L=f.text.split('\n')
- for l in L:
- currentWidth = stringWidth(l,fontName,fontSize)
- requiredWidth = max(currentWidth,requiredWidth)
- extraSpace = maxWidth-currentWidth
- lines.append((extraSpace,l.split(' '),currentWidth))
- lineno = lineno+1
- maxWidth = lineno', ''),
- 'keyword' : ('', ''),
- 'parameter' : ('', ''),
- 'identifier' : ('', ''),
- 'string' : ('', '') }
-
- def __init__(self, text, style, bulletText = None, dedent=0, frags=None):
- if text:
- text = self.fontify(self.escapeHtml(text))
- XPreformatted.__init__(self, text, style,bulletText=bulletText,dedent=dedent,frags=frags)
-
- def escapeHtml(self, text):
- s = text.replace('&', '&')
- s = s.replace('<', '<')
- s = s.replace('>', '>')
- return s
-
- def fontify(self, code):
- "Return a fontified version of some Python code."
-
- if code[0] == '\n':
- code = code[1:]
-
- tags = PyFontify.fontify(code)
- fontifiedCode = ''
- pos = 0
- for k, i, j, dummy in tags:
- fontifiedCode = fontifiedCode + code[pos:i]
- s, e = self.formats[k]
- fontifiedCode = fontifiedCode + s + code[i:j] + e
- pos = j
-
- fontifiedCode = fontifiedCode + code[pos:]
-
- return fontifiedCode
-
-if __name__=='__main__': #NORUNTESTS
- import sys
- def dumpXPreformattedLines(P):
- print('\n############dumpXPreforemattedLines(%s)' % str(P))
- lines = P.blPara.lines
- n =len(lines)
- outw=sys.stdout.write
- for l in range(n):
- line = lines[l]
- words = line.words
- nwords = len(words)
- outw('line%d: %d(%d)\n ' % (l,nwords,line.wordCount))
- for w in range(nwords):
- outw(" %d:'%s'"%(w,words[w].text))
- print()
-
- def dumpXPreformattedFrags(P):
- print('\n############dumpXPreforemattedFrags(%s)' % str(P))
- frags = P.frags
- n =len(frags)
- for l in range(n):
- print("frag%d: '%s'" % (l, frags[l].text))
-
- outw=sys.stdout.write
- l = 0
- for L in _getFragLines(frags):
- n=0
- for W in _getFragWords(L,360):
- outw("frag%d.%d: size=%d" % (l, n, W[0]))
- n = n + 1
- for w in W[1:]:
- outw(" '%s'" % w[1])
- print()
- l = l + 1
-
- def try_it(text,style,dedent,aW,aH):
- P=XPreformatted(text,style,dedent=dedent)
- dumpXPreformattedFrags(P)
- w,h = P.wrap(aW, aH)
- dumpXPreformattedLines(P)
- S = P.split(aW,aH)
- dumpXPreformattedLines(P)
- for s in S:
- s.wrap(aW,aH)
- dumpXPreformattedLines(s)
- aH = 500
-
- from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
- styleSheet = getSampleStyleSheet()
- B = styleSheet['BodyText']
- DTstyle = ParagraphStyle("discussiontext", parent=B)
- DTstyle.fontName= 'Helvetica'
- for (text,dedent,style, aW, aH, active) in [('''
-
-
-The CMYK or subtractive
-
-method follows the way a printer
-mixes three pigments (cyan, magenta, and yellow) to form colors.
-Because mixing chemicals is more difficult than combining light there
-is a fourth parameter for darkness. For example a chemical
-combination of the CMY pigments generally never makes a perfect
-
-black -- instead producing a muddy color -- so, to get black printers
-don't use the CMY pigments but use a direct black ink. Because
-CMYK maps more directly to the way printer hardware works it may
-be the case that &| & | colors specified in CMYK will provide better fidelity
-and better control when printed.
-
-
-''',0,DTstyle, 456.0, 42.8, 0),
-('''
-
- This is a non rearranging form of the Paragraph class;
- XML tags are allowed in text and have the same
-
- meanings as for the Paragraph class.
- As for Preformatted, if dedent is non zero dedent
- common leading spaces will be removed from the
- front of each line.
-
-''',3, DTstyle, 456.0, 42.8, 0),
-("""\
- class FastXMLParser:
- # Nonsense method
- def nonsense(self):
- self.foo = 'bar'
-""",0, styleSheet['Code'], 456.0, 4.8, 1),
-]:
- if active: try_it(text,style,dedent,aW,aH)
diff --git a/reportlab/rl_config.py b/reportlab/rl_config.py
deleted file mode 100644
index 8c24a0e6..00000000
--- a/reportlab/rl_config.py
+++ /dev/null
@@ -1,131 +0,0 @@
-'''module that aggregates config information'''
-__all__=('_reset','register_reset')
-
-def _defaults_init():
- '''
- create & return defaults for all reportlab settings from
- reportlab.rl_settings.py
- reportlab.local_rl_settings.py
- reportlab_settings.py or ~/.reportlab_settings
-
- latter values override earlier
- '''
- from reportlab.lib.utils import rl_exec
- import os
-
- _DEFAULTS={}
- rl_exec('from reportlab.rl_settings import *',_DEFAULTS)
-
- _overrides=_DEFAULTS.copy()
- try:
- rl_exec('from reportlab.local_rl_settings import *',_overrides)
- _DEFAULTS.update(_overrides)
- except ImportError:
- pass
-
- _overrides=_DEFAULTS.copy()
- try:
- rl_exec('from reportlab_settings import *',_overrides)
- _DEFAULTS.update(_overrides)
- except ImportError:
- _overrides=_DEFAULTS.copy()
- try:
- try:
- fn = os.path.expanduser(os.path.join('~','.reportlab_settings')) #appengine fails with ImportError
- except ImportError:
- fn = None
- if fn:
- with open(fn,'rb') as f:
- rl_exec(f.read(),_overrides)
- _DEFAULTS.update(_overrides)
- except:
- pass
- return _DEFAULTS
-
-_DEFAULTS=_defaults_init()
-
-_SAVED = {}
-sys_version=None
-
-#this is used to set the options from
-def _setOpt(name, value, conv=None):
- '''set a module level value from environ/default'''
- from os import environ
- ename = 'RL_'+name
- if ename in environ:
- value = environ[ename]
- if conv: value = conv(value)
- globals()[name] = value
-
-def _startUp():
- '''This function allows easy resetting to the global defaults
- If the environment contains 'RL_xxx' then we use the value
- else we use the given default'''
- import os, sys
- global sys_version, _unset_
- sys_version = sys.version.split()[0] #strip off the other garbage
- from reportlab.lib import pagesizes
- from reportlab.lib.utils import rl_isdir
-
- if _SAVED=={}:
- _unset_ = getattr(sys,'_rl_config__unset_',None)
- if _unset_ is None:
- class _unset_: pass
- sys._rl_config__unset_ = _unset_ = _unset_()
- global __all__
- A = list(__all__)
- for k,v in _DEFAULTS.items():
- _SAVED[k] = globals()[k] = v
- if k not in __all__:
- A.append(k)
- __all__ = tuple(A)
-
- #places to search for Type 1 Font files
- import reportlab
- D = {'REPORTLAB_DIR': os.path.abspath(os.path.dirname(reportlab.__file__)),
- 'CWD': os.getcwd(),
- 'disk': os.getcwd().split(':')[0],
- 'sys_version': sys_version,
- 'XDG_DATA_HOME': os.environ.get('XDG_DATA_HOME','~/.local/share'),
- }
-
- for k in _SAVED:
- if k.endswith('SearchPath'):
- P=[]
- for p in _SAVED[k]:
- d = (p % D).replace('/',os.sep)
- if '~' in d:
- try:
- d = os.path.expanduser(d) #appengine fails with ImportError
- except ImportError:
- continue
- if rl_isdir(d): P.append(d)
- _setOpt(k,os.pathsep.join(P),lambda x:x.split(os.pathsep))
- globals()[k] = list(filter(rl_isdir,globals()[k]))
- else:
- v = _SAVED[k]
- if isinstance(v,(int,float)): conv = type(v)
- elif k=='defaultPageSize': conv = lambda v,M=pagesizes: getattr(M,v)
- else: conv = None
- _setOpt(k,v,conv)
-
-_registered_resets=[]
-def register_reset(func):
- '''register a function to be called by rl_config._reset'''
- _registered_resets[:] = [x for x in _registered_resets if x()]
- L = [x for x in _registered_resets if x() is func]
- if L: return
- from weakref import ref
- _registered_resets.append(ref(func))
-
-def _reset():
- '''attempt to reset reportlab and friends'''
- _startUp() #our reset
- for f in _registered_resets[:]:
- c = f()
- if c:
- c()
- else:
- _registered_resets.remove(f)
-
-_startUp()
diff --git a/reportlab/rl_settings.py b/reportlab/rl_settings.py
deleted file mode 100644
index 593404e2..00000000
--- a/reportlab/rl_settings.py
+++ /dev/null
@@ -1,209 +0,0 @@
-#Copyright ReportLab Europe Ltd. 2000-2013
-#see license.txt for license details
-'''default settings for reportlab
-
-to override these drop a module rl_local_settings.py parallel to this file or
-anywhere on the path.
-'''
-import os, sys
-__version__=''' $Id$ '''
-__all__=tuple('''allowTableBoundsErrors
-shapeChecking
-defaultEncoding
-defaultGraphicsFontName
-pageCompression
-useA85
-defaultPageSize
-defaultImageCaching
-ZLIB_WARNINGS
-warnOnMissingFontGlyphs
-verbose
-showBoundary
-emptyTableAction
-invariant
-eps_preview_transparent
-eps_preview
-eps_ttf_embed
-eps_ttf_embed_uid
-overlapAttachedSpace
-longTableOptimize
-autoConvertEncoding
-_FUZZ
-wrapA85
-fsEncodings
-odbc_driver
-platypus_link_underline
-canvas_basefontname
-allowShortTableRows
-imageReaderFlags
-paraFontSizeHeightOffset
-canvas_baseColor
-ignoreContainerActions
-ttfAsciiReadable
-pdfMultiLine
-pdfComments
-debug
-rtlSupport
-listWrapOnFakeWidth
-T1SearchPath
-TTFSearchPath
-CMapSearchPath
-baseUnderlineProportion
-decimalSymbol'''.split())
-
-allowTableBoundsErrors = 1 # set to 0 to die on too large elements in tables in debug (recommend 1 for production use)
-shapeChecking = 1
-defaultEncoding = 'WinAnsiEncoding' # 'WinAnsi' or 'MacRoman'
-defaultGraphicsFontName= 'Times-Roman' #initializer for STATE_DEFAULTS in shapes.py
-pageCompression = 1 # default page compression mode
-useA85 = 1 #set to 0 to disable Ascii Base 85 stream filters
-defaultPageSize = 'A4' #default page size
-defaultImageCaching = 0 #set to zero to remove those annoying cached images
-ZLIB_WARNINGS = 1
-warnOnMissingFontGlyphs = 0 #if 1, warns of each missing glyph
-verbose = 0
-showBoundary = 0 # turns on and off boundary behaviour in Drawing
-emptyTableAction= 'error' # one of 'error', 'indicate', 'ignore'
-invariant= 0 #produces repeatable,identical PDFs with same timestamp info (for regression testing)
-eps_preview_transparent= None #set to white etc
-eps_preview= 1 #set to False to disable
-eps_ttf_embed= 1 #set to False to disable
-eps_ttf_embed_uid= 0 #set to 1 to enable
-overlapAttachedSpace= 1 #if set non false then adajacent flowable space after
- #and space before are merged (max space is used).
-longTableOptimize = 1 #default don't use Henning von Bargen's long table optimizations
-autoConvertEncoding = 0 #convert internally as needed (experimental)
-_FUZZ= 1e-6 #fuzz for layout arithmetic
-wrapA85= 0 #set to 1 to get old wrapped line behaviour
-fsEncodings=('utf8','cp1252','cp430') #encodings to attempt utf8 conversion with
-odbc_driver= 'odbc' #default odbc driver
-platypus_link_underline= 0 #paragraph links etc underlined if true
-canvas_basefontname= 'Helvetica' #this is used to initialize the canvas; if you override to make
- #something else you are responsible for ensuring the font is registered etc etc
- #this will be used everywhere and the font family connections will be made
- #if the bold/italic/bold italic fonts are also registered and defined as a family.
-
-allowShortTableRows=1 #allows some rows in a table to be short
-imageReaderFlags=0 #attempt to convert images into internal memory files to reduce
- #the number of open files (see lib.utils.ImageReader)
- #if imageReaderFlags&2 then attempt autoclosing of those files
- #if imageReaderFlags&4 then cache data
- #if imageReaderFlags==-1 then use Ralf Schmitt's re-opening approach
-paraFontSizeHeightOffset= 1 #if true paragraphs start at height-fontSize
-canvas_baseColor= None #initialize the canvas fill and stroke colors if this is set
-ignoreContainerActions= 1 #if true then action flowables in flowable _Containers will be ignored
-ttfAsciiReadable= 1 #smaller subsets when set to 0
-pdfMultiLine= 0 #use more lines in pdf etc
-pdfComments= 0 #put in pdf comments
-debug= 0 #for debugging code
-rtlSupport= 0 #set to 1 to attempt import of RTL assistance eg fribidi etc etc
-listWrapOnFakeWidth= 1 #set to 0/False to force platypus.flowables._listWrapOn to report correct widths
- #else it reports minimum(required,available) width
-baseUnderlineProportion= 0.0 #non-zero for doing font size proportional lines in Paragraph.py
- #by default typical value 0.05. may be overridden on a parastyle.
-decimalSymbol= '.' #what we use to align floats numerically
-
-# places to look for T1Font information
-T1SearchPath = (
- 'c:/Program Files/Adobe/Acrobat 9.0/Resource/Font',
- 'c:/Program Files/Adobe/Acrobat 8.0/Resource/Font',
- 'c:/Program Files/Adobe/Acrobat 7.0/Resource/Font',
- 'c:/Program Files/Adobe/Acrobat 6.0/Resource/Font', #Win32, Acrobat 6
- 'c:/Program Files/Adobe/Acrobat 5.0/Resource/Font', #Win32, Acrobat 5
- 'c:/Program Files/Adobe/Acrobat 4.0/Resource/Font', #Win32, Acrobat 4
- '%(disk)s/Applications/Python %(sys_version)s/reportlab/fonts', #Mac?
- '/usr/lib/Acrobat9/Resource/Font', #Linux, Acrobat 5?
- '/usr/lib/Acrobat8/Resource/Font', #Linux, Acrobat 5?
- '/usr/lib/Acrobat7/Resource/Font', #Linux, Acrobat 5?
- '/usr/lib/Acrobat6/Resource/Font', #Linux, Acrobat 5?
- '/usr/lib/Acrobat5/Resource/Font', #Linux, Acrobat 5?
- '/usr/lib/Acrobat4/Resource/Font', #Linux, Acrobat 4
- '/usr/local/Acrobat9/Resource/Font', #Linux, Acrobat 5?
- '/usr/local/Acrobat8/Resource/Font', #Linux, Acrobat 5?
- '/usr/local/Acrobat7/Resource/Font', #Linux, Acrobat 5?
- '/usr/local/Acrobat6/Resource/Font', #Linux, Acrobat 5?
- '/usr/local/Acrobat5/Resource/Font', #Linux, Acrobat 5?
- '/usr/local/Acrobat4/Resource/Font', #Linux, Acrobat 4
- '/usr/share/fonts/default/Type1', #Linux, Fedora
- '%(REPORTLAB_DIR)s/fonts', #special
- '%(REPORTLAB_DIR)s/../fonts', #special
- '%(REPORTLAB_DIR)s/../../fonts', #special
- '%(CWD)s/fonts', #special
- '~/fonts',
- '~/.fonts',
- '%(XDG_DATA_HOME)s/fonts',
- '~/.local/share/fonts',
- )
-
-# places to look for TT Font information
-TTFSearchPath = (
- 'c:/winnt/fonts',
- 'c:/windows/fonts',
- '/usr/lib/X11/fonts/TrueType/',
- '/usr/share/fonts/truetype',
- '/usr/share/fonts', #Linux, Fedora
- '/usr/share/fonts/dejavu', #Linux, Fedora
- '%(REPORTLAB_DIR)s/fonts', #special
- '%(REPORTLAB_DIR)s/../fonts', #special
- '%(REPORTLAB_DIR)s/../../fonts',#special
- '%(CWD)s/fonts', #special
- '~/fonts',
- '~/.fonts',
- '%(XDG_DATA_HOME)s/fonts',
- '~/.local/share/fonts',
- #mac os X - from
- #http://developer.apple.com/technotes/tn/tn2024.html
- '~/Library/Fonts',
- '/Library/Fonts',
- '/Network/Library/Fonts',
- '/System/Library/Fonts',
- )
-
-# places to look for CMap files - should ideally merge with above
-CMapSearchPath = (
- '/usr/lib/Acrobat9/Resource/CMap',
- '/usr/lib/Acrobat8/Resource/CMap',
- '/usr/lib/Acrobat7/Resource/CMap',
- '/usr/lib/Acrobat6/Resource/CMap',
- '/usr/lib/Acrobat5/Resource/CMap',
- '/usr/lib/Acrobat4/Resource/CMap',
- '/usr/local/Acrobat9/Resource/CMap',
- '/usr/local/Acrobat8/Resource/CMap',
- '/usr/local/Acrobat7/Resource/CMap',
- '/usr/local/Acrobat6/Resource/CMap',
- '/usr/local/Acrobat5/Resource/CMap',
- '/usr/local/Acrobat4/Resource/CMap',
- 'C:\\Program Files\\Adobe\\Acrobat\\Resource\\CMap',
- 'C:\\Program Files\\Adobe\\Acrobat 9.0\\Resource\\CMap',
- 'C:\\Program Files\\Adobe\\Acrobat 8.0\\Resource\\CMap',
- 'C:\\Program Files\\Adobe\\Acrobat 7.0\\Resource\\CMap',
- 'C:\\Program Files\\Adobe\\Acrobat 6.0\\Resource\\CMap',
- 'C:\\Program Files\\Adobe\\Acrobat 5.0\\Resource\\CMap',
- 'C:\\Program Files\\Adobe\\Acrobat 4.0\\Resource\\CMap',
- '%(REPORTLAB_DIR)s/fonts/CMap', #special
- '%(REPORTLAB_DIR)s/../fonts/CMap', #special
- '%(REPORTLAB_DIR)s/../../fonts/CMap', #special
- '%(CWD)s/fonts/CMap', #special
- '%(CWD)s/fonts', #special
- '~/fonts/CMap',
- '~/.fonts/CMap',
- '%(XDG_DATA_HOME)s/fonts/CMap',
- '~/.local/share/fonts/CMap',
- )
-
-if sys.platform.startswith('linux'):
- def _findFontDirs(*ROOTS):
- R = [].append
- for rootd in ROOTS:
- for root, dirs, files in os.walk(rootd):
- if not files: continue
- R(root)
- return tuple(R.__self__)
- T1SearchPath = T1SearchPath + _findFontDirs(
- '/usr/share/fonts/type1',
- '/usr/share/fonts/Type1',
- )
- TTFSearchPath = TTFSearchPath + _findFontDirs(
- '/usr/share/fonts/truetype',
- '/usr/share/fonts/TTF',
- )
diff --git a/requirements.txt b/requirements.txt
index 6cc17e3c..c7a586a1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,4 +5,6 @@ django-registration-redux==1.1
django-reversion==1.8.5
sqlparse==0.1.13
simplejson==3.6.5
-lxml==3.4.1
\ No newline at end of file
+lxml==3.4.1
+pil==1.1.7
+z3c.rlm==2.7.2
\ No newline at end of file
diff --git a/z3c/__init__.py b/z3c/__init__.py
deleted file mode 100644
index bf99a9da..00000000
--- a/z3c/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# this is a namespace package
-try:
- import pkg_resources
- pkg_resources.declare_namespace(__name__)
-except ImportError:
- import pkgutil
- __path__ = pkgutil.extend_path(__path__, __name__)
-
diff --git a/z3c/rml/README.txt b/z3c/rml/README.txt
deleted file mode 100644
index 2d9ff334..00000000
--- a/z3c/rml/README.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-=========================
-Reportlab Markup Language
-=========================
-
-This package is a free implementation of the RML markup language developed by
-Reportlab. Unfortunately, full compliance cannot be immediately verified,
-since the RML User Guide is ambiguous, incomplete and even incorrect. This
-package can also not support the commercial extensions to Reportlab.
-
-In the course of implementing the specification, I made already some
-improvements for various tags and added others fully. I also tried hard to
-test all features. If you have any new sample RML files that you would like to
-share, please check them in.
-
-Why reimplement RML? The other free implementation of RML tinyRML is
-unfortunately pretty messy code and hard to debug. It makes it also hard to
-add additional tags. However, much thanks goes to their authors, since they
-have solved some of the very tricky issues.
diff --git a/z3c/rml/__init__.py b/z3c/rml/__init__.py
deleted file mode 100644
index fc80500c..00000000
--- a/z3c/rml/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Hook up our custom paragraph parser.
-import z3c.rml.paraparser
-import z3c.rml.rlfix
-
-
-from reportlab.lib.styles import getSampleStyleSheet
-SampleStyleSheet = getSampleStyleSheet()
diff --git a/z3c/rml/attr.py b/z3c/rml/attr.py
deleted file mode 100644
index 7dae41ee..00000000
--- a/z3c/rml/attr.py
+++ /dev/null
@@ -1,607 +0,0 @@
-# #############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-# #############################################################################
-"""RML Attribute Implementation
-"""
-import cStringIO
-import logging
-import os
-import re
-import reportlab.graphics.widgets.markers
-import reportlab.lib.colors
-import reportlab.lib.pagesizes
-import reportlab.lib.styles
-import reportlab.lib.units
-import reportlab.lib.utils
-import urllib
-import zope.interface
-import zope.schema
-from lxml import etree
-
-from z3c.rml import interfaces, SampleStyleSheet
-
-MISSING = object()
-logger = logging.getLogger("z3c.rml")
-
-
-def getFileInfo(directive):
- root = directive
- while root.parent:
- root = root.parent
- return '(file %s, line %i)' % (
- root.filename, directive.element.sourceline)
-
-
-def getManager(context, interface=None):
- if interface is None:
- # Avoid circular imports
- from z3c.rml import interfaces
-
- interface = interfaces.IManager
- # Walk up the path until the manager is found
- # Using interface.providedBy is much slower because it does many more checks
- while (
- context is not None and
- not interface in context.__class__.__dict__.get('__implemented__', {})
- ):
- context = context.parent
- # If no manager was found, raise an error
- if context is None:
- raise ValueError('The manager could not be found.')
- return context
-
-
-def deprecated(oldName, attr, reason):
- zope.interface.directlyProvides(attr, interfaces.IDeprecated)
- attr.deprecatedName = oldName
- attr.deprecatedReason = reason
- return attr
-
-
-class RMLAttribute(zope.schema.Field):
- """An attribute of the RML directive."""
-
- missing_value = MISSING
- default = MISSING
-
- def fromUnicode(self, ustr):
- """See zope.schema.interfaces.IField"""
- if self.context is None:
- raise ValueError('Attribute not bound to a context.')
- return super(RMLAttribute, self).fromUnicode(unicode(ustr))
-
- def get(self):
- """See zope.schema.interfaces.IField"""
- # If the attribute has a deprecated partner and the deprecated name
- # has been specified, use it.
- if (interfaces.IDeprecated.providedBy(self) and
- self.deprecatedName in self.context.element.attrib):
- name = self.deprecatedName
- logger.warn(
- u'Deprecated attribute "%s": %s %s' % (
- name, self.deprecatedReason, getFileInfo(self.context)))
- else:
- name = self.__name__
- # Extract the value.
- value = self.context.element.get(name, self.missing_value)
- # Get the correct default value.
- if value is self.missing_value:
- if self.default is not None:
- return self.default
- return self.missing_value
- return self.fromUnicode(value)
-
-
-class BaseChoice(RMLAttribute):
- choices = {}
- doLower = True
-
- def fromUnicode(self, value):
- if self.doLower:
- value = value.lower()
- if value in self.choices:
- return self.choices[value]
- raise ValueError(
- '%r not a valid value for attribute "%s". %s' % (
- value, self.__name__, getFileInfo(self.context)))
-
-
-class Combination(RMLAttribute):
- """A combination of several other attribute types."""
-
- def __init__(self, value_types=(), *args, **kw):
- super(Combination, self).__init__(*args, **kw)
- self.value_types = value_types
-
- def fromUnicode(self, value):
- for value_type in self.value_types:
- bound = value_type.bind(self)
- try:
- return bound.fromUnicode(value)
- except ValueError:
- pass
- raise ValueError(
- '"%s" is not a valid value. %s' % (
- value, getFileInfo(self.context)))
-
-
-class String(RMLAttribute, zope.schema.Bytes):
- """A simple Bytes string."""
-
-
-class Text(RMLAttribute, zope.schema.Text):
- """A simple unicode string."""
-
-
-class Integer(RMLAttribute, zope.schema.Int):
- """An integer. A minimum and maximum value can be specified."""
- # By making min and max simple attributes, we avoid some validation
- # problems.
- min = None
- max = None
-
-
-class Float(RMLAttribute, zope.schema.Float):
- """An flaoting point. A minimum and maximum value can be specified."""
- # By making min and max simple attributes, we avoid some validation
- # problems.
- min = None
- max = None
-
-
-class StringOrInt(RMLAttribute):
- """A (bytes) string or an integer."""
-
- def fromUnicode(self, value):
- try:
- return int(value)
- except ValueError:
- return str(value)
-
-
-class Sequence(RMLAttribute, zope.schema._field.AbstractCollection):
- """A list of values of a specified type."""
-
- splitre = re.compile('[ \t\n,;]*')
-
- def __init__(self, splitre=None, *args, **kw):
- super(Sequence, self).__init__(*args, **kw)
- if splitre is not None:
- self.splitre = splitre
-
- def fromUnicode(self, ustr):
- if ustr.startswith('(') and ustr.endswith(')'):
- ustr = ustr[1:-1]
- ustr = ustr.strip()
- raw_values = self.splitre.split(ustr)
- result = [self.value_type.bind(self.context).fromUnicode(raw.strip())
- for raw in raw_values]
- if ((self.min_length is not None and len(result) < self.min_length) and
- (self.max_length is not None and len(result) > self.max_length)):
- raise ValueError(
- 'Length of sequence must be at least %s and at most %i. %s' % (
- self.min_length, self.max_length,
- getFileInfo(self.context)))
- return result
-
-
-class IntegerSequence(Sequence):
- """A sequence of integers."""
-
- def fromUnicode(self, ustr):
- ustr = ustr.strip()
- pieces = self.splitre.split(ustr)
- numbers = set([])
- for piece in pieces:
- # Ignore empty pieces.
- if not piece:
- continue
- # The piece is a range.
- if '-' in piece:
- start, end = piece.split('-')
- # Make range lower and upper bound inclusive.
- numbers.update(range(int(start), int(end) + 1))
- continue
- # The piece is just a number
- numbers.add(int(piece))
- return list(numbers)
-
-
-class Choice(BaseChoice):
- """A choice of several values. The values are always case-insensitive."""
-
- def __init__(self, choices=None, doLower=True, *args, **kw):
- super(Choice, self).__init__(*args, **kw)
- if isinstance(choices, (tuple, list)):
- choices = dict(
- [(val.lower() if doLower else val, val) for val in choices])
- else:
- choices = dict(
- [(key.lower() if doLower else key, val)
- for key, val in choices.items()])
- self.choices = choices
- self.doLower = doLower
-
-
-class Boolean(BaseChoice):
- '''A boolean value.
-
- For true the values "true", "yes", and "1" are allowed. For false, the
- values "false", "no", "1" are allowed.
- '''
- choices = {'true': True, 'false': False,
- 'yes': True, 'no': False,
- '1': True, '0': False,
- }
-
-
-class TextBoolean(BaseChoice):
- '''A boolean value as text.
-
- ReportLab sometimes exposes low-level APIs, so we have to provide values
- that are directly inserted into the PDF.
-
- For "true" the values "true", "yes", and "1" are allowed. For "false", the
- values "false", "no", "1" are allowed.
- '''
- choices = {'true': 'true', 'false': 'false',
- 'yes': 'true', 'no': 'false',
- '1': 'true', '0': 'false',
- }
-
-
-class BooleanWithDefault(Boolean):
- '''This is a boolean field that can also receive the value "default".'''
- choices = Boolean.choices.copy()
- choices.update({'default': None})
-
-
-class Measurement(RMLAttribute):
- '''This field represents a length value.
-
- The units "in" (inch), "cm", "mm", and "pt" are allowed. If no units are
- specified, the value is given in points/pixels.
- '''
-
- def __init__(self, allowPercentage=False, allowStar=False, *args, **kw):
- super(Measurement, self).__init__(*args, **kw)
- self.allowPercentage = allowPercentage
- self.allowStar = allowStar
-
- units = [
- (re.compile('^(-?[0-9\.]+)\s*in$'), reportlab.lib.units.inch),
- (re.compile('^(-?[0-9\.]+)\s*cm$'), reportlab.lib.units.cm),
- (re.compile('^(-?[0-9\.]+)\s*mm$'), reportlab.lib.units.mm),
- (re.compile('^(-?[0-9\.]+)\s*pt$'), 1),
- (re.compile('^(-?[0-9\.]+)\s*$'), 1)
- ]
-
- allowPercentage = False
- allowStar = False
-
- def fromUnicode(self, value):
- if value == 'None':
- return None
- if value == '*' and self.allowStar:
- return value
- if value.endswith('%') and self.allowPercentage:
- return value
-
- for unit in self.units:
- res = unit[0].search(value, 0)
- if res:
- return unit[1] * float(res.group(1))
- raise ValueError(
- 'The value %r is not a valid measurement. %s' % (
- value, getFileInfo(self.context)))
-
-
-class File(Text):
- """This field will return a file object.
-
- The value itself can eith be be a relative or absolute path. Additionally
- the following syntax is supported: [path.to.python.mpackage]/path/to/file
- """
- open = staticmethod(urllib.urlopen)
- packageExtract = re.compile('^\[([0-9A-z_.]*)\]/(.*)$')
-
- doNotOpen = False
-
- def __init__(self, doNotOpen=False, *args, **kw):
- super(File, self).__init__(*args, **kw)
- self.doNotOpen = doNotOpen
-
- def fromUnicode(self, value):
- # Check whether the value is of the form:
- # []/rel/path/image.gif"
- if value.startswith('['):
- result = self.packageExtract.match(value)
- if result is None:
- raise ValueError(
- 'The package-path-pair you specified was incorrect. %s' % (
- getFileInfo(self.context)))
- modulepath, path = result.groups()
- module = __import__(modulepath, {}, {}, (modulepath))
- value = os.path.join(os.path.dirname(module.__file__), path)
- # If there is a drive name in the path, then we want a local file to
- # be opened. This is only interesting for Windows of course.
- if os.path.splitdrive(value)[0]:
- value = 'file:///' + value
- # If the file is not to be opened, simply return the path.
- if self.doNotOpen:
- return value
- # Open/Download the file
- fileObj = self.open(value)
- sio = cStringIO.StringIO(fileObj.read())
- fileObj.close()
- sio.seek(0)
- return sio
-
-
-class Image(File):
- """Similar to the file File attribute, except that an image is internally
- expected."""
-
- def __init__(self, onlyOpen=False, *args, **kw):
- super(Image, self).__init__(*args, **kw)
- self.onlyOpen = onlyOpen
-
- def fromUnicode(self, value):
- if value.lower().endswith('.svg') or value.lower().endswith('.svgz'):
- return self._load_svg(value)
- fileObj = super(Image, self).fromUnicode(value)
- if self.onlyOpen:
- return fileObj
- return reportlab.lib.utils.ImageReader(fileObj)
-
- def _load_svg(self, value):
- manager = getManager(self.context)
-
- width = self.context.element.get('width')
- if width is not None:
- width = Measurement().fromUnicode(width)
- height = self.context.element.get('height')
- if height is not None:
- height = Measurement().fromUnicode(height)
- preserve = self.context.element.get('preserveAspectRatio')
- if preserve is not None:
- preserve = Boolean().fromUnicode(preserve)
-
- cache_key = '%s-%sx%s-%s' % (value, width, height, preserve)
- if cache_key in manager.svgs:
- return manager.svgs[cache_key]
-
- from gzip import GzipFile
- from reportlab.graphics import renderPM
- from svg2rlg import Renderer
- from xml.etree import cElementTree
-
- fileObj = super(Image, self).fromUnicode(value)
- svg = fileObj.getvalue()
- if svg[:2] == '\037\213':
- svg = GzipFile(fileobj=fileObj).read()
- svg = cElementTree.fromstring(svg)
- svg = Renderer(value).render(svg)
-
- if preserve:
- if width is not None or height is not None:
- if width is not None and height is None:
- height = svg.height * width / svg.width
- elif height is not None and width is None:
- width = svg.width * height / svg.height
- elif float(width) / height > float(svg.width) / svg.height:
- width = svg.width * height / svg.height
- else:
- height = svg.height * width / svg.width
- else:
- if width is None:
- width = svg.width
- if height is None:
- height = svg.height
-
- svg.scale(width / svg.width, height / svg.height)
- svg.width = width
- svg.height = height
-
- svg = renderPM.drawToPIL(svg, dpi=300)
- svg = reportlab.lib.utils.ImageReader(svg)
- svg.read = True # A hack to get ImageReader through as an open Image
- # when used with imageAndFlowables
- manager.svgs[cache_key] = svg
- return svg
-
-
-class Color(RMLAttribute):
- """Requires the input of a color. There are several supported formats.
-
- Three values in a row are interpreted as RGB value ranging from 0-255.
- A string is interpreted as a name to a pre-defined color.
- The 'CMYK()' wrapper around four values represents a CMYK color
- specification.
- """
-
- def __init__(self, acceptNone=False, *args, **kw):
- super(Color, self).__init__(*args, **kw)
- self.acceptNone = acceptNone
-
- def fromUnicode(self, value):
- if self.acceptNone and value.lower() == 'none':
- return None
- manager = getManager(self.context)
-
- if value.startswith('rml:'):
- value = manager.get_name(value[4:], '#000000')
-
- if value in manager.colors:
- return manager.colors[value]
- try:
- return reportlab.lib.colors.toColor(value)
- # Bare except, since code raises string exception: Invalid color value
- except:
- raise ValueError(
- 'The color specification "%s" is not valid. %s' % (
- value, getFileInfo(self.context)))
-
-
-def _getStyle(context, value):
- manager = getManager(context)
- for styles in (manager.styles, SampleStyleSheet.byName):
- if value in styles:
- return styles[value]
- elif 'style.' + value in styles:
- return styles['style.' + value]
- elif value.startswith('style.') and value[6:] in styles:
- return styles[value[6:]]
- raise ValueError('Style %r could not be found. %s' % (
- value, getFileInfo(context)))
-
-
-class Style(String):
- """Requires a valid style to be entered.
-
- Whether the style is a paragraph, table or box style is irrelevant, except
- that it has to fit the tag.
- """
- default = SampleStyleSheet.byName['Normal']
-
- def fromUnicode(self, value):
- return _getStyle(self.context, value)
-
-
-class Padding(Sequence):
- """This attribute is specific for padding and will produce the proper
- length of the padding sequence."""
-
- def __init__(self, *args, **kw):
- kw.update(dict(value_type=Integer(), min_length=1, max_length=4))
- super(Padding, self).__init__(*args, **kw)
-
- def fromUnicode(self, value):
- seq = super(Padding, self).fromUnicode(value)
- # pdfgen does not like a single paddign value.
- if len(seq) == 1:
- seq.append(seq[0])
- return seq
-
-
-class Symbol(Text):
- """This attribute should contain the text representation of a symbol to be
- used."""
-
- def fromUnicode(self, value):
- return reportlab.graphics.widgets.markers.makeMarker(value)
-
-
-class PageSize(RMLAttribute):
- """A simple measurement pair that specifies the page size. Optionally you
- can also specify a the name of a page size, such as A4, letter, or legal.
- """
-
- sizePair = Sequence(value_type=Measurement())
- words = Sequence(value_type=String())
-
- def fromUnicode(self, value):
- # First try to get a pair
- try:
- return self.sizePair.bind(self.context).fromUnicode(value)
- except ValueError:
- pass
- # Now we try to lookup a name. The following type of combinations must
- # work: "Letter" "LETTER" "A4 landscape" "letter portrait"
- words = self.words.bind(self.context).fromUnicode(value)
- words = [word.lower() for word in words]
- # First look for the orientation
- orienter = None
- for orientation in ('landscape', 'portrait'):
- if orientation in words:
- orienter = getattr(reportlab.lib.pagesizes, orientation)
- words.remove(orientation)
- # We must have exactely one value left that matches a paper size
- pagesize = getattr(reportlab.lib.pagesizes, words[0].upper())
- # Now do the final touches
- if orienter:
- pagesize = orienter(pagesize)
- return pagesize
-
-
-class TextNode(RMLAttribute):
- """Return the text content of an element."""
-
- def get(self):
- if self.context.element.text is None:
- return u''
- return unicode(self.context.element.text).strip()
-
-
-class FirstLevelTextNode(TextNode):
- """Gets all the text content of an element without traversing into any
- child-elements."""
-
- def get(self):
- text = self.context.element.text or u''
- for child in self.context.element.getchildren():
- text += child.tail or u''
- return text.strip()
-
-
-class TextNodeSequence(Sequence, TextNode):
- """A sequence of values retrieved from the element's content."""
-
- def get(self):
- return self.fromUnicode(self.context.element.text)
-
-
-class TextNodeGrid(TextNodeSequence):
- """A grid/matrix of values retrieved from the element's content.
-
- The number of columns is specified for every case, but the number of rows
- is dynamic.
- """
-
- def __init__(self, columns=None, *args, **kw):
- super(TextNodeGrid, self).__init__(*args, **kw)
- self.columns = columns
-
- def fromUnicode(self, ustr):
- result = super(TextNodeGrid, self).fromUnicode(ustr)
- if len(result) % self.columns != 0:
- raise ValueError(
- 'Number of elements must be divisible by %i. %s' % (
- self.columns, getFileInfo(self.context)))
- return [result[i * self.columns:(i + 1) * self.columns]
- for i in range(len(result) / self.columns)]
-
-
-class RawXMLContent(RMLAttribute):
- """Retrieve the raw content of an element.
-
- Only some special element substitution will be made.
- """
-
- def __init__(self, *args, **kw):
- super(RawXMLContent, self).__init__(*args, **kw)
-
- def get(self):
- # ReportLab's paragraph parser does not like attributes from other
- # namespaces; sigh. So we have to improvize.
- text = etree.tounicode(self.context.element, pretty_print=False)
- text = text[text.find('>') + 1:text.rfind('<')]
- return text
-
-
-class XMLContent(RawXMLContent):
- """Same as 'RawXMLContent', except that the whitespace is normalized."""
-
- def get(self):
- text = super(XMLContent, self).get()
- return text.strip().replace('\t', ' ')
diff --git a/z3c/rml/canvas.py b/z3c/rml/canvas.py
deleted file mode 100644
index 416a2545..00000000
--- a/z3c/rml/canvas.py
+++ /dev/null
@@ -1,1012 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Page Drawing Related Element Processing
-"""
-import zope.interface
-import reportlab.pdfgen.canvas
-from z3c.rml import attr, directive, interfaces, occurence, stylesheet
-from z3c.rml import chart, flowable, form, page, special
-
-
-class IShape(interfaces.IRMLDirectiveSignature):
- """A shape to be drawn on the canvas."""
-
- x = attr.Measurement(
- title=u'X-Coordinate',
- description=(u'The X-coordinate of the lower-left position of the '
- u'shape.'),
- required=True)
-
- y = attr.Measurement(
- title=u'Y-Coordinate',
- description=(u'The Y-coordinate of the lower-left position of the '
- u'shape.'),
- required=True)
-
- fill = attr.Boolean(
- title=u'Fill',
- description=u'A flag to specify whether the shape should be filled.',
- required=False)
-
- stroke = attr.Boolean(
- title=u'Stroke',
- description=(u"A flag to specify whether the shape's outline should "
- u"be drawn."),
- required=False)
-
-
-class CanvasRMLDirective(directive.RMLDirective):
- callable = None
- attrMapping = None
-
- def process(self):
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- getattr(canvas, self.callable)(**kwargs)
-
-
-class ISaveState(interfaces.IRMLDirectiveSignature):
- """Saves the current canvas state."""
-
-class SaveState(CanvasRMLDirective):
- signature = ISaveState
- callable = 'saveState'
-
-
-class IRestoreState(interfaces.IRMLDirectiveSignature):
- """Saves the current canvas state."""
-
-class RestoreState(CanvasRMLDirective):
- signature = IRestoreState
- callable = 'restoreState'
-
-
-class IDrawString(interfaces.IRMLDirectiveSignature):
- """Draws a simple string (left aligned) onto the canvas at the specified
- location."""
-
- x = attr.Measurement(
- title=u'X-Coordinate',
- description=(u'The X-coordinate of the lower-left position of the '
- u'string.'),
- required=True)
-
- y = attr.Measurement(
- title=u'Y-Coordinate',
- description=(u'The Y-coordinate of the lower-left position of the '
- u'string.'),
- required=True)
-
- text = attr.RawXMLContent(
- title=u'Text',
- description=(u'The string/text that is put onto the canvas.'),
- required=True)
-
-class DrawString(CanvasRMLDirective, special.TextFlowables):
- signature = IDrawString
- callable = 'drawString'
-
- def process(self):
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- kwargs['text'] = self._getText(self.element, canvas).strip()
- getattr(canvas, self.callable)(**kwargs)
-
-class IDrawRightString(IDrawString):
- """Draws a simple string (right aligned) onto the canvas at the specified
- location."""
-
-class DrawRightString(DrawString):
- signature = IDrawRightString
- callable = 'drawRightString'
-
-
-class IDrawCenteredString(IDrawString):
- """Draws a simple string (centered aligned) onto the canvas at the specified
- location."""
-
-class DrawCenteredString(DrawString):
- signature = IDrawCenteredString
- callable = 'drawCentredString'
-
-
-class IDrawAlignedString(IDrawString):
- """Draws a simple string (aligned to the pivot character) onto the canvas
- at the specified location."""
-
- pivotChar = attr.Text(
- title=u'Text',
- description=(u'The string/text that is put onto the canvas.'),
- min_length=1,
- max_length=1,
- default=u'.',
- required=True)
-
-class DrawAlignedString(DrawString):
- signature = IDrawAlignedString
- callable = 'drawAlignedString'
-
-
-class IEllipse(IShape):
- """Draws an ellipse on the canvas."""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the ellipse.',
- required=True)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the ellipse.',
- required=True)
-
-class Ellipse(CanvasRMLDirective):
- signature = IEllipse
- callable = 'ellipse'
- attrMapping = {'x': 'x1', 'y': 'y1'}
-
- def process(self):
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- # Convert width and height to end locations
- kwargs['x2'] = kwargs['x1'] + kwargs['width']
- del kwargs['width']
- kwargs['y2'] = kwargs['y1'] + kwargs['height']
- del kwargs['height']
- getattr(canvas, self.callable)(**kwargs)
-
-
-class ICircle(IShape):
- """Draws a circle on the canvas."""
-
- radius = attr.Measurement(
- title=u'Radius',
- description=u'The radius of the circle.',
- required=True)
-
-class Circle(CanvasRMLDirective):
- signature = ICircle
- callable = 'circle'
- attrMapping = {'x': 'x_cen', 'y': 'y_cen', 'radius': 'r'}
-
-
-class IRectangle(IShape):
- """Draws an ellipse on the canvas."""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the rectangle.',
- required=True)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the rectangle.',
- required=True)
-
- round = attr.Measurement(
- title=u'Corner Radius',
- description=u'The radius of the rounded corners.',
- required=False)
-
- href = attr.Text(
- title=u'Link URL',
- description=u'When specified, the rectangle becomes a link to that URL.',
- required=False)
-
- destination = attr.Text(
- title=u'Link Destination',
- description=(u'When specified, the rectangle becomes a link to that '
- u'destination.'),
- required=False)
-
-class Rectangle(CanvasRMLDirective):
- signature = IRectangle
- callable = 'rect'
- attrMapping = {'round': 'radius'}
-
- def process(self):
- if 'round' in self.element.keys():
- self.callable = 'roundRect'
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- # Create a link
- url = kwargs.pop('href', None)
- if url:
- canvas.linkURL(
- url,
- (kwargs['x'], kwargs['y'],
- kwargs['x']+kwargs['width'], kwargs['y']+kwargs['height']))
- dest = kwargs.pop('destination', None)
- if dest:
- canvas.linkRect(
- '', dest,
- (kwargs['x'], kwargs['y'],
- kwargs['x']+kwargs['width'], kwargs['y']+kwargs['height']))
-
- # Render the rectangle
- getattr(canvas, self.callable)(**kwargs)
-
-class IGrid(interfaces.IRMLDirectiveSignature):
- """A shape to be drawn on the canvas."""
-
- xs = attr.Sequence(
- title=u'X-Coordinates',
- description=(u'A sequence x-coordinates that represent the vertical '
- u'line positions.'),
- value_type=attr.Measurement(),
- required=True)
-
- ys = attr.Sequence(
- title=u'Y-Coordinates',
- description=(u'A sequence y-coordinates that represent the horizontal '
- u'line positions.'),
- value_type=attr.Measurement(),
- required=True)
-
-
-class Grid(CanvasRMLDirective):
- signature = IGrid
- callable = 'grid'
- attrMapping = {'xs': 'xlist', 'ys': 'ylist'}
-
-
-class ILines(interfaces.IRMLDirectiveSignature):
- """A path of connected lines drawn on the canvas."""
-
- linelist = attr.TextNodeGrid(
- title=u'Line List',
- description=(u'A list of lines coordinates to draw.'),
- value_type=attr.Measurement(),
- columns=4,
- required=True)
-
-class Lines(CanvasRMLDirective):
- signature = ILines
- callable = 'lines'
-
-
-class ICurves(interfaces.IRMLDirectiveSignature):
- """A path of connected bezier curves drawn on the canvas."""
-
- curvelist = attr.TextNodeGrid(
- title=u'Curve List',
- description=(u'A list of curve coordinates to draw.'),
- value_type=attr.Measurement(),
- columns=8,
- required=True)
-
-class Curves(CanvasRMLDirective):
- signature = ICurves
- callable = 'bezier'
-
- def process(self):
- argset = self.getAttributeValues(valuesOnly=True)[0]
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- for args in argset:
- getattr(canvas, self.callable)(*args)
-
-
-class IImage(interfaces.IRMLDirectiveSignature):
- """Draws an external image on the canvas."""
-
- file = attr.Image(
- title=u'File',
- description=(u'Reference to the external file of the iamge.'),
- required=True)
-
- x = attr.Measurement(
- title=u'X-Coordinate',
- description=(u'The X-coordinate of the lower-left position of the '
- u'shape.'),
- required=True)
-
- y = attr.Measurement(
- title=u'Y-Coordinate',
- description=(u'The Y-coordinate of the lower-left position of the '
- u'shape.'),
- required=True)
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the image.',
- required=False)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the image.',
- required=False)
-
- showBoundary = attr.Boolean(
- title=u'Show Boundary',
- description=(u'A flag determining whether a border should be drawn '
- u'around the image.'),
- default=False,
- required=False)
-
- preserveAspectRatio = attr.Boolean(
- title=u'Preserve Aspect Ratio',
- description=(u"A flag determining whether the image's aspect ration "
- u"should be conserved under any circumstances."),
- default=False,
- required=False)
-
-class Image(CanvasRMLDirective):
- signature = IImage
- callable = 'drawImage'
- attrMapping = {'file': 'image'}
-
- def process(self):
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- preserve = kwargs.pop('preserveAspectRatio')
- show = kwargs.pop('showBoundary')
-
- if preserve:
- imgX, imgY = kwargs['image'].getSize()
-
- # Scale image correctly, if width and/or height were specified
- if 'width' in kwargs and 'height' not in kwargs:
- kwargs['height'] = imgY * kwargs['width'] / imgX
- elif 'height' in kwargs and 'width' not in kwargs:
- kwargs['width'] = imgX * kwargs['height'] / imgY
- elif 'width' in kwargs and 'height' in kwargs:
- if float(kwargs['width'])/kwargs['height'] > float(imgX)/imgY:
- kwargs['width'] = imgX * kwargs['height'] / imgY
- else:
- kwargs['height'] = imgY * kwargs['width'] / imgX
-
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- getattr(canvas, self.callable)(**kwargs)
-
- if show:
- width = kwargs.get('width', kwargs['image'].getSize()[0])
- height = kwargs.get('height', kwargs['image'].getSize()[1])
- canvas.rect(kwargs['x'], kwargs['y'], width, height)
-
-
-class IPlace(interfaces.IRMLDirectiveSignature):
- """Draws a set of flowables on the canvas within a given region."""
-
- x = attr.Measurement(
- title=u'X-Coordinate',
- description=(u'The X-coordinate of the lower-left position of the '
- u'place.'),
- required=True)
-
- y = attr.Measurement(
- title=u'Y-Coordinate',
- description=(u'The Y-coordinate of the lower-left position of the '
- u'place.'),
- required=True)
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the place.',
- required=False)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the place.',
- required=False)
-
-class Place(CanvasRMLDirective):
- signature = IPlace
-
- def process(self):
- x, y, width, height = self.getAttributeValues(
- select=('x', 'y', 'width', 'height'), valuesOnly=True)
- y += height
-
- flows = flowable.Flow(self.element, self.parent)
- flows.process()
-
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- for flow in flows.flow:
- flowWidth, flowHeight = flow.wrap(width, height)
- if flowWidth <= width and flowHeight <= height:
- y -= flowHeight
- flow.drawOn(canvas, x, y)
- height -= flowHeight
- else:
- raise ValueError("Not enough space")
-
-
-class IParam(interfaces.IRMLDirectiveSignature):
- """Sets one paramter for the text annotation."""
-
- name = attr.String(
- title=u'Name',
- description=u'The name of the paramter.',
- required=True)
-
- value = attr.TextNode(
- title=u'Value',
- description=(u'The parameter value.'),
- required=True)
-
-class Param(directive.RMLDirective):
- signature = IParam
-
- def process(self):
- args = dict(self.getAttributeValues())
- self.parent.params[args['name']] = args['value']
-
-
-class ITextAnnotation(interfaces.IRMLDirectiveSignature):
- """Writes a low-level text annotation into the PDF."""
- occurence.containing(
- occurence.ZeroOrMore('param', IParam))
-
- contents = attr.FirstLevelTextNode(
- title=u'Contents',
- description=u'The PDF commands that are inserted as annotation.',
- required=True)
-
-class TextAnnotation(CanvasRMLDirective):
- signature = ITextAnnotation
- factories = {'param': Param}
-
- paramTypes = {'escape': attr.Integer()}
-
- def process(self):
- contents = self.getAttributeValues(valuesOnly=True)[0]
- self.params = {}
- self.processSubDirectives()
- for name, type in self.paramTypes.items():
- if name in self.params:
- bound = type.bind(self)
- self.params[name] = bound.fromUnicode(self.params[name])
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- canvas.textAnnotation(contents, **self.params)
-
-
-class IMoveTo(interfaces.IRMLDirectiveSignature):
- """Move the path cursor to the specified location."""
-
- position = attr.TextNodeSequence(
- title=u'Position',
- description=u'Position to which the path pointer is moved to.',
- value_type=attr.Measurement(),
- min_length=2,
- max_length=2,
- required=True)
-
-class MoveTo(directive.RMLDirective):
- signature = IMoveTo
-
- def process(self):
- args = self.getAttributeValues(valuesOnly=True)
- self.parent.path.moveTo(*args[0])
-
-
-class ICurveTo(interfaces.IRMLDirectiveSignature):
- """Create a bezier curve from the current location to the specified one."""
-
- curvelist = attr.TextNodeGrid(
- title=u'Curve Specification',
- description=u'Describes the end position and the curve properties.',
- value_type=attr.Measurement(),
- columns=6,
- required=True)
-
-class CurveTo(directive.RMLDirective):
- signature = ICurveTo
-
- def process(self):
- argset = self.getAttributeValues(valuesOnly=True)[0]
- for args in argset:
- self.parent.path.curveTo(*args)
-
-class ICurvesTo(ICurveTo):
- pass
-directive.DeprecatedDirective(
- ICurvesTo,
- 'Available for ReportLab RML compatibility. Please use the "curveto" '
- 'directive instead.')
-
-
-class IPath(IShape):
- """Create a line path."""
- occurence.containing(
- occurence.ZeroOrMore('moveto', IMoveTo),
- occurence.ZeroOrMore('curveto', ICurveTo),
- occurence.ZeroOrMore('curvesto', ICurvesTo),
- )
-
- points = attr.TextNodeGrid(
- title=u'Points',
- description=(u'A list of coordinate points that define th path.'),
- value_type=attr.Measurement(),
- columns=2,
- required=True)
-
- close = attr.Boolean(
- title=u'Close Path',
- description=(u"A flag specifying whether the path should be closed."),
- default=False,
- required=False)
-
- clip = attr.Boolean(
- title=u'Clip Path',
- description=(u"A flag specifying whether the path should clip "
- u"overlapping elements."),
- default=False,
- required=False)
-
-class Path(CanvasRMLDirective):
- signature = IPath
- factories = {
- 'moveto': MoveTo,
- 'curveto': CurveTo,
- 'curvesto': CurveTo
- }
-
- def processPoints(self, text):
- if text.strip() == '':
- return
- bound = self.signature['points'].bind(self)
- for coords in bound.fromUnicode(text):
- self.path.lineTo(*coords)
-
- def process(self):
- kwargs = dict(self.getAttributeValues(ignore=('points',)))
-
- # Start the path and set the cursor to the start location.
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- self.path = canvas.beginPath()
- self.path.moveTo(kwargs.pop('x'), kwargs.pop('y'))
-
- # Process the text before the first sub-directive.
- if self.element.text is not None:
- self.processPoints(self.element.text)
- # Handle each sub-directive.
- for directive in self.element.getchildren():
- if directive.tag in self.factories:
- self.factories[directive.tag](directive, self).process()
- # If there is more text after sub-directive, process it.
- if directive.tail is not None:
- self.processPoints(directive.tail)
-
- if kwargs.pop('close', False):
- self.path.close()
-
- if kwargs.pop('clip', False):
- canvas.clipPath(self.path, **kwargs)
- else:
- canvas.drawPath(self.path, **kwargs)
-
-
-class IFill(interfaces.IRMLDirectiveSignature):
- """Set the fill color."""
-
- color = attr.Color(
- title=u'Color',
- description=(u'The color value to be set.'),
- required=True)
-
-class Fill(CanvasRMLDirective):
- signature = IFill
- callable = 'setFillColor'
- attrMapping = {'color': 'aColor'}
-
-
-class IStroke(interfaces.IRMLDirectiveSignature):
- """Set the stroke/line color."""
-
- color = attr.Color(
- title=u'Color',
- description=(u'The color value to be set.'),
- required=True)
-
-class Stroke(CanvasRMLDirective):
- signature = IStroke
- callable = 'setStrokeColor'
- attrMapping = {'color': 'aColor'}
-
-
-class ISetFont(interfaces.IRMLDirectiveSignature):
- """Set the font name and/or size."""
-
- name = attr.String(
- title=u'Font Name',
- description=(u'The name of the font as it was registered.'),
- required=True)
-
- size = attr.Measurement(
- title=u'Size',
- description=(u'The font size.'),
- required=True)
-
- leading = attr.Measurement(
- title=u'Leading',
- description=(u'The font leading.'),
- required=False)
-
-class SetFont(CanvasRMLDirective):
- signature = ISetFont
- callable = 'setFont'
- attrMapping = {'name': 'psfontname'}
-
-
-class ISetFontSize(interfaces.IRMLDirectiveSignature):
- """Set the font size."""
-
- size = attr.Measurement(
- title=u'Size',
- description=(u'The font size.'),
- required=True)
-
- leading = attr.Measurement(
- title=u'Leading',
- description=(u'The font leading.'),
- required=False)
-
-class SetFontSize(CanvasRMLDirective):
- signature = ISetFontSize
- callable = 'setFontSize'
-
-
-class IScale(interfaces.IRMLDirectiveSignature):
- """Scale the drawing using x and y scaling factors."""
-
- sx = attr.Float(
- title=u'X-Scaling-Factor',
- description=(u'The scaling factor applied on x-coordinates.'),
- default=1,
- required=False)
-
- sy = attr.Float(
- title=u'Y-Scaling-Factor',
- description=(u'The scaling factor applied on y-coordinates.'),
- default=1,
- required=False)
-
-class Scale(CanvasRMLDirective):
- signature = IScale
- callable = 'scale'
- attrMapping = {'sx': 'x', 'sy': 'y'}
-
-
-class ITranslate(interfaces.IRMLDirectiveSignature):
- """Translate the drawing coordinates by the specified x and y offset."""
-
- dx = attr.Measurement(
- title=u'X-Offset',
- description=(u'The amount to move the drawing to the right.'),
- required=True)
-
- dy = attr.Measurement(
- title=u'Y-Offset',
- description=(u'The amount to move the drawing upward.'),
- required=True)
-
-class Translate(CanvasRMLDirective):
- signature = ITranslate
- callable = 'translate'
-
-
-class IRotate(interfaces.IRMLDirectiveSignature):
- """Rotate the drawing counterclockwise."""
-
- degrees = attr.Measurement(
- title=u'Angle',
- description=(u'The angle in degrees.'),
- required=True)
-
-class Rotate(CanvasRMLDirective):
- signature = IRotate
- callable = 'rotate'
- attrMapping = {'degrees': 'theta'}
-
-
-class ISkew(interfaces.IRMLDirectiveSignature):
- """Skew the drawing."""
-
- alpha = attr.Measurement(
- title=u'Alpha',
- description=(u'The amount to skew the drawing in the horizontal.'),
- required=True)
-
- beta = attr.Measurement(
- title=u'Beta',
- description=(u'The amount to skew the drawing in the vertical.'),
- required=True)
-
-class Skew(CanvasRMLDirective):
- signature = ISkew
- callable = 'skew'
-
-
-class ITransform(interfaces.IRMLDirectiveSignature):
- """A full 2-D matrix transformation"""
-
- matrix = attr.TextNodeSequence(
- title=u'Matrix',
- description=u'The transformation matrix.',
- value_type=attr.Float(),
- min_length=6,
- max_length=6,
- required=True)
-
-class Transform(CanvasRMLDirective):
- signature = ITransform
-
- def process(self):
- args = self.getAttributeValues(valuesOnly=True)
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- canvas.transform(*args[0])
-
-
-class ILineMode(interfaces.IRMLDirectiveSignature):
- """Set the line mode for the following graphics elements."""
-
- width = attr.Measurement(
- title=u'Width',
- description=(u'The line width.'),
- required=False)
-
- dash = attr.Sequence(
- title=u'Dash-Pattern',
- description=(u'The dash-pattern of a line.'),
- value_type=attr.Measurement(),
- required=False)
-
- miterLimit = attr.Measurement(
- title=u'Miter Limit',
- description=(u'The ???.'),
- required=False)
-
- join = attr.Choice(
- title=u'Join',
- description=u'The way lines are joined together.',
- choices=interfaces.JOIN_CHOICES,
- required=False)
-
- cap = attr.Choice(
- title=u'Cap',
- description=u'The cap is the desciption of how the line-endings look.',
- choices=interfaces.CAP_CHOICES,
- required=False)
-
-class LineMode(CanvasRMLDirective):
- signature = ILineMode
-
- def process(self):
- kw = dict(self.getAttributeValues())
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- if 'width' in kw:
- canvas.setLineWidth(kw['width'])
- if 'join' in kw:
- canvas.setLineJoin(kw['join'])
- if 'cap' in kw:
- canvas.setLineCap(kw['cap'])
- if 'miterLimit' in kw:
- canvas.setMiterLimit(kw['miterLimit'])
- if 'dash' in kw:
- canvas.setDash(kw['dash'])
-
-
-class IBookmark(interfaces.IRMLDirectiveSignature):
- """
- This creates a bookmark to the current page which can be referred to with
- the given key elsewhere. (Used inside a page drawing.)
- """
-
- name = attr.Text(
- title=u'Name',
- description=u'The name of the bookmark.',
- required=True)
-
- fit = attr.Choice(
- title=u'Fit',
- description=u'The Fit Type.',
- choices=('XYZ', 'Fit', 'FitH', 'FitV', 'FitR'),
- required=False)
-
- zoom = attr.Float(
- title=u'Zoom',
- description=u'The zoom level when clicking on the bookmark.',
- required=False)
-
- x = attr.Measurement(
- title=u'X-Position',
- description=u'The x-position.',
- required=False)
-
- y = attr.Measurement(
- title=u'Y-Position',
- description=u'The y-position.',
- required=False)
-
-class Bookmark(CanvasRMLDirective):
- signature = IBookmark
-
- def process(self):
- args = dict(self.getAttributeValues())
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- args['left'], args['top'] = canvas.absolutePosition(args['x'], args['y'])
- canvas.bookmarkPage(**args)
-
-
-class IPlugInGraphic(interfaces.IRMLDirectiveSignature):
- """Inserts a custom graphic developed in Python."""
-
- module = attr.String(
- title=u'Module',
- description=u'The Python module in which the flowable is located.',
- required=True)
-
- function = attr.String(
- title=u'Function',
- description=(u'The name of the factory function within the module '
- u'that returns the custom flowable.'),
- required=True)
-
- params = attr.TextNode(
- title=u'Parameters',
- description=(u'A list of parameters encoded as a long string.'),
- required=False)
-
-class PlugInGraphic(CanvasRMLDirective):
- signature = IPlugInGraphic
-
- def process(self):
- modulePath, functionName, params = self.getAttributeValues(
- valuesOnly=True)
- module = __import__(modulePath, {}, {}, [modulePath])
- function = getattr(module, functionName)
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- function(canvas, params)
-
-
-class IDrawing(interfaces.IRMLDirectiveSignature):
- """A container directive for all directives that draw directly on the
- cnavas."""
- occurence.containing(
- # State Manipulation
- occurence.ZeroOrMore('saveState', ISaveState),
- occurence.ZeroOrMore('restoreState', IRestoreState),
- # String Drawing
- occurence.ZeroOrMore('drawString', IDrawString),
- occurence.ZeroOrMore('drawRightString', IDrawRightString),
- occurence.ZeroOrMore('drawCenteredString', IDrawCenteredString),
- occurence.ZeroOrMore('drawCentredString', IDrawCenteredString),
- occurence.ZeroOrMore('drawAlignedString', IDrawAlignedString),
- # Drawing Operations
- occurence.ZeroOrMore('ellipse', IEllipse),
- occurence.ZeroOrMore('circle', ICircle),
- occurence.ZeroOrMore('rect', IRectangle),
- occurence.ZeroOrMore('grid', IGrid),
- occurence.ZeroOrMore('lines', ILines),
- occurence.ZeroOrMore('curves', ICurves),
- occurence.ZeroOrMore('image', IImage),
- occurence.ZeroOrMore('place', IPlace),
- occurence.ZeroOrMore('textAnnotation', ITextAnnotation),
- occurence.ZeroOrMore('path', IPath),
- # State Change Operations
- occurence.ZeroOrMore('fill', IFill),
- occurence.ZeroOrMore('stroke', IStroke),
- occurence.ZeroOrMore('setFont', ISetFont),
- occurence.ZeroOrMore('setFontSize', ISetFontSize),
- occurence.ZeroOrMore('scale', IScale),
- occurence.ZeroOrMore('translate', ITranslate),
- occurence.ZeroOrMore('rotate', IRotate),
- occurence.ZeroOrMore('skew', ISkew),
- occurence.ZeroOrMore('transform', ITransform),
- occurence.ZeroOrMore('lineMode', ILineMode),
- # Form Field Elements
- occurence.ZeroOrMore('barCode', form.IBarCode),
- occurence.ZeroOrMore('textField', form.ITextField),
- occurence.ZeroOrMore('buttonField', form.IButtonField),
- occurence.ZeroOrMore('selectField', form.ISelectField),
- # Charts
- occurence.ZeroOrMore('barChart', chart.IBarChart),
- occurence.ZeroOrMore('barChart3D', chart.IBarChart3D),
- occurence.ZeroOrMore('linePlot', chart.ILinePlot),
- occurence.ZeroOrMore('linePlot3D', chart.ILinePlot3D),
- occurence.ZeroOrMore('pieChart', chart.IPieChart),
- occurence.ZeroOrMore('pieChart3D', chart.IPieChart3D),
- occurence.ZeroOrMore('spiderChart', chart.ISpiderChart),
- # Misc
- occurence.ZeroOrMore('bookmark', IBookmark),
- occurence.ZeroOrMore('plugInGraphic', IPlugInGraphic),
- )
-
-class Drawing(directive.RMLDirective):
- signature = IDrawing
-
- factories = {
- # State Management
- 'saveState': SaveState,
- 'restoreState': RestoreState,
- # Drawing Strings
- 'drawString': DrawString,
- 'drawRightString': DrawRightString,
- 'drawCenteredString': DrawCenteredString,
- 'drawCentredString': DrawCenteredString,
- 'drawAlignedString': DrawAlignedString,
- # Drawing Operations
- 'ellipse': Ellipse,
- 'circle': Circle,
- 'rect': Rectangle,
- 'grid': Grid,
- 'lines': Lines,
- 'curves': Curves,
- 'image': Image,
- 'place': Place,
- 'textAnnotation': TextAnnotation,
- 'path': Path,
- # Form Field Elements
- 'barCode': form.BarCode,
- 'textField': form.TextField,
- 'buttonField': form.ButtonField,
- 'selectField': form.SelectField,
- # State Change Operations
- 'fill': Fill,
- 'stroke': Stroke,
- 'setFont': SetFont,
- 'setFontSize': SetFontSize,
- 'scale': Scale,
- 'translate': Translate,
- 'rotate': Rotate,
- 'skew': Skew,
- 'transform': Transform,
- 'lineMode': LineMode,
- # Charts
- 'barChart': chart.BarChart,
- 'barChart3D': chart.BarChart3D,
- 'linePlot': chart.LinePlot,
- 'linePlot3D': chart.LinePlot3D,
- 'pieChart': chart.PieChart,
- 'pieChart3D': chart.PieChart3D,
- 'spiderChart': chart.SpiderChart,
- # Misc
- 'bookmark': Bookmark,
- 'plugInGraphic': PlugInGraphic,
- }
-
-
-class IPageDrawing(IDrawing):
- """Draws directly on the content of one page's canvas. Every call of this
- directive creates a new page."""
-
- occurence.containing(
- #'mergePage': IMergePage,
- *IDrawing.getTaggedValue('directives'))
-
-class PageDrawing(Drawing):
- signature = IDrawing
-
- factories = Drawing.factories.copy()
- factories.update({
- 'mergePage': page.MergePage
- })
-
- def process(self):
- super(Drawing, self).process()
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- canvas.showPage()
-
-
-class IPageInfo(interfaces.IRMLDirectiveSignature):
- """Set's up page-global settings."""
-
- pageSize = attr.PageSize(
- title=u'Page Size',
- description=(u'The page size of all pages within this document.'),
- required=True)
-
-class PageInfo(CanvasRMLDirective):
- signature=IPageInfo
- callable = 'setPageSize'
- attrMapping = {'pageSize': 'size'}
diff --git a/z3c/rml/chart.py b/z3c/rml/chart.py
deleted file mode 100644
index f0f93c61..00000000
--- a/z3c/rml/chart.py
+++ /dev/null
@@ -1,1662 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Chart Element Processing
-"""
-import reportlab.lib.formatters
-from reportlab.graphics import shapes
-from reportlab.graphics.charts import barcharts, lineplots, piecharts
-from reportlab.graphics.charts import spider, doughnut
-from z3c.rml import attr, directive, interfaces, occurence
-
-# Patches against Reportlab 2.0
-lineplots.Formatter = reportlab.lib.formatters.Formatter
-
-
-class PropertyItem(directive.RMLDirective):
-
- def process(self):
- attrs = dict(self.getAttributeValues())
- self.parent.dataList.append(attrs)
-
-
-class PropertyCollection(directive.RMLDirective):
- propertyName = None
-
- def processAttributes(self):
- prop = getattr(self.parent.context, self.propertyName)
- # Get global properties
- for name, value in self.getAttributeValues():
- setattr(prop, name, value)
-
- def process(self):
- self.processAttributes()
- # Get item specific properties
- prop = getattr(self.parent.context, self.propertyName)
- self.dataList = []
- self.processSubDirectives()
- for index, data in enumerate(self.dataList):
- for name, value in data.items():
- setattr(prop[index], name, value)
-
-
-class IText(interfaces.IRMLDirectiveSignature):
- """Draw a text on the chart."""
-
- x = attr.Measurement(
- title=u'X-Coordinate',
- description=(u'The X-coordinate of the lower-left position of the '
- u'text.'),
- required=True)
-
- y = attr.Measurement(
- title=u'Y-Coordinate',
- description=(u'The Y-coordinate of the lower-left position of the '
- u'text.'),
- required=True)
-
- angle = attr.Float(
- title=u'Rotation Angle',
- description=(u'The angle about which the text will be rotated.'),
- required=False)
-
- text = attr.TextNode(
- title=u'Text',
- description=u'The text to be printed.',
- required=True)
-
- fontName = attr.String(
- title=u'Font Name',
- description=u'The name of the font.',
- required=False)
-
- fontSize = attr.Measurement(
- title=u'Font Size',
- description=u'The font size for the text.',
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=u'The color in which the text will appear.',
- required=False)
-
- textAnchor = attr.Choice(
- title=u'Text Anchor',
- description=u'The position in the text to which the coordinates refer.',
- choices=('start', 'middle', 'end', 'boxauto'),
- required=False)
-
-
-class Text(directive.RMLDirective):
- signature = IText
-
- def process(self):
- attrs = dict(self.getAttributeValues())
- string = shapes.String(
- attrs.pop('x'), attrs.pop('y'), attrs.pop('text'))
- angle = attrs.pop('angle', 0)
- for name, value in attrs.items():
- setattr(string, name, value)
- group = shapes.Group(string)
- group.translate(0,0)
- group.rotate(angle)
- self.parent.parent.drawing.add(group)
-
-
-class ITexts(interfaces.IRMLDirectiveSignature):
- """A set of texts drawn on the chart."""
- occurence.containing(
- occurence.ZeroOrMore('text', IText)
- )
-
-class Texts(directive.RMLDirective):
- signature = ITexts
- factories = {'text': Text}
-
-
-class Series(directive.RMLDirective):
-
- def process(self):
- attrs = self.getAttributeValues(valuesOnly=True)
- self.parent.data.append(attrs[0])
-
-
-class Data(directive.RMLDirective):
- series = None
-
- def process(self):
- self.data = []
- self.factories = {'series': self.series}
- self.processSubDirectives()
- self.parent.context.data = self.data
-
-
-class ISeries1D(interfaces.IRMLDirectiveSignature):
- """A one-dimensional series."""
-
- values = attr.TextNodeSequence(
- title=u'Values',
- description=u"Numerical values representing the series' data.",
- value_type=attr.Float(),
- required=True)
-
-class Series1D(Series):
- signature = ISeries1D
-
-
-class IData1D(interfaces.IRMLDirectiveSignature):
- """A 1-D data set."""
- occurence.containing(
- occurence.OneOrMore('series', ISeries1D)
- )
-
-class Data1D(Data):
- signature = IData1D
- series = Series1D
-
-
-class ISingleData1D(interfaces.IRMLDirectiveSignature):
- """A 1-D data set."""
- occurence.containing(
- occurence.One('series', ISeries1D)
- )
-
-class SingleData1D(Data1D):
- signature = ISingleData1D
-
- def process(self):
- self.data = []
- self.factories = {'series': self.series}
- self.processSubDirectives()
- self.parent.context.data = self.data[0]
-
-
-class ISeries2D(interfaces.IRMLDirectiveSignature):
- """A two-dimensional series."""
-
- values = attr.TextNodeGrid(
- title=u'Values',
- description=u"Numerical values representing the series' data.",
- value_type=attr.Float(),
- columns=2,
- required=True)
-
-class Series2D(Series):
- signature = ISeries2D
-
-
-class IData2D(interfaces.IRMLDirectiveSignature):
- """A 2-D data set."""
- occurence.containing(
- occurence.OneOrMore('series', ISeries2D)
- )
-
-class Data2D(Data):
- signature = IData2D
- series = Series2D
-
-
-class IBar(interfaces.IRMLDirectiveSignature):
- """Define the look of a bar."""
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=u'The color in which the bar border is drawn.',
- required=False)
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The width of the bar border line.',
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=u'The color with which the bar is filled.',
- required=False)
-
-class Bar(PropertyItem):
- signature = IBar
-
-class IBars(IBar):
- """Collection of bar subscriptions."""
- occurence.containing(
- occurence.ZeroOrMore('bar', IBar)
- )
-
-class Bars(PropertyCollection):
- signature = IBars
- propertyName = 'bars'
- factories = {'bar': Bar}
-
-
-class ILabelBase(interfaces.IRMLDirectiveSignature):
-
- dx = attr.Measurement(
- title=u'Horizontal Extension',
- description=(u'The width of the label.'),
- required=False)
-
- dy = attr.Measurement(
- title=u'Vertical Extension',
- description=(u'The height of the label.'),
- required=False)
-
- angle = attr.Float(
- title=u'Angle',
- description=(u'The angle to rotate the label.'),
- required=False)
-
- boxAnchor = attr.Choice(
- title=u'Box Anchor',
- description=(u'The position relative to the label.'),
- choices=('nw','n','ne','w','c','e','sw','s','se', 'autox', 'autoy'),
- required=False)
-
- boxStrokeColor = attr.Color(
- title=u'Box Stroke Color',
- description=(u'The color of the box border line.'),
- required=False)
-
- boxStrokeWidth = attr.Measurement(
- title=u'Box Stroke Width',
- description=u'The width of the box border line.',
- required=False)
-
- boxFillColor = attr.Color(
- title=u'Box Fill Color',
- description=(u'The color in which the box is filled.'),
- required=False)
-
- boxTarget = attr.Text(
- title=u'Box Target',
- description=u'The box target.',
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=(u'The color in which the label is filled.'),
- required=False)
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=(u'The color of the label.'),
- required=False)
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The width of the label line.',
- required=False)
-
- fontName = attr.String(
- title=u'Font Name',
- description=u'The font used to print the value.',
- required=False)
-
- fontSize = attr.Measurement(
- title=u'Font Size',
- description=u'The size of the value text.',
- required=False)
-
- leading = attr.Measurement(
- title=u'Leading',
- description=(u'The height of a single text line. It includes '
- u'character height.'),
- required=False)
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width the label.',
- required=False)
-
- maxWidth = attr.Measurement(
- title=u'Maximum Width',
- description=u'The maximum width the label.',
- required=False)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height the label.',
- required=False)
-
- textAnchor = attr.Choice(
- title=u'Text Anchor',
- description=u'The position in the text to which the coordinates refer.',
- choices=('start', 'middle', 'end', 'boxauto'),
- required=False)
-
- visible = attr.Boolean(
- title=u'Visible',
- description=u'A flag making the label text visible.',
- required=False)
-
- leftPadding = attr.Measurement(
- title=u'Left Padding',
- description=u'The size of the padding on the left side.',
- required=False)
-
- rightPadding = attr.Measurement(
- title=u'Right Padding',
- description=u'The size of the padding on the right side.',
- required=False)
-
- topPadding = attr.Measurement(
- title=u'Top Padding',
- description=u'The size of the padding on the top.',
- required=False)
-
- bottomPadding = attr.Measurement(
- title=u'Bottom Padding',
- description=u'The size of the padding on the bottom.',
- required=False)
-
-
-class IPositionLabelBase(ILabelBase):
-
- x = attr.Measurement(
- title=u'X-Coordinate',
- description=(u'The X-coordinate of the lower-left position of the '
- u'label.'),
- required=False)
-
- y = attr.Measurement(
- title=u'Y-Coordinate',
- description=(u'The Y-coordinate of the lower-left position of the '
- u'label.'),
- required=False)
-
-
-class ILabel(IPositionLabelBase):
- """A label for the chart on an axis."""
-
- text = attr.TextNode(
- title=u'Text',
- description=u'The label text to be displayed.',
- required=True)
-
-class Label(PropertyItem):
- signature = ILabel
-
-class IBarLabels(ILabelBase):
- """A set of labels for a bar chart"""
- occurence.containing(
- occurence.ZeroOrMore('label', ILabel)
- )
-
-class BarLabels(PropertyCollection):
- signature = IBarLabels
- propertyName = 'barLabels'
- factories = {'label': Label}
- name = 'barLabels'
-
-class ILabels(IPositionLabelBase):
- """A set of labels of an axis."""
- occurence.containing(
- occurence.ZeroOrMore('label', ILabel)
- )
-
-class Labels(PropertyCollection):
- signature = ILabels
- propertyName = 'labels'
- factories = {'label': Label}
-
-
-class IAxis(interfaces.IRMLDirectiveSignature):
- occurence.containing(
- occurence.ZeroOrMore('labels', ILabels)
- )
-
- visible = attr.Boolean(
- title=u'Visible',
- description=u'When true, draw the entire axis with all details.',
- required=False)
-
- visibleAxis = attr.Boolean(
- title=u'Visible Axis',
- description=u'When true, draw the axis line.',
- required=False)
-
- visibleTicks = attr.Boolean(
- title=u'Visible Ticks',
- description=u'When true, draw the axis ticks on the line.',
- required=False)
-
- visibleLabels = attr.Boolean(
- title=u'Visible Labels',
- description=u'When true, draw the axis labels.',
- required=False)
-
- visibleGrid = attr.Boolean(
- title=u'Visible Grid',
- description=u'When true, draw the grid lines for the axis.',
- required=False)
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The width of axis line and ticks.',
- required=False)
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=u'The color in which the axis line and ticks are drawn.',
- required=False)
-
- strokeDashArray = attr.Sequence(
- title=u'Stroke Dash Array',
- description=u'The dash array that is used for the axis line and ticks.',
- value_type=attr.Float(),
- required=False)
-
- gridStrokeWidth = attr.Measurement(
- title=u'Grid Stroke Width',
- description=u'The width of the grid lines.',
- required=False)
-
- gridStrokeColor = attr.Color(
- title=u'Grid Stroke Color',
- description=u'The color in which the grid lines are drawn.',
- required=False)
-
- gridStrokeDashArray = attr.Sequence(
- title=u'Grid Stroke Dash Array',
- description=u'The dash array that is used for the grid lines.',
- value_type=attr.Float(),
- required=False)
-
- gridStart = attr.Measurement(
- title=u'Grid Start',
- description=(u'The start of the grid lines with respect to the '
- u'axis origin.'),
- required=False)
-
- gridEnd = attr.Measurement(
- title=u'Grid End',
- description=(u'The end of the grid lines with respect to the '
- u'axis origin.'),
- required=False)
-
- style = attr.Choice(
- title=u'Style',
- description=u'The plot style of the common categories.',
- choices=('parallel', 'stacked', 'parallel_3d'),
- required=False)
-
-
-class Axis(directive.RMLDirective):
- signature = IAxis
- name = ''
- factories = {'labels': Labels}
-
- def process(self):
- self.context = axis = getattr(self.parent.context, self.name)
- for name, value in self.getAttributeValues():
- setattr(axis, name, value)
- self.processSubDirectives()
-
-
-class IName(interfaces.IRMLDirectiveSignature):
- """A category name"""
- text = attr.TextNode(
- title=u'Text',
- description=u'The text value that is the name.',
- required=True)
-
-class Name(directive.RMLDirective):
- signature = IName
-
- def process(self):
- text = self.getAttributeValues(valuesOnly=True)[0]
- self.parent.names.append(text)
-
-
-class ICategoryNames(interfaces.IRMLDirectiveSignature):
- """A list of category names."""
- occurence.containing(
- occurence.OneOrMore('name', IName),
- )
-
-class CategoryNames(directive.RMLDirective):
- signature = ICategoryNames
- factories = {'name': Name}
-
- def process(self):
- self.names = []
- self.processSubDirectives()
- self.parent.context.categoryNames = self.names
-
-
-class ICategoryAxis(IAxis):
- """An axis displaying categories (instead of numerical values)."""
- occurence.containing(
- occurence.ZeroOrOne('categoryNames', ICategoryNames),
- *IAxis.queryTaggedValue('directives', ())
- )
-
- categoryNames = attr.Sequence(
- title=u'Category Names',
- description=u'A simple list of category names.',
- value_type=attr.Text(),
- required=False)
-
- joinAxis = attr.Boolean(
- title=u'Join Axis',
- description=u'When true, both axes join together.',
- required=False)
-
- joinAxisPos = attr.Measurement(
- title=u'Join Axis Position',
- description=u'The position at which the axes should join together.',
- required=False)
-
- reverseDirection = attr.Boolean(
- title=u'Reverse Direction',
- description=u'A flag to reverse the direction of category names.',
- required=False)
-
- labelAxisMode = attr.Choice(
- title=u'Label Axis Mode',
- description=u'Defines the relative position of the axis labels.',
- choices=('high', 'low', 'axis'),
- required=False)
-
- tickShift = attr.Boolean(
- title=u'Tick Shift',
- description=(u'When true, place the ticks in the center of a '
- u'category instead the beginning and end.'),
- required=False)
-
-class CategoryAxis(Axis):
- signature = ICategoryAxis
- name = 'categoryAxis'
- factories = Axis.factories.copy()
- factories.update({
- 'categoryNames': CategoryNames,
- })
-
-
-class IXCategoryAxis(ICategoryAxis):
- """X-Category Axis"""
-
- tickUp = attr.Measurement(
- title=u'Tick Up',
- description=u'Length of tick above the axis line.',
- required=False)
-
- tickDown = attr.Measurement(
- title=u'Tick Down',
- description=u'Length of tick below the axis line.',
- required=False)
-
- joinAxisMode = attr.Choice(
- title=u'Join Axis Mode',
- description=u'Mode for connecting axes.',
- choices=('bottom', 'top', 'value', 'points', 'None'),
- required=False)
-
-class XCategoryAxis(CategoryAxis):
- signature = IXCategoryAxis
-
-
-class IYCategoryAxis(ICategoryAxis):
- """Y-Category Axis"""
-
- tickLeft = attr.Measurement(
- title=u'Tick Left',
- description=u'Length of tick left to the axis line.',
- required=False)
-
- tickRight = attr.Measurement(
- title=u'Tick Right',
- description=u'Length of tick right to the axis line.',
- required=False)
-
- joinAxisMode = attr.Choice(
- title=u'Join Axis Mode',
- description=u'Mode for connecting axes.',
- choices=('bottom', 'top', 'value', 'points', 'None'),
- required=False)
-
-class YCategoryAxis(CategoryAxis):
- signature = IYCategoryAxis
-
-
-class IValueAxis(IAxis):
-
- forceZero = attr.Boolean(
- title=u'Force Zero',
- description=u'When set, the range will contain the origin.',
- required=False)
-
- minimumTickSpacing = attr.Measurement(
- title=u'Minimum Tick Spacing',
- description=u'The minimum distance between ticks.',
- required=False)
-
- maximumTicks = attr.Integer(
- title=u'Maximum Ticks',
- description=u'The maximum number of ticks to be shown.',
- required=False)
-
- labelTextFormat = attr.String(
- title=u'Label Text Format',
- description=u'Formatting string for axis labels.',
- required=False)
-
- labelTextPostFormat = attr.Text(
- title=u'Label Text Post Format',
- description=u'An additional formatting string.',
- required=False)
-
- labelTextScale = attr.Float(
- title=u'Label Text Scale',
- description=u'The sclaing factor for the label tick values.',
- required=False)
-
- valueMin = attr.Float(
- title=u'Minimum Value',
- description=u'The smallest value on the axis.',
- required=False)
-
- valueMax = attr.Float(
- title=u'Maximum Value',
- description=u'The largest value on the axis.',
- required=False)
-
- valueStep = attr.Float(
- title=u'Value Step',
- description=u'The step size between ticks',
- required=False)
-
- valueSteps = attr.Sequence(
- title=u'Step Sizes',
- description=u'List of step sizes between ticks.',
- value_type = attr.Float(),
- required=False)
-
- rangeRound = attr.Choice(
- title=u'Range Round',
- description=u'Method to be used to round the range values.',
- choices=('none', 'both', 'ceiling', 'floor'),
- required=False)
-
- zrangePref = attr.Float(
- title=u'Zero Range Preference',
- description=u'Zero range axis limit preference.',
- required=False)
-
-class ValueAxis(Axis):
- signature = IValueAxis
- name = 'valueAxis'
-
-
-class IXValueAxis(IValueAxis):
- """X-Value Axis"""
-
- tickUp = attr.Measurement(
- title=u'Tick Up',
- description=u'Length of tick above the axis line.',
- required=False)
-
- tickDown = attr.Measurement(
- title=u'Tick Down',
- description=u'Length of tick below the axis line.',
- required=False)
-
- joinAxis = attr.Boolean(
- title=u'Join Axis',
- description=u'Whether to join the axes.',
- required=False)
-
- joinAxisMode = attr.Choice(
- title=u'Join Axis Mode',
- description=u'Mode for connecting axes.',
- choices=('bottom', 'top', 'value', 'points', 'None'),
- required=False)
-
- joinAxisPos = attr.Measurement(
- title=u'Join Axis Position',
- description=u'The position in the plot at which to join the axes.',
- required=False)
-
-class XValueAxis(ValueAxis):
- signature = IXValueAxis
-
-class LineXValueAxis(XValueAxis):
- name = 'xValueAxis'
-
-class IYValueAxis(IValueAxis):
- """Y-Value Axis"""
-
- tickLeft = attr.Measurement(
- title=u'Tick Left',
- description=u'Length of tick left to the axis line.',
- required=False)
-
- tickRight = attr.Measurement(
- title=u'Tick Right',
- description=u'Length of tick right to the axis line.',
- required=False)
-
- joinAxis = attr.Boolean(
- title=u'Join Axis',
- description=u'Whether to join the axes.',
- required=False)
-
- joinAxisMode = attr.Choice(
- title=u'Join Axis Mode',
- description=u'Mode for connecting axes.',
- choices=('bottom', 'top', 'value', 'points', 'None'),
- required=False)
-
- joinAxisPos = attr.Measurement(
- title=u'Join Axis Position',
- description=u'The position in the plot at which to join the axes.',
- required=False)
-
-
-class YValueAxis(ValueAxis):
- signature = IYValueAxis
-
-class LineYValueAxis(YValueAxis):
- name = 'yValueAxis'
-
-
-class ILineLabels(IPositionLabelBase):
- """A set of labels of an axis."""
- occurence.containing(
- occurence.ZeroOrMore('label', ILabel)
- )
-
-class LineLabels(PropertyCollection):
- signature = ILineLabels
- propertyName = 'lineLabels'
- factories = {'label': Label}
-
-
-class ILineBase(interfaces.IRMLDirectiveSignature):
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The width of the plot line.',
- required=False)
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=u'The color of the plot line.',
- required=False)
-
- strokeDashArray = attr.Sequence(
- title=u'Stroke Dash Array',
- description=u'The dash array of the plot line.',
- value_type = attr.Float(),
- required=False)
-
- symbol = attr.Symbol(
- title=u'Symbol',
- description=u'The symbol to be used for every data point in the plot.',
- required=False)
-
-class ILine(ILineBase):
- """A line description of a series of a line plot."""
-
- name = attr.Text(
- title=u'Name',
- description=u'The name of the line.',
- required=False)
-
-class Line(PropertyItem):
- signature = ILine
-
-class ILines(ILineBase):
- """The set of all line descriptions in the line plot."""
- occurence.containing(
- occurence.OneOrMore('line', ILine),
- )
-
-class Lines(PropertyCollection):
- signature = ILines
- propertyName = 'lines'
- factories = {'line': Line}
-
-
-class ISliceLabel(ILabelBase):
- """The label of a slice within a bar chart."""
-
- text = attr.TextNode(
- title=u'Text',
- description=u'The label text to be displayed.',
- required=True)
-
-class SliceLabel(Label):
- signature = ISliceLabel
-
- def process(self):
- for name, value in self.getAttributeValues():
- self.parent.context['label_'+name] = value
- # Now we do not have simple labels anymore
- self.parent.parent.parent.context.simpleLabels = False
-
-
-class ISlicePointer(interfaces.IRMLDirectiveSignature):
- """A pointer to a slice in a pie chart."""
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=u'The color of the pointer line.',
- required=False)
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The wodth of the pointer line.',
- required=False)
-
- elbowLength = attr.Measurement(
- title=u'Elbow Length',
- description=u'The length of the final segment of the pointer.',
- required=False)
-
- edgePad = attr.Measurement(
- title=u'Edge Padding',
- description=u'The padding between between the pointer label and box.',
- required=False)
-
- piePad = attr.Measurement(
- title=u'Pie Padding',
- description=u'The padding between between the pointer label and chart.',
- required=False)
-
-class SlicePointer(directive.RMLDirective):
- signature = ISlicePointer
-
- def process(self):
- for name, value in self.getAttributeValues():
- self.parent.context['label_pointer_'+name] = value
-
-
-class ISliceBase(interfaces.IRMLDirectiveSignature):
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The wodth of the slice line.',
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=u'The fill color of the slice.',
- required=False)
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=u'The color of the pointer line.',
- required=False)
-
- strokeDashArray = attr.Sequence(
- title=u'Stroke Dash Array',
- description=u'Teh dash array of the slice borderline.',
- value_type=attr.Float(),
- required=False)
-
- popout = attr.Measurement(
- title=u'Popout',
- description=u'The distance of how much the slice should be popped out.',
- required=False)
-
- fontName = attr.String(
- title=u'Font Name',
- description=u'The font name of the label.',
- required=False)
-
- fontSize = attr.Measurement(
- title=u'Font Size',
- description=u'The font size of the label.',
- required=False)
-
- labelRadius = attr.Measurement(
- title=u'Label Radius',
- description=(u'The radius at which the label should be placed around '
- u'the pie.'),
- required=False)
-
-
-class ISlice(ISliceBase):
- """A slice in a pie chart."""
- occurence.containing(
- occurence.ZeroOrOne('label', ISliceLabel),
- occurence.ZeroOrOne('pointer', ISlicePointer),
- )
-
- swatchMarker = attr.Symbol(
- required=False)
-
-class Slice(directive.RMLDirective):
- signature = ISlice
- factories = {
- 'label': SliceLabel,
- 'pointer': SlicePointer}
-
- def process(self):
- self.context = attrs = dict(self.getAttributeValues())
- self.processSubDirectives()
- self.parent.context.append(attrs)
-
-
-class ISlice3D(ISlice):
- """A 3-D slice of a 3-D pie chart."""
-
- fillColorShaded = attr.Color(
- title=u'Fill Color Shade',
- description=u'The shade used for the fill color.',
- required=False)
-
-class Slice3D(Slice):
- signature = ISlice3D
- factories = {}
- # Sigh, the 3-D Pie does not support advanced slice labels. :-(
- # 'label': SliceLabel}
-
-
-class ISlices(ISliceBase):
- """The collection of all 2-D slice descriptions."""
- occurence.containing(
- occurence.OneOrMore('slice', ISlice),
- )
-
-class Slices(directive.RMLDirective):
- signature = ISlices
- factories = {'slice': Slice}
-
- def process(self):
- # Get global slice properties
- for name, value in self.getAttributeValues():
- setattr(self.parent.context.slices, name, value)
- # Get slice specific properties
- self.context = slicesData = []
- self.processSubDirectives()
- for index, sliceData in enumerate(slicesData):
- for name, value in sliceData.items():
- setattr(self.parent.context.slices[index], name, value)
-
-
-class ISlices3D(ISliceBase):
- """The collection of all 3-D slice descriptions."""
- occurence.containing(
- occurence.OneOrMore('slice', ISlice3D),
- )
-
- fillColorShaded = attr.Color(
- required=False)
-
-class Slices3D(Slices):
- signature = ISlices3D
- factories = {'slice': Slice3D}
-
-
-class ISimpleLabel(IName):
- """A simple label"""
-
-class SimpleLabel(Name):
- signature = ISimpleLabel
-
-class ISimpleLabels(interfaces.IRMLDirectiveSignature):
- """A set of simple labels for a chart."""
- occurence.containing(
- occurence.OneOrMore('label', ISimpleLabel),
- )
-
-class SimpleLabels(directive.RMLDirective):
- signature = ISimpleLabels
- factories = {'label': Name}
-
- def process(self):
- self.names = []
- self.processSubDirectives()
- self.parent.context.labels = self.names
-
-
-class IStrandBase(interfaces.IRMLDirectiveSignature):
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'The line width of the strand.',
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=u'The fill color of the strand area.',
- required=False)
-
- strokeColor= attr.Color(
- title=u'Stroke Color',
- description=u'The color of the strand line.',
- required=False)
-
- strokeDashArray = attr.Sequence(
- title=u'Stroke Dash Array',
- description=u'The dash array of the strand line.',
- value_type=attr.Float(),
- required=False)
-
- symbol = attr.Symbol(
- title=u'Symbol',
- description=u'The symbol to use to mark the strand.',
- required=False)
-
- symbolSize = attr.Measurement(
- title=u'Symbol Size',
- description=u'The size of the strand symbol.',
- required=False)
-
-class IStrand(IStrandBase):
- """A strand in the spider diagram"""
-
- name = attr.Text(
- title=u'Name',
- description=u'The name of the strand.',
- required=False)
-
-class Strand(PropertyItem):
- signature = IStrand
-
-
-class IStrands(IStrand):
- """A collection of strands."""
- occurence.containing(
- occurence.OneOrMore('strand', IStrand)
- )
-
-class Strands(PropertyCollection):
- signature = IStrands
- propertyName = 'strands'
- attrs = IStrandBase
- factories = {'strand': Strand}
-
-
-class IStrandLabelBase(ILabelBase):
-
- _text = attr.TextNode(
- title=u'Text',
- description=u'The label text of the strand.',
- required=False)
-
- row = attr.Integer(
- title=u'Row',
- description=u'The row of the strand label',
- required=False)
-
- col = attr.Integer(
- title=u'Column',
- description=u'The column of the strand label.',
- required=False)
-
- format = attr.String(
- title=u'Format',
- description=u'The format string for the label.',
- required=False)
-
-class IStrandLabel(IStrandLabelBase):
- """A label for a strand."""
-
- dR = attr.Float(
- title=u'Radial Shift',
- description=u'The radial shift of the label.',
- required=False)
-
-class StrandLabel(Label):
- signature = IStrandLabel
-
-
-class IStrandLabels(IStrandLabelBase):
- """A set of strand labels."""
- occurence.containing(
- occurence.OneOrMore('label', IStrandLabel)
- )
-
-class StrandLabels(PropertyCollection):
- signature = IStrandLabels
- propertyName = 'strandLabels'
- factories = {'label': StrandLabel}
-
- def process(self):
- self.processAttributes()
- # Get item specific properties
- prop = getattr(self.parent.context, self.propertyName)
- self.dataList = []
- self.processSubDirectives()
- for data in self.dataList:
- row = data.pop('row')
- col = data.pop('col')
- for name, value in data.items():
- setattr(prop[row, col], name, value)
-
-
-class ISpoke(interfaces.IRMLDirectiveSignature):
- """A spoke in the spider diagram."""
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u"The width of the spoke's line.",
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=u"The fill color of the spoke's area.",
- required=False)
-
- strokeColor= attr.Color(
- title=u'Stroke Color',
- description=u'The color of the spoke line.',
- required=False)
-
- strokeDashArray = attr.Sequence(
- title=u'Stroke Dash Array',
- description=u'The dash array of the spoke line.',
- value_type=attr.Float(),
- required=False)
-
- labelRadius = attr.Measurement(
- title=u'Label Radius',
- description=u'The radius of the label arouns the spoke.',
- required=False)
-
- visible = attr.Boolean(
- title=u'Visible',
- description=u'When true, the spoke line is drawn.',
- required=False)
-
-class Spoke(PropertyItem):
- signature = ISpoke
-
-
-class ISpokes(ISpoke):
- """A collection of spokes."""
- occurence.containing(
- occurence.OneOrMore('spoke', ISpoke)
- )
-
-class Spokes(PropertyCollection):
- signature = ISpokes
- propertyName = 'spokes'
- factories = {'spoke': Spoke}
-
-
-class ISpokeLabelBase(ILabelBase):
- pass
-
-class ISpokeLabel(ISpokeLabelBase):
- """A label for a spoke."""
- _text = attr.TextNode(
- title=u'Text',
- description=u'The text of the spoke (label).',
- required=False)
-
-class SpokeLabel(Label):
- signature = ISpokeLabel
-
-
-class ISpokeLabels(ISpokeLabelBase):
- """A set of spoke labels."""
- occurence.containing(
- occurence.OneOrMore('label', ISpokeLabel)
- )
-
-class SpokeLabels(PropertyCollection):
- signature = ISpokeLabels
- propertyName = 'spokeLabels'
- factories = {'label': SpokeLabel}
-
-
-class IChart(interfaces.IRMLDirectiveSignature):
- occurence.containing(
- occurence.ZeroOrOne('texts', ITexts),
- )
-
- # Drawing Options
-
- dx = attr.Measurement(
- title=u'Drawing X-Position',
- description=u'The x-position of the entire drawing on the canvas.',
- required=False)
-
- dy = attr.Measurement(
- title=u'Drawing Y-Position',
- description=u'The y-position of the entire drawing on the canvas.',
- required=False)
-
- dwidth = attr.Measurement(
- title=u'Drawing Width',
- description=u'The width of the entire drawing',
- required=False)
-
- dheight = attr.Measurement(
- title=u'Drawing Height',
- description=u'The height of the entire drawing',
- required=False)
-
- angle = attr.Float(
- title=u'Angle',
- description=u'The orientation of the drawing as an angle in degrees.',
- required=False)
-
- # Plot Area Options
-
- x = attr.Measurement(
- title=u'Chart X-Position',
- description=u'The x-position of the chart within the drawing.',
- required=False)
-
- y = attr.Measurement(
- title=u'Chart Y-Position',
- description=u'The y-position of the chart within the drawing.',
- required=False)
-
- width = attr.Measurement(
- title=u'Chart Width',
- description=u'The width of the chart.',
- required=False)
-
- height = attr.Measurement(
- title=u'Chart Height',
- description=u'The height of the chart.',
- required=False)
-
- strokeColor = attr.Color(
- title=u'Stroke Color',
- description=u'Color of the chart border.',
- required=False)
-
- strokeWidth = attr.Measurement(
- title=u'Stroke Width',
- description=u'Width of the chart border.',
- required=False)
-
- fillColor = attr.Color(
- title=u'Fill Color',
- description=u'Color of the chart interior.',
- required=False)
-
- debug = attr.Boolean(
- title=u'Debugging',
- description=u'A flag that when set to True turns on debug messages.',
- required=False)
-
-class Chart(directive.RMLDirective):
- signature = IChart
- factories = {
- 'texts': Texts
- }
- attrMapping = {}
-
- def createChart(self, attributes):
- raise NotImplementedError
-
- def process(self):
- attrs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- angle = attrs.pop('angle', 0)
- x, y = attrs.pop('dx'), attrs.pop('dy')
- self.drawing = shapes.Drawing(attrs.pop('dwidth'), attrs.pop('dheight'))
- self.context = chart = self.createChart(attrs)
- self.processSubDirectives()
- group = shapes.Group(chart)
- group.translate(0,0)
- group.rotate(angle)
- self.drawing.add(group)
- manager = attr.getManager(self, interfaces.ICanvasManager)
- self.drawing.drawOn(manager.canvas, x, y)
-
-
-class IBarChart(IChart):
- """Creates a two-dimensional bar chart."""
- occurence.containing(
- occurence.One('data', IData1D),
- occurence.ZeroOrOne('bars', IBars),
- occurence.ZeroOrOne('categoryAxis', ICategoryAxis),
- occurence.ZeroOrOne('valueAxis', IValueAxis),
- occurence.ZeroOrOne('barLabels', IBarLabels),
- *IChart.queryTaggedValue('directives', ())
- )
-
- direction = attr.Choice(
- title=u'Direction',
- description=u'The direction of the bars within the chart.',
- choices=('horizontal', 'vertical'),
- default='horizontal',
- required=False)
-
- useAbsolute = attr.Boolean(
- title=u'Use Absolute Spacing',
- description=u'Flag to use absolute spacing values.',
- default=False,
- required=False)
-
- barWidth = attr.Measurement(
- title=u'Bar Width',
- description=u'The width of an individual bar.',
- default=10,
- required=False)
-
- groupSpacing = attr.Measurement(
- title=u'Group Spacing',
- description=u'Width between groups of bars.',
- default=5,
- required=False)
-
- barSpacing = attr.Measurement(
- title=u'Bar Spacing',
- description=u'Width between individual bars.',
- default=0,
- required=False)
-
- barLabelFormat = attr.String(
- title=u'Bar Label Text Format',
- description=u'Formatting string for bar labels.',
- required=False)
-
-
-class BarChart(Chart):
- signature = IBarChart
- nameBase = 'BarChart'
- factories = Chart.factories.copy()
- factories.update({
- 'data': Data1D,
- 'bars': Bars,
- 'barLabels': BarLabels,
- })
-
- def createChart(self, attrs):
- direction = attrs.pop('direction')
- # Setup sub-elements based on direction
- if direction == 'horizontal':
- self.factories['categoryAxis'] = YCategoryAxis
- self.factories['valueAxis'] = XValueAxis
- else:
- self.factories['categoryAxis'] = XCategoryAxis
- self.factories['valueAxis'] = YValueAxis
- # Generate the chart
- chart = getattr(
- barcharts, direction.capitalize()+self.nameBase)()
- for name, value in attrs.items():
- setattr(chart, name, value)
- return chart
-
-
-class IBarChart3D(IBarChart):
- """Creates a three-dimensional bar chart."""
- occurence.containing(
- *IBarChart.queryTaggedValue('directives', ())
- )
-
- thetaX = attr.Float(
- title=u'Theta-X',
- description=u'Fraction of dx/dz.',
- required=False)
-
- thetaY = attr.Float(
- title=u'Theta-Y',
- description=u'Fraction of dy/dz.',
- required=False)
-
- zDepth = attr.Measurement(
- title=u'Z-Depth',
- description=u'Depth of an individual series/bar.',
- required=False)
-
- zSpace = attr.Measurement(
- title=u'Z-Space',
- description=u'Z-Gap around a series/bar.',
- required=False)
-
-class BarChart3D(BarChart):
- signature = IBarChart3D
- nameBase = 'BarChart3D'
- attrMapping = {'thetaX': 'theta_x', 'thetaY': 'theta_y'}
-
-
-class ILinePlot(IChart):
- """A line plot."""
- occurence.containing(
- occurence.One('data', IData2D),
- occurence.ZeroOrOne('lines', ILines),
- occurence.ZeroOrOne('xValueAxis', IXValueAxis),
- occurence.ZeroOrOne('yValueAxis', IYValueAxis),
- occurence.ZeroOrOne('lineLabels', ILineLabels),
- *IChart.queryTaggedValue('directives', ())
- )
-
- reversePlotOrder = attr.Boolean(
- title=u'Reverse Plot Order',
- description=u'When true, the coordinate system is reversed.',
- required=False)
-
- lineLabelNudge = attr.Measurement(
- title=u'Line Label Nudge',
- description=u'The distance between the data point and its label.',
- required=False)
-
- lineLabelFormat = attr.String(
- title=u'Line Label Format',
- description=u'Formatting string for data point labels.',
- required=False)
-
- joinedLines = attr.Boolean(
- title=u'Joined Lines',
- description=u'When true, connect all data points with lines.',
- required=False)
-
-class LinePlot(Chart):
- signature = ILinePlot
-
- factories = Chart.factories.copy()
- factories.update({
- 'data': Data2D,
- 'lines': Lines,
- 'xValueAxis': LineXValueAxis,
- 'yValueAxis': LineYValueAxis,
- 'lineLabels': LineLabels,
- })
-
- def createChart(self, attrs):
- # Generate the chart
- chart = lineplots.LinePlot()
- for name, value in attrs.items():
- setattr(chart, name, value)
- return chart
-
-class ILinePlot3D(ILinePlot):
- """Creates a three-dimensional line plot."""
- occurence.containing(
- *ILinePlot.queryTaggedValue('directives', ())
- )
-
- thetaX = attr.Float(
- title=u'Theta-X',
- description=u'Fraction of dx/dz.',
- required=False)
-
- thetaY = attr.Float(
- title=u'Theta-Y',
- description=u'Fraction of dy/dz.',
- required=False)
-
- zDepth = attr.Measurement(
- title=u'Z-Depth',
- description=u'Depth of an individual series/bar.',
- required=False)
-
- zSpace = attr.Measurement(
- title=u'Z-Space',
- description=u'Z-Gap around a series/bar.',
- required=False)
-
-class LinePlot3D(LinePlot):
- signature = ILinePlot3D
- nameBase = 'LinePlot3D'
- attrMapping = {'thetaX': 'theta_x', 'thetaY': 'theta_y'}
-
- def createChart(self, attrs):
- # Generate the chart
- chart = lineplots.LinePlot3D()
- for name, value in attrs.items():
- setattr(chart,name, value)
- return chart
-
-
-
-class IPieChart(IChart):
- """A pie chart."""
- occurence.containing(
- occurence.One('data', ISingleData1D),
- occurence.ZeroOrOne('slices', ISlices),
- occurence.ZeroOrOne('labels', ISimpleLabels),
- *IChart.queryTaggedValue('directives', ())
- )
-
- startAngle = attr.Integer(
- title=u'Start Angle',
- description=u'The start angle in the chart of the first slice '
- u'in degrees.',
- required=False)
-
- direction = attr.Choice(
- title=u'Direction',
- description=u'The direction in which the pie chart will be built.',
- choices=('clockwise', 'anticlockwise'),
- required=False)
-
- checkLabelOverlap = attr.Boolean(
- title=u'Check Label Overlap',
- description=(u'When true, check and attempt to fix standard '
- u'label overlaps'),
- required=False)
-
- pointerLabelMode = attr.Choice(
- title=u'Pointer Label Mode',
- description=(u'The location relative to the slace the label should '
- u'be placed.'),
- choices={'none': None,
- 'leftright': 'LeftRight',
- 'leftandright': 'LeftAndRight'},
- required=False)
-
- sameRadii = attr.Boolean(
- title=u'Same Radii',
- description=u'When true, make x/y radii the same.',
- required=False)
-
- orderMode = attr.Choice(
- title=u'Order Mode',
- description=u'',
- choices=('fixed', 'alternate'),
- required=False)
-
- xradius = attr.Measurement(
- title=u'X-Radius',
- description=u'The radius of the X-directions',
- required=False)
-
- yradius = attr.Measurement(
- title=u'Y-Radius',
- description=u'The radius of the Y-directions',
- required=False)
-
-
-class PieChart(Chart):
- signature = IPieChart
- chartClass = piecharts.Pie
-
- factories = Chart.factories.copy()
- factories.update({
- 'data': SingleData1D,
- 'slices': Slices,
- 'labels': SimpleLabels,
- })
-
- def createChart(self, attrs):
- # Generate the chart
- chart = self.chartClass()
- for name, value in attrs.items():
- setattr(chart, name, value)
- return chart
-
-
-class IPieChart3D(IPieChart):
- """A 3-D pie chart."""
- occurence.containing(
- occurence.One('slices', ISlices3D),
- *IChart.queryTaggedValue('directives', ())
- )
-
- perspective = attr.Float(
- title=u'Perspsective',
- description=u'The flattening parameter.',
- required=False)
-
- depth_3d = attr.Measurement(
- title=u'3-D Depth',
- description=u'The depth of the pie.',
- required=False)
-
- angle_3d = attr.Float(
- title=u'3-D Angle',
- description=u'The view angle in the Z-coordinate.',
- required=False)
-
-class PieChart3D(PieChart):
- signature = IPieChart3D
- chartClass = piecharts.Pie3d
-
- factories = PieChart.factories.copy()
- factories.update({
- 'slices': Slices3D,
- })
-
-class ISpiderChart(IChart):
- """A spider chart."""
- occurence.containing(
- occurence.One('data', IData1D),
- occurence.ZeroOrOne('strands', IStrands),
- occurence.ZeroOrOne('strandLabels', IStrandLabels),
- occurence.ZeroOrOne('spokes', ISpokes),
- occurence.ZeroOrOne('spokeLabels', ISpokeLabels),
- occurence.ZeroOrOne('labels', ISimpleLabels),
- *IChart.queryTaggedValue('directives', ())
- )
-
- startAngle = attr.Integer(
- title=u'Start Angle',
- description=u'The start angle in the chart of the first strand '
- u'in degrees.',
- required=False)
-
- direction = attr.Choice(
- title=u'Direction',
- description=u'The direction in which the spider chart will be built.',
- choices=('clockwise', 'anticlockwise'),
- required=False)
-
-class SpiderChart(Chart):
- signature = ISpiderChart
- factories = Chart.factories.copy()
- factories.update({
- 'data': Data1D,
- 'strands': Strands,
- 'strandLabels': StrandLabels,
- 'spokes': Spokes,
- 'spokeLabels': SpokeLabels,
- 'labels': SimpleLabels,
- })
-
- def createChart(self, attrs):
- # Generate the chart
- chart = spider.SpiderChart()
- for name, value in attrs.items():
- setattr(chart, name, value)
- return chart
diff --git a/z3c/rml/directive.py b/z3c/rml/directive.py
deleted file mode 100644
index 1e059c64..00000000
--- a/z3c/rml/directive.py
+++ /dev/null
@@ -1,123 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""RML Directive Implementation
-"""
-import logging
-import zope.interface
-import zope.schema
-
-from lxml import etree
-from z3c.rml import interfaces
-from z3c.rml.attr import getManager
-
-logging.raiseExceptions = False
-logger = logging.getLogger("z3c.rml")
-
-ABORT_ON_INVALID_DIRECTIVE = False
-
-def DeprecatedDirective(iface, reason):
- zope.interface.directlyProvides(iface, interfaces.IDeprecatedDirective)
- iface.setTaggedValue('deprecatedReason', reason)
- return iface
-
-def getFileInfo(directive, element=None):
- root = directive
- while root.parent:
- root = root.parent
- if element is None:
- element = directive.element
- return '(file %s, line %i)' %(root.filename, element.sourceline)
-
-class RMLDirective(object):
- zope.interface.implements(interfaces.IRMLDirective)
- signature = None
- factories = {}
-
- def __init__(self, element, parent):
- self.element = element
- self.parent = parent
-
- def getAttributeValues(self, ignore=None, select=None, attrMapping=None,
- includeMissing=False, valuesOnly=False):
- """See interfaces.IRMLDirective"""
- manager = getManager(self)
- cache = '%s.%s' % (self.signature.__module__, self.signature.__name__)
- if cache in manager.attributesCache:
- fields = manager.attributesCache[cache]
- else:
- fields = []
- for name, attr in zope.schema.getFieldsInOrder(self.signature):
- fields.append((name, attr))
- manager.attributesCache[cache] = fields
-
- items = []
- for name, attr in fields:
- # Only add the attribute to the list, if it is supposed there
- if ((ignore is None or name not in ignore) and
- (select is None or name in select)):
- # Get the value.
- value = attr.bind(self).get()
- # If no value was found for a required field, raise a value
- # error
- if attr.required and value is attr.missing_value:
- raise ValueError(
- 'No value for required attribute "%s" '
- 'in directive "%s" %s.' % (
- name, self.element.tag, getFileInfo(self)))
- # Only add the entry if the value is not the missing value or
- # missing values are requested to be included.
- if value is not attr.missing_value or includeMissing:
- items.append((name, value))
-
- # Sort the items based on the section
- if select is not None:
- select = list(select)
- items = sorted(items, key=lambda (n, v): select.index(n))
-
- # If the attribute name does not match the internal API
- # name, then convert the name to the internal one
- if attrMapping:
- items = [(attrMapping.get(name, name), value)
- for name, value in items]
-
- # Sometimes we only want the values without the names
- if valuesOnly:
- return [value for name, value in items]
-
- return items
-
- def processSubDirectives(self, select=None, ignore=None):
- # Go through all children of the directive and try to process them.
- for element in self.element.getchildren():
- # Ignore all comments
- if isinstance(element, etree._Comment):
- continue
- # Raise an error/log any unknown directive.
- if element.tag not in self.factories:
- msg = "Directive %r could not be processed and was " \
- "ignored. %s" %(element.tag, getFileInfo(self, element))
- # Record any tags/elements that could not be processed.
- logger.warn(msg)
- if ABORT_ON_INVALID_DIRECTIVE:
- raise ValueError(msg)
- continue
- if select is not None and element.tag not in select:
- continue
- if ignore is not None and element.tag in ignore:
- continue
- directive = self.factories[element.tag](element, self)
- directive.process()
-
- def process(self):
- self.processSubDirectives()
diff --git a/z3c/rml/doclogic.py b/z3c/rml/doclogic.py
deleted file mode 100644
index 19bd264a..00000000
--- a/z3c/rml/doclogic.py
+++ /dev/null
@@ -1,169 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2012 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""``doc*`` directives.
-"""
-import reportlab.platypus
-from z3c.rml import attr, directive, flowable, interfaces, occurence
-
-class IDocAssign(interfaces.IRMLDirectiveSignature):
- """Assign a value to the namesapce."""
-
- var = attr.String(
- title=u'Variable Name',
- description=u'The name under which the value is stored.',
- required=True)
-
- expr = attr.String(
- title=u'Expression',
- description=u'The expression that creates the value when evaluated.',
- required=True)
-
-class DocAssign(flowable.Flowable):
- signature = IDocAssign
- klass = reportlab.platypus.flowables.DocAssign
-
-
-class IDocExec(interfaces.IRMLDirectiveSignature):
- """Execute a statement."""
-
- stmt = attr.String(
- title=u'Statement',
- description=u'The statement to be executed.',
- required=True)
-
-class DocExec(flowable.Flowable):
- signature = IDocExec
- klass = reportlab.platypus.flowables.DocExec
-
-
-class IDocPara(interfaces.IRMLDirectiveSignature):
- """Create a paragraph with the value returned from the expression."""
-
- expr = attr.String(
- title=u'Expression',
- description=u'The expression to be executed.',
- required=True)
-
- format = attr.String(
- title=u'Format',
- description=u'The format used to render the expression value.',
- required=False)
-
- style = attr.Style(
- title=u'Style',
- description=u'The style of the paragraph.',
- required=False)
-
- escape = attr.Boolean(
- title=u'Escape Text',
- description=u'When set (default) the expression value is escaped.',
- required=False)
-
-class DocPara(flowable.Flowable):
- signature = IDocPara
- klass = reportlab.platypus.flowables.DocPara
-
-
-class IDocAssert(interfaces.IRMLDirectiveSignature):
- """Assert a certain condition."""
-
- cond = attr.String(
- title=u'Condition',
- description=u'The condition to be asserted.',
- required=True)
-
- format = attr.String(
- title=u'Format',
- description=u'The text displayed if assertion fails.',
- required=False)
-
-class DocAssert(flowable.Flowable):
- signature = IDocAssert
- klass = reportlab.platypus.flowables.DocAssert
-
-
-class IDocElse(interfaces.IRMLDirectiveSignature):
- """Starts 'else' block."""
-
-class DocElse(flowable.Flowable):
- signature = IDocElse
-
- def process(self):
- if not isinstance(self.parent, DocIf):
- raise ValueError(" can only be placed inside a ")
- self.parent.flow = self.parent.elseFlow
-
-
-class IDocIf(flowable.IFlow):
- """Display story flow based on the value of the condition."""
-
- cond = attr.String(
- title=u'Condition',
- description=u'The condition to be tested.',
- required=True)
-
-class DocIf(flowable.Flow):
- signature = IDocAssert
- klass = reportlab.platypus.flowables.DocIf
-
- def __init__(self, *args, **kw):
- super(flowable.Flow, self).__init__(*args, **kw)
- self.thenFlow = self.flow = []
- self.elseFlow = []
-
- def process(self):
- args = dict(self.getAttributeValues())
- self.processSubDirectives()
- dif = self.klass(
- thenBlock = self.thenFlow, elseBlock = self.elseFlow, **args)
- self.parent.flow.append(dif)
-
-class IDocWhile(flowable.IFlow):
- """Repeat the included directives as long as the condition is true."""
-
- cond = attr.String(
- title=u'Condition',
- description=u'The condition to be tested.',
- required=True)
-
-class DocWhile(flowable.Flow):
- signature = IDocAssert
- klass = reportlab.platypus.flowables.DocWhile
-
- def process(self):
- args = dict(self.getAttributeValues())
- self.processSubDirectives()
- dwhile = self.klass(whileBlock = self.flow, **args)
- self.parent.flow.append(dwhile)
-
-
-flowable.Flow.factories['docAssign'] = DocAssign
-flowable.Flow.factories['docExec'] = DocExec
-flowable.Flow.factories['docPara'] = DocPara
-flowable.Flow.factories['docAssert'] = DocAssert
-flowable.Flow.factories['docIf'] = DocIf
-flowable.Flow.factories['docElse'] = DocElse
-flowable.Flow.factories['docWhile'] = DocWhile
-
-flowable.IFlow.setTaggedValue(
- 'directives',
- flowable.IFlow.getTaggedValue('directives') +
- (occurence.ZeroOrMore('docAssign', IDocAssign),
- occurence.ZeroOrMore('docExec', IDocExec),
- occurence.ZeroOrMore('docPara', IDocPara),
- occurence.ZeroOrMore('docIf', IDocIf),
- occurence.ZeroOrMore('docElse', IDocElse),
- occurence.ZeroOrMore('docWhile', IDocWhile),
- )
- )
diff --git a/z3c/rml/document.py b/z3c/rml/document.py
deleted file mode 100644
index fdc32bc0..00000000
--- a/z3c/rml/document.py
+++ /dev/null
@@ -1,757 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""RML ``document`` element
-"""
-import cStringIO
-import logging
-import sys
-import zope.interface
-import reportlab.pdfgen.canvas
-from reportlab.pdfbase import pdfmetrics, ttfonts, cidfonts
-from reportlab.lib import colors, fonts
-from reportlab.platypus import tableofcontents
-from reportlab.platypus.doctemplate import IndexingFlowable
-
-from z3c.rml import attr, canvas, directive, doclogic, interfaces, list
-from z3c.rml import occurence, pdfinclude, special, storyplace, stylesheet
-from z3c.rml import template
-
-LOGGER_NAME = 'z3c.rml.render'
-
-class IRegisterType1Face(interfaces.IRMLDirectiveSignature):
- """Register a new Type 1 font face."""
-
- afmFile = attr.File(
- title=u'AFM File',
- description=u'Path to AFM file used to register the Type 1 face.',
- doNotOpen=True,
- required=True)
-
- pfbFile = attr.File(
- title=u'PFB File',
- description=u'Path to PFB file used to register the Type 1 face.',
- doNotOpen=True,
- required=True)
-
-class RegisterType1Face(directive.RMLDirective):
- signature = IRegisterType1Face
-
- def process(self):
- args = self.getAttributeValues(valuesOnly=True)
- face = pdfmetrics.EmbeddedType1Face(*args)
- pdfmetrics.registerTypeFace(face)
-
-
-class IRegisterFont(interfaces.IRMLDirectiveSignature):
- """Register a new font based on a face and encoding."""
-
- name = attr.String(
- title=u'Name',
- description=(u'The name under which the font can be used in style '
- u'declarations or other parameters that lookup a font.'),
- required=True)
-
- faceName = attr.String(
- title=u'Face Name',
- description=(u'The name of the face the font uses. The face has to '
- u'be previously registered.'),
- required=True)
-
- encName = attr.String(
- title=u'Encoding Name',
- description=(u'The name of the encdoing to be used.'),
- required=True)
-
-class RegisterFont(directive.RMLDirective):
- signature = IRegisterFont
-
- def process(self):
- args = self.getAttributeValues(valuesOnly=True)
- font = pdfmetrics.Font(*args)
- pdfmetrics.registerFont(font)
-
-
-class IAddMapping(interfaces.IRMLDirectiveSignature):
- """Map various styles(bold, italic) of a font name to the actual ps fonts
- used."""
-
- faceName = attr.String(
- title=u'Name',
- description=(u'The name of the font to be mapped'),
- required=True)
-
- bold = attr.Integer(
- title=u'Bold',
- description=(u'Bold'),
- required=True)
-
- italic = attr.Integer(
- title=u'Italic',
- description=(u'Italic'),
- required=True)
-
- psName = attr.String(
- title=u'psName',
- description=(u'Actual font name mapped'),
- required=True)
-
-class AddMapping(directive.RMLDirective):
- signature = IAddMapping
-
- def process(self):
- args = self.getAttributeValues(valuesOnly=True)
- fonts.addMapping(*args)
-
-class IRegisterTTFont(interfaces.IRMLDirectiveSignature):
- """Register a new TrueType font given the TT file and face name."""
-
- faceName = attr.String(
- title=u'Face Name',
- description=(u'The name of the face the font uses. The face has to '
- u'be previously registered.'),
- required=True)
-
- fileName = attr.File(
- title=u'File Name',
- description=u'File path of the of the TrueType font.',
- doNotOpen=True,
- required=True)
-
-class RegisterTTFont(directive.RMLDirective):
- signature = IRegisterTTFont
-
- def process(self):
- args = self.getAttributeValues(valuesOnly=True)
- font = ttfonts.TTFont(*args)
- pdfmetrics.registerFont(font)
-
-
-class IRegisterCidFont(interfaces.IRMLDirectiveSignature):
- """Register a new CID font given the face name."""
-
- faceName = attr.String(
- title=u'Face Name',
- description=(u'The name of the face the font uses. The face has to '
- u'be previously registered.'),
- required=True)
-
- encName = attr.String(
- title=u'Encoding Name',
- description=(u'The name of the encoding to use for the font.'),
- required=False)
-
-class RegisterCidFont(directive.RMLDirective):
- signature = IRegisterCidFont
- attrMapping = {'faceName': 'face', 'encName': 'encoding'}
-
- def process(self):
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- if 'encoding' in args:
- font = cidfonts.CIDFont(**args)
- else:
- font = cidfonts.UnicodeCIDFont(**args)
- pdfmetrics.registerFont(font)
-
-
-class IRegisterFontFamily(interfaces.IRMLDirectiveSignature):
- """Register a new font family."""
-
- name = attr.String(
- title=u'Name',
- description=(u'The name of the font family.'),
- required=True)
-
- normal = attr.String(
- title=u'Normal Font Name',
- description=(u'The name of the normal font variant.'),
- required=False)
-
- bold = attr.String(
- title=u'Bold Font Name',
- description=(u'The name of the bold font variant.'),
- required=False)
-
- italic = attr.String(
- title=u'Italic Font Name',
- description=(u'The name of the italic font variant.'),
- required=False)
-
- boldItalic = attr.String(
- title=u'Bold/Italic Font Name',
- description=(u'The name of the bold/italic font variant.'),
- required=True)
-
-class RegisterFontFamily(directive.RMLDirective):
- signature = IRegisterFontFamily
- attrMapping = {'name': 'family'}
-
- def process(self):
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- pdfmetrics.registerFontFamily(**args)
-
-
-class IColorDefinition(interfaces.IRMLDirectiveSignature):
- """Define a new color and give it a name to be known under."""
-
- id = attr.String(
- title=u'Id',
- description=(u'The id/name the color will be available under.'),
- required=True)
-
- RGB = attr.Color(
- title=u'RGB Color',
- description=(u'The color value that is represented.'),
- required=False)
-
- CMYK = attr.Color(
- title=u'CMYK Color',
- description=(u'The color value that is represented.'),
- required=False)
-
- value = attr.Color(
- title=u'Color',
- description=(u'The color value that is represented.'),
- required=False)
-
- spotName = attr.String(
- title=u'Spot Name',
- description=(u'The Spot Name of the CMYK color.'),
- required=False)
-
- density = attr.Float(
- title=u'Density',
- description=(u'The color density of the CMYK color.'),
- min=0.0,
- max=1.0,
- required=False)
-
- knockout = attr.String(
- title=u'Knockout',
- description=(u'The knockout of the CMYK color.'),
- required=False)
-
- alpha = attr.Float(
- title=u'Alpha',
- description=(u'The alpha channel of the color.'),
- min=0.0,
- max=1.0,
- required=False)
-
-class ColorDefinition(directive.RMLDirective):
- signature = IColorDefinition
-
- def process(self):
- kwargs = dict(self.getAttributeValues())
- id = kwargs.pop('id')
- for attrName in ('RGB', 'CMYK', 'value'):
- color = kwargs.pop(attrName, None)
- if color is not None:
- # CMYK has additional attributes.
- for name, value in kwargs.items():
- setattr(color, name, value)
- manager = attr.getManager(self)
- manager.colors[id] = color
- return
- raise ValueError('At least one color definition must be specified.')
-
-# Initialize also supports the tag.
-stylesheet.Initialize.factories['color'] = ColorDefinition
-stylesheet.IInitialize.setTaggedValue(
- 'directives',
- stylesheet.IInitialize.getTaggedValue('directives') +
- (occurence.ZeroOrMore('color', IColorDefinition),)
- )
-
-
-class IStartIndex(interfaces.IRMLDirectiveSignature):
- """Start a new index."""
-
- name = attr.String(
- title=u'Name',
- description=u'The name of the index.',
- default='index',
- required=True)
-
- offset = attr.Integer(
- title=u'Offset',
- description=u'The counting offset.',
- min=0,
- required=False)
-
- format = attr.Choice(
- title=u'Format',
- description=(u'The format the index is going to use.'),
- choices=interfaces.LIST_FORMATS,
- required=False)
-
-class StartIndex(directive.RMLDirective):
- signature = IStartIndex
-
- def process(self):
- kwargs = dict(self.getAttributeValues())
- name = kwargs['name']
- manager = attr.getManager(self)
- manager.indexes[name] = tableofcontents.SimpleIndex(**kwargs)
-
-
-class ICropMarks(interfaces.IRMLDirectiveSignature):
- """Crop Marks specification"""
-
- name = attr.String(
- title=u'Name',
- description=u'The name of the index.',
- default='index',
- required=True)
-
- borderWidth = attr.Measurement(
- title=u'Border Width',
- description=u'The width of the crop mark border.',
- required=False)
-
- markColor = attr.Color(
- title=u'Mark Color',
- description=u'The color of the crop marks.',
- required=False)
-
- markWidth = attr.Measurement(
- title=u'Mark Width',
- description=u'The line width of the actual crop marks.',
- required=False)
-
- markLength = attr.Measurement(
- title=u'Mark Length',
- description=u'The length of the actual crop marks.',
- required=False)
-
- markLast = attr.Boolean(
- title=u'Mark Last',
- description=u'If set, marks are drawn after the content is rendered.',
- required=False)
-
- bleedWidth = attr.Measurement(
- title=u'Bleed Width',
- description=(u'The width of the page bleed.'),
- required=False)
-
-class CropMarksProperties(object):
- borderWidth = 36
- markWidth = 0.5
- markColor = colors.toColor('green')
- markLength = 18
- markLast = True
- bleedWidth = 0
-
-class CropMarks(directive.RMLDirective):
- signature = ICropMarks
-
- def process(self):
- cmp = CropMarksProperties()
- for name, value in self.getAttributeValues():
- setattr(cmp, name, value)
- self.parent.parent.cropMarks = cmp
-
-class ILogConfig(interfaces.IRMLDirectiveSignature):
- """Configure the render logger."""
-
- level = attr.Choice(
- title=u'Level',
- description=u'The default log level.',
- choices=interfaces.LOG_LEVELS,
- doLower=False,
- required=False)
-
- format = attr.String(
- title=u'Format',
- description=u'The format of the log messages.',
- required=False)
-
- filename = attr.File(
- title=u'File Name',
- description=u'The path to the file that is being logged.',
- doNotOpen=True,
- required=True)
-
- filemode = attr.Choice(
- title=u'File Mode',
- description=u'The mode to open the file in.',
- choices={'WRITE': 'w', 'APPEND': 'a'},
- default='a',
- required=False)
-
- datefmt = attr.String(
- title=u'Date Format',
- description=u'The format of the log message date.',
- required=False)
-
-class LogConfig(directive.RMLDirective):
- signature = ILogConfig
-
- def process(self):
- args = dict(self.getAttributeValues())
-
- # cleanup win paths like:
- # ....\\input\\file:///D:\\trunk\\...
- if sys.platform[:3].lower() == "win":
- if args['filename'].startswith('file:///'):
- args['filename'] = args['filename'][len('file:///'):]
-
- logger = logging.getLogger(LOGGER_NAME)
- handler = logging.FileHandler(args['filename'], args['filemode'])
- formatter = logging.Formatter(
- args.get('format'), args.get('datefmt'))
- handler.setFormatter(formatter)
- logger.addHandler(handler)
- if 'level' in args:
- logger.setLevel(args['level'])
- self.parent.parent.logger = logger
-
-
-class IDocInit(interfaces.IRMLDirectiveSignature):
- occurence.containing(
- occurence.ZeroOrMore('color', IColorDefinition),
- occurence.ZeroOrMore('name', special.IName),
- occurence.ZeroOrMore('registerType1Face', IRegisterType1Face),
- occurence.ZeroOrMore('registerFont', IRegisterFont),
- occurence.ZeroOrMore('registerCidFont', IRegisterCidFont),
- occurence.ZeroOrMore('registerTTFont', IRegisterTTFont),
- occurence.ZeroOrMore('registerFontFamily', IRegisterFontFamily),
- occurence.ZeroOrMore('addMapping', IAddMapping),
- occurence.ZeroOrMore('logConfig', ILogConfig),
- occurence.ZeroOrMore('cropMarks', ICropMarks),
- occurence.ZeroOrMore('startIndex', IStartIndex),
- )
-
- pageMode = attr.Choice(
- title=u'Page Mode',
- description=(u'The page mode in which the document is opened in '
- u'the viewer.'),
- choices=('UseNone', 'UseOutlines', 'UseThumbs', 'FullScreen'),
- required=False)
-
- pageLayout = attr.Choice(
- title=u'Page Layout',
- description=(u'The layout in which the pages are displayed in '
- u'the viewer.'),
- choices=('SinglePage', 'OneColumn', 'TwoColumnLeft', 'TwoColumnRight'),
- required=False)
-
- useCropMarks = attr.Boolean(
- title=u'Use Crop Marks',
- description=u'A flag when set shows crop marks on the page.',
- required=False)
-
- hideToolbar = attr.TextBoolean(
- title=u'Hide Toolbar',
- description=(u'A flag indicating that the toolbar is hidden in '
- u'the viewer.'),
- required=False)
-
- hideMenubar = attr.TextBoolean(
- title=u'Hide Menubar',
- description=(u'A flag indicating that the menubar is hidden in '
- u'the viewer.'),
- required=False)
-
- hideWindowUI = attr.TextBoolean(
- title=u'Hide Window UI',
- description=(u'A flag indicating that the window UI is hidden in '
- u'the viewer.'),
- required=False)
-
- fitWindow = attr.TextBoolean(
- title=u'Fit Window',
- description=u'A flag indicating that the page fits in the viewer.',
- required=False)
-
- centerWindow = attr.TextBoolean(
- title=u'Center Window',
- description=(u'A flag indicating that the page fits is centered '
- u'in the viewer.'),
- required=False)
-
- displayDocTitle = attr.TextBoolean(
- title=u'Display Doc Title',
- description=(u'A flag indicating that the document title is displayed '
- u'in the viewer.'),
- required=False)
-
- nonFullScreenPageMode = attr.Choice(
- title=u'Non-Full-Screen Page Mode',
- description=(u'Non-Full-Screen page mode in the viewer.'),
- choices=('UseNone', 'UseOutlines', 'UseThumbs', 'UseOC'),
- required=False)
-
- direction = attr.Choice(
- title=u'Text Direction',
- description=(u'The text direction of the PDF.'),
- choices=('L2R', 'R2L'),
- required=False)
-
- viewArea = attr.Choice(
- title=u'View Area',
- description=(u'View Area setting used in the viewer.'),
- choices=('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'),
- required=False)
-
- viewClip = attr.Choice(
- title=u'View Clip',
- description=(u'View Clip setting used in the viewer.'),
- choices=('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'),
- required=False)
-
- printArea = attr.Choice(
- title=u'Print Area',
- description=(u'Print Area setting used in the viewer.'),
- choices=('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'),
- required=False)
-
- printClip = attr.Choice(
- title=u'Print Clip',
- description=(u'Print Clip setting used in the viewer.'),
- choices=('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox'),
- required=False)
-
- printScaling = attr.Choice(
- title=u'Print Scaling',
- description=(u'The print scaling mode in which the document is opened '
- u'in the viewer.'),
- choices=('None', 'AppDefault'),
- required=False)
-
-class DocInit(directive.RMLDirective):
- signature = IDocInit
- factories = {
- 'name': special.Name,
- 'color': ColorDefinition,
- 'registerType1Face': RegisterType1Face,
- 'registerFont': RegisterFont,
- 'registerTTFont': RegisterTTFont,
- 'registerCidFont': RegisterCidFont,
- 'registerFontFamily': RegisterFontFamily,
- 'addMapping': AddMapping,
- 'logConfig': LogConfig,
- 'cropMarks': CropMarks,
- 'startIndex': StartIndex,
- }
-
- viewerOptions = dict(
- (option[0].lower()+option[1:], option)
- for option in ['HideToolbar', 'HideMenubar', 'HideWindowUI', 'FitWindow',
- 'CenterWindow', 'DisplayDocTitle',
- 'NonFullScreenPageMode', 'Direction', 'ViewArea',
- 'ViewClip', 'PrintArea', 'PrintClip', 'PrintScaling'])
-
- def process(self):
- kwargs = dict(self.getAttributeValues())
- self.parent.cropMarks = kwargs.get('useCropMarks', False)
- self.parent.pageMode = kwargs.get('pageMode')
- self.parent.pageLayout = kwargs.get('pageLayout')
- for name in self.viewerOptions:
- setattr(self.parent, name, kwargs.get(name))
- super(DocInit, self).process()
-
-
-class IDocument(interfaces.IRMLDirectiveSignature):
- occurence.containing(
- occurence.ZeroOrOne('docinit', IDocInit),
- occurence.ZeroOrOne('stylesheet', stylesheet.IStylesheet),
- occurence.ZeroOrOne('template', template.ITemplate),
- occurence.ZeroOrOne('story', template.IStory),
- occurence.ZeroOrOne('pageInfo', canvas.IPageInfo),
- occurence.ZeroOrMore('pageDrawing', canvas.IPageDrawing),
- )
-
- filename = attr.String(
- title=u'File Name',
- description=(u'The default name of the output file, if no output '
- u'file was provided.'),
- required=True)
-
- title = attr.String(
- title=u'Title',
- description=(u'The "Title" annotation for the PDF document.'),
- required=False)
-
- subject = attr.String(
- title=u'Subject',
- description=(u'The "Subject" annotation for the PDF document.'),
- required=False)
-
- author = attr.String(
- title=u'Author',
- description=(u'The "Author" annotation for the PDF document.'),
- required=False)
-
- creator = attr.String(
- title=u'Creator',
- description=(u'The "Creator" annotation for the PDF document.'),
- required=False)
-
- debug = attr.Boolean(
- title=u'Debug',
- description=u'A flag to activate the debug output.',
- default=False,
- required=False)
-
- compression = attr.BooleanWithDefault(
- title=u'Compression',
- description=(u'A flag determining whether page compression should '
- u'be used.'),
- required=False)
-
- invariant = attr.BooleanWithDefault(
- title=u'Invariant',
- description=(u'A flag that determines whether the produced PDF '
- u'should be invariant with respect to the date and '
- u'the exact contents.'),
- required=False)
-
-class Document(directive.RMLDirective):
- signature = IDocument
- zope.interface.implements(interfaces.IManager,
- interfaces.IPostProcessorManager,
- interfaces.ICanvasManager)
-
- factories = {
- 'docinit': DocInit,
- 'stylesheet': stylesheet.Stylesheet,
- 'template': template.Template,
- 'story': template.Story,
- 'pageInfo': canvas.PageInfo,
- 'pageDrawing': canvas.PageDrawing,
- }
-
- def __init__(self, element):
- super(Document, self).__init__(element, None)
- self.names = {}
- self.styles = {}
- self.colors = {}
- self.indexes = {}
- self.postProcessors = []
- self.filename = ''
- self.cropMarks = False
- self.pageLayout = None
- self.pageMode = None
- self.logger = None
- self.svgs = {}
- self.attributesCache = {}
- for name in DocInit.viewerOptions:
- setattr(self, name, None)
-
- def _indexAdd(self, canvas, name, label):
- self.indexes[name](canvas, name, label)
-
- def _beforeDocument(self):
- self._initCanvas(self.doc.canv)
- self.canvas = self.doc.canv
-
- def _initCanvas(self, canvas):
- canvas._indexAdd = self._indexAdd
- canvas.manager = self
- if self.pageLayout:
- canvas._doc._catalog.setPageLayout(self.pageLayout)
- if self.pageMode:
- canvas._doc._catalog.setPageMode(self.pageMode)
- for name, option in DocInit.viewerOptions.items():
- if getattr(self, name) is not None:
- canvas.setViewerPreference(option, getattr(self, name))
- # Setting annotations.
- data = dict(self.getAttributeValues(
- select=('title', 'subject', 'author', 'creator')))
- canvas.setTitle(data.get('title'))
- canvas.setSubject(data.get('subject'))
- canvas.setAuthor(data.get('author'))
- canvas.setCreator(data.get('creator'))
-
- def process(self, outputFile=None, maxPasses=2):
- """Process document"""
- # Reset all reportlab global variables. This is very important for
- # ReportLab not to fail.
- reportlab.rl_config._reset()
-
- debug = self.getAttributeValues(select=('debug',), valuesOnly=True)[0]
- if not debug:
- reportlab.rl_config.shapeChecking = 0
-
- # Add our colors mapping to the default ones.
- colors.toColor.setExtraColorsNameSpace(self.colors)
-
- if outputFile is None:
- # TODO: This is relative to the input file *not* the CWD!!!
- outputFile = open(self.element.get('filename'), 'wb')
-
- # Create a temporary output file, so that post-processors can
- # massage the output
- self.outputFile = tempOutput = cStringIO.StringIO()
-
- # Process common sub-directives
- self.processSubDirectives(select=('docinit', 'stylesheet'))
-
- # Handle Page Drawing Documents
- if self.element.find('pageDrawing') is not None:
- kwargs = dict(self.getAttributeValues(
- select=('compression', 'debug'),
- attrMapping={'compression': 'pageCompression',
- 'debug': 'verbosity'}
- ))
- kwargs['cropMarks'] = self.cropMarks
-
- self.canvas = reportlab.pdfgen.canvas.Canvas(tempOutput, **kwargs)
- self._initCanvas(self.canvas)
- self.processSubDirectives(select=('pageInfo', 'pageDrawing'))
- self.canvas.save()
-
- # Handle Flowable-based documents.
- elif self.element.find('template') is not None:
- self.processSubDirectives(select=('template', 'story'))
- self.doc.beforeDocument = self._beforeDocument
- self.doc.multiBuild(self.flowables, maxPasses=maxPasses)
-
- # Process all post processors
- for name, processor in self.postProcessors:
- tempOutput.seek(0)
- tempOutput = processor.process(tempOutput)
-
- # Save the result into our real output file
- tempOutput.seek(0)
- outputFile.write(tempOutput.getvalue())
-
- # Cleanup.
- colors.toColor.setExtraColorsNameSpace({})
- reportlab.rl_config.shapeChecking = 1
-
- def get_name(self, name, default=None):
- if default is None:
- default = u''
-
- if name not in self.names:
- if self.doc._indexingFlowables and isinstance(
- self.doc._indexingFlowables[-1],
- DummyIndexingFlowable
- ):
- return default
- self.doc._indexingFlowables.append(DummyIndexingFlowable())
-
- return self.names.get(name, default)
-
-
-class DummyIndexingFlowable(IndexingFlowable):
- """A dummy flowable to trick multiBuild into performing +1 pass."""
-
- def __init__(self):
- self.i = -1
-
- def isSatisfied(self):
- self.i += 1
- return self.i
diff --git a/z3c/rml/dtd.py b/z3c/rml/dtd.py
deleted file mode 100644
index f78628d5..00000000
--- a/z3c/rml/dtd.py
+++ /dev/null
@@ -1,76 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Generate a DTD from the code
-"""
-import zope.schema
-
-from z3c.rml import attr, document, occurence
-
-occurence2Symbol = {
- occurence.ZeroOrMore: '*',
- occurence.ZeroOrOne: '?',
- occurence.OneOrMore: '+',
- }
-
-
-def generateElement(name, signature):
- if signature is None:
- return ''
- # Create the list of sub-elements.
- subElementList = []
- for occurence in signature.queryTaggedValue('directives', ()):
- subElementList.append(
- occurence.tag + occurence2Symbol.get(occurence.__class__, '')
- )
- fields = zope.schema.getFieldsInOrder(signature)
- for attrName, field in fields:
- if isinstance(field, attr.TextNode):
- subElementList.append('#PCDATA')
- break
- subElementList = ','.join(subElementList)
- if subElementList:
- subElementList = ' (' + subElementList + ')'
- text = '\n' %(name, subElementList)
- # Create a list of attributes for this element.
- for attrName, field in fields:
- # Ignore text nodes, since they are not attributes.
- if isinstance(field, attr.TextNode):
- continue
- # Create the type
- if isinstance(field, attr.Choice):
- type = '(' + '|'.join(field.choices.keys()) + ')'
- else:
- type = 'CDATA'
- # Create required flag
- if field.required:
- required = '#REQUIRED'
- else:
- required = '#IMPLIED'
- # Put it all together
- text += '\n' %(name, attrName, type, required)
- text += '\n'
- # Walk through all sub-elements, creating th eDTD entries for them.
- for occurence in signature.queryTaggedValue('directives', ()):
- text += generateElement(occurence.tag, occurence.signature)
- return text
-
-
-def generate(useWrapper=False):
- text = generateElement('document', document.Document.signature)
- if useWrapper:
- text = '\n' %text
- return text
-
-def main():
- print generate()
diff --git a/z3c/rml/flowable.py b/z3c/rml/flowable.py
deleted file mode 100644
index 8b139e95..00000000
--- a/z3c/rml/flowable.py
+++ /dev/null
@@ -1,1611 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Flowable Element Processing
-"""
-import copy
-import logging
-import re
-import reportlab.lib.styles
-import reportlab.platypus
-import reportlab.platypus.doctemplate
-import reportlab.platypus.flowables
-import reportlab.platypus.tables
-import zope.schema
-from reportlab.lib import styles, utils
-from xml.sax.saxutils import unescape
-from z3c.rml import attr, directive, interfaces, occurence
-from z3c.rml import form, platypus, special, SampleStyleSheet, stylesheet
-
-try:
- import reportlab.graphics.barcode
-except ImportError:
- # barcode package has not been installed
- import types
- import reportlab.graphics
- reportlab.graphics.barcode = types.ModuleType('barcode')
- reportlab.graphics.barcode.createBarcodeDrawing = None
-
-# XXX:Copy of reportlab.lib.pygments2xpre.pygments2xpre to fix bug in Python 2.
-def pygments2xpre(s, language="python"):
- "Return markup suitable for XPreformatted"
- try:
- from pygments import highlight
- from pygments.formatters import HtmlFormatter
- except ImportError:
- return s
-
- from pygments.lexers import get_lexer_by_name
-
- l = get_lexer_by_name(language)
-
- h = HtmlFormatter()
- # XXX: Does not work in Python 2, since pygments creates non-unicode
- # outpur snippets.
- #from io import StringIO
- from cStringIO import StringIO
- out = StringIO()
- highlight(s,l,h,out)
- styles = [(cls, style.split(';')[0].split(':')[1].strip())
- for cls, (style, ttype, level) in h.class2style.items()
- if cls and style and style.startswith('color:')]
- from reportlab.lib.pygments2xpre import _2xpre
- return _2xpre(out.getvalue(),styles)
-
-
-class Flowable(directive.RMLDirective):
- klass=None
- attrMapping = None
-
- def process(self):
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- self.parent.flow.append(self.klass(**args))
-
-class ISpacer(interfaces.IRMLDirectiveSignature):
- """Creates a vertical space in the flow."""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the spacer. Currently not implemented.',
- default=100,
- required=False)
-
- length = attr.Measurement(
- title=u'Length',
- description=u'The height of the spacer.',
- required=True)
-
-class Spacer(Flowable):
- signature = ISpacer
- klass = reportlab.platypus.Spacer
- attrMapping = {'length': 'height'}
-
-
-class IIllustration(interfaces.IRMLDirectiveSignature):
- """Inserts an illustration with graphics elements."""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the illustration.',
- required=True)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the illustration.',
- default=100,
- required=True)
-
-class Illustration(Flowable):
- signature = IIllustration
- klass = platypus.Illustration
-
- def process(self):
- args = dict(self.getAttributeValues())
- self.parent.flow.append(self.klass(self, **args))
-
-
-class IBarCodeFlowable(form.IBarCodeBase):
- """Creates a bar code as a flowable."""
-
- value = attr.String(
- title=u'Value',
- description=u'The value represented by the code.',
- required=True)
-
-class BarCodeFlowable(Flowable):
- signature = IBarCodeFlowable
- klass = staticmethod(reportlab.graphics.barcode.createBarcodeDrawing)
- attrMapping = {'code': 'codeName'}
-
-class IPluginFlowable(interfaces.IRMLDirectiveSignature):
- """Inserts a custom flowable developed in Python."""
-
- module = attr.String(
- title=u'Module',
- description=u'The Python module in which the flowable is located.',
- required=True)
-
- function = attr.String(
- title=u'Function',
- description=(u'The name of the factory function within the module '
- u'that returns the custom flowable.'),
- required=True)
-
- params = attr.TextNode(
- title=u'Parameters',
- description=(u'A list of parameters encoded as a long string.'),
- required=False)
-
-class PluginFlowable(Flowable):
- signature = IPluginFlowable
-
- def process(self):
- modulePath, functionName, text = self.getAttributeValues(
- valuesOnly=True)
- module = __import__(modulePath, {}, {}, [modulePath])
- function = getattr(module, functionName)
- flowables = function(text)
- if not isinstance(flowables, (tuple, list)):
- flowables = [flowables]
- self.parent.flow += list(flowables)
-
-
-class IMinimalParagraphBase(interfaces.IRMLDirectiveSignature):
-
- style = attr.Style(
- title=u'Style',
- description=(u'The paragraph style that is applied to the paragraph. '
- u'See the ``paraStyle`` tag for creating a paragraph '
- u'style.'),
- required=False)
-
- bulletText = attr.String(
- title=u'Bullet Character',
- description=(u'The bullet character is the ASCII representation of '
- u'the symbol making up the bullet in a listing.'),
- required=False)
-
- dedent = attr.Integer(
- title=u'Dedent',
- description=(u'Number of characters to be removed in front of every '
- u'line of the text.'),
- required=False)
-
-
-class IBold(interfaces.IRMLDirectiveSignature):
- """Renders the text inside as bold."""
-
-class IItalic(interfaces.IRMLDirectiveSignature):
- """Renders the text inside as italic."""
-
-class IUnderLine(interfaces.IRMLDirectiveSignature):
- """Underlines the contained text."""
-
-class IBreak(interfaces.IRMLDirectiveSignature):
- """Inserts a line break in the paragraph."""
-
-class IPageNumber(interfaces.IRMLDirectiveSignature):
- """Inserts the current page number into the text."""
-
-class IParagraphBase(IMinimalParagraphBase):
- occurence.containing(
- occurence.ZeroOrMore('b', IBold),
- occurence.ZeroOrMore('i', IItalic),
- occurence.ZeroOrMore('u', IUnderLine),
- occurence.ZeroOrMore('br', IBreak,
- condition=occurence.laterThanReportlab21),
- occurence.ZeroOrMore('pageNumber', IPageNumber)
- )
-
-class IPreformatted(IMinimalParagraphBase):
- """A preformatted text, similar to the tag in HTML."""
-
- style = attr.Style(
- title=u'Style',
- description=(u'The paragraph style that is applied to the paragraph. '
- u'See the ``paraStyle`` tag for creating a paragraph '
- u'style.'),
- default=SampleStyleSheet['Code'],
- required=False)
-
- text = attr.RawXMLContent(
- title=u'Text',
- description=(u'The text that will be layed out.'),
- required=True)
-
- maxLineLength = attr.Integer(
- title=u'Max Line Length',
- description=(u'The maximum number of characters on one line.'),
- required=False)
-
- newLineChars = attr.Text(
- title=u'New Line Characters',
- description=u'The characters placed at the beginning of a wrapped line',
- required=False)
-
-class Preformatted(Flowable):
- signature = IPreformatted
- klass = reportlab.platypus.Preformatted
-
-class IXPreformatted(IParagraphBase):
- """A preformatted text that allows paragraph markup."""
-
- style = attr.Style(
- title=u'Style',
- description=(u'The paragraph style that is applied to the paragraph. '
- u'See the ``paraStyle`` tag for creating a paragraph '
- u'style.'),
- default=SampleStyleSheet['Normal'],
- required=False)
-
- text = attr.RawXMLContent(
- title=u'Text',
- description=(u'The text that will be layed out.'),
- required=True)
-
-class XPreformatted(Flowable):
- signature = IXPreformatted
- klass = reportlab.platypus.XPreformatted
-
-
-class ICodeSnippet(IXPreformatted):
- """A code snippet with text highlighting."""
-
- style = attr.Style(
- title=u'Style',
- description=(u'The paragraph style that is applied to the paragraph. '
- u'See the ``paraStyle`` tag for creating a paragraph '
- u'style.'),
- required=False)
-
- language = attr.String(
- title=u'Language',
- description=u'The language the code snippet is written in.',
- required=False)
-
-class CodeSnippet(XPreformatted):
- signature = ICodeSnippet
-
- def process(self):
- args = dict(self.getAttributeValues())
- lang = args.pop('language', None)
- args['text'] = unescape(args['text'])
- if lang is not None:
- args['text'] = pygments2xpre(args['text'], lang.lower())
- if 'style' not in args:
- args['style'] = attr._getStyle(self, 'Code')
- self.parent.flow.append(self.klass(**args))
-
-
-class IParagraph(IParagraphBase, stylesheet.IBaseParagraphStyle):
- """Lays out an entire paragraph."""
-
- text = attr.XMLContent(
- title=u'Text',
- description=(u'The text that will be layed out.'),
- required=True)
-
-class Paragraph(Flowable):
- signature = IParagraph
- klass = reportlab.platypus.Paragraph
- defaultStyle = 'Normal'
-
- styleAttributes = zope.schema.getFieldNames(stylesheet.IBaseParagraphStyle)
-
- def processStyle(self, style):
- attrs = []
- for attr in self.styleAttributes:
- if self.element.get(attr) is not None:
- attrs.append(attr)
- attrs = self.getAttributeValues(select=attrs)
- if attrs:
- style = copy.deepcopy(style)
- for name, value in attrs:
- setattr(style, name, value)
- return style
-
- def process(self):
- args = dict(self.getAttributeValues(ignore=self.styleAttributes))
- if 'style' not in args:
- args['style'] = attr._getStyle(self, self.defaultStyle)
- args['style'] = self.processStyle(args['style'])
- self.parent.flow.append(self.klass(**args))
-
-
-class ITitle(IParagraph):
- """The title is a simple paragraph with a special title style."""
-
-class Title(Paragraph):
- signature = ITitle
- defaultStyle = 'Title'
-
-class IHeading1(IParagraph):
- """Heading 1 is a simple paragraph with a special heading 1 style."""
-
-class Heading1(Paragraph):
- signature = IHeading1
- defaultStyle = 'Heading1'
-
-
-class IHeading2(IParagraph):
- """Heading 2 is a simple paragraph with a special heading 2 style."""
-
-class Heading2(Paragraph):
- signature = IHeading2
- defaultStyle = 'Heading2'
-
-
-class IHeading3(IParagraph):
- """Heading 3 is a simple paragraph with a special heading 3 style."""
-
-class Heading3(Paragraph):
- signature = IHeading3
- defaultStyle = 'Heading3'
-
-
-class IHeading4(IParagraph):
- """Heading 4 is a simple paragraph with a special heading 4 style."""
-
-class Heading4(Paragraph):
- signature = IHeading4
- defaultStyle = 'Heading4'
-
-
-class IHeading5(IParagraph):
- """Heading 5 is a simple paragraph with a special heading 5 style."""
-
-class Heading5(Paragraph):
- signature = IHeading5
- defaultStyle = 'Heading5'
-
-
-class IHeading6(IParagraph):
- """Heading 6 is a simple paragraph with a special heading 6 style."""
-
-class Heading6(Paragraph):
- signature = IHeading6
- defaultStyle = 'Heading6'
-
-
-class ITableCell(interfaces.IRMLDirectiveSignature):
- """A table cell within a table."""
-
- content = attr.RawXMLContent(
- title=u'Content',
- description=(u'The content of the cell; can be text or any flowable.'),
- required=True)
-
- fontName = attr.String(
- title=u'Font Name',
- description=u'The name of the font for the cell.',
- required=False)
-
- fontSize = attr.Measurement(
- title=u'Font Size',
- description=u'The font size for the text of the cell.',
- required=False)
-
- leading = attr.Measurement(
- title=u'Leading',
- description=(u'The height of a single text line. It includes '
- u'character height.'),
- required=False)
-
- fontColor = attr.Color(
- title=u'Font Color',
- description=u'The color in which the text will appear.',
- required=False)
-
- leftPadding = attr.Measurement(
- title=u'Left Padding',
- description=u'The size of the padding on the left side.',
- required=False)
-
- rightPadding = attr.Measurement(
- title=u'Right Padding',
- description=u'The size of the padding on the right side.',
- required=False)
-
- topPadding = attr.Measurement(
- title=u'Top Padding',
- description=u'The size of the padding on the top.',
- required=False)
-
- bottomPadding = attr.Measurement(
- title=u'Bottom Padding',
- description=u'The size of the padding on the bottom.',
- required=False)
-
- background = attr.Color(
- title=u'Background Color',
- description=u'The color to use as the background for the cell.',
- required=False)
-
- align = attr.Choice(
- title=u'Text Alignment',
- description=u'The text alignment within the cell.',
- choices=interfaces.ALIGN_TEXT_CHOICES,
- required=False)
-
- vAlign = attr.Choice(
- title=u'Vertical Alignment',
- description=u'The vertical alignment of the text within the cell.',
- choices=interfaces.VALIGN_TEXT_CHOICES,
- required=False)
-
- lineBelowThickness = attr.Measurement(
- title=u'Line Below Thickness',
- description=u'The thickness of the line below the cell.',
- required=False)
-
- lineBelowColor = attr.Color(
- title=u'Line Below Color',
- description=u'The color of the line below the cell.',
- required=False)
-
- lineBelowCap = attr.Choice(
- title=u'Line Below Cap',
- description=u'The cap at the end of the line below the cell.',
- choices=interfaces.CAP_CHOICES,
- required=False)
-
- lineBelowCount = attr.Integer(
- title=u'Line Below Count',
- description=(u'Describes whether the line below is a single (1) or '
- u'double (2) line.'),
- required=False)
-
- lineBelowSpace = attr.Measurement(
- title=u'Line Below Space',
- description=u'The space of the line below the cell.',
- required=False)
-
- lineAboveThickness = attr.Measurement(
- title=u'Line Above Thickness',
- description=u'The thickness of the line above the cell.',
- required=False)
-
- lineAboveColor = attr.Color(
- title=u'Line Above Color',
- description=u'The color of the line above the cell.',
- required=False)
-
- lineAboveCap = attr.Choice(
- title=u'Line Above Cap',
- description=u'The cap at the end of the line above the cell.',
- choices=interfaces.CAP_CHOICES,
- required=False)
-
- lineAboveCount = attr.Integer(
- title=u'Line Above Count',
- description=(u'Describes whether the line above is a single (1) or '
- u'double (2) line.'),
- required=False)
-
- lineAboveSpace = attr.Measurement(
- title=u'Line Above Space',
- description=u'The space of the line above the cell.',
- required=False)
-
- lineLeftThickness = attr.Measurement(
- title=u'Left Line Thickness',
- description=u'The thickness of the line left of the cell.',
- required=False)
-
- lineLeftColor = attr.Color(
- title=u'Left Line Color',
- description=u'The color of the line left of the cell.',
- required=False)
-
- lineLeftCap = attr.Choice(
- title=u'Line Left Cap',
- description=u'The cap at the end of the line left of the cell.',
- choices=interfaces.CAP_CHOICES,
- required=False)
-
- lineLeftCount = attr.Integer(
- title=u'Line Left Count',
- description=(u'Describes whether the left line is a single (1) or '
- u'double (2) line.'),
- required=False)
-
- lineLeftSpace = attr.Measurement(
- title=u'Line Left Space',
- description=u'The space of the line left of the cell.',
- required=False)
-
- lineRightThickness = attr.Measurement(
- title=u'Right Line Thickness',
- description=u'The thickness of the line right of the cell.',
- required=False)
-
- lineRightColor = attr.Color(
- title=u'Right Line Color',
- description=u'The color of the line right of the cell.',
- required=False)
-
- lineRightCap = attr.Choice(
- title=u'Line Right Cap',
- description=u'The cap at the end of the line right of the cell.',
- choices=interfaces.CAP_CHOICES,
- required=False)
-
- lineRightCount = attr.Integer(
- title=u'Line Right Count',
- description=(u'Describes whether the right line is a single (1) or '
- u'double (2) line.'),
- required=False)
-
- lineRightSpace = attr.Measurement(
- title=u'Line Right Space',
- description=u'The space of the line right of the cell.',
- required=False)
-
- href = attr.Text(
- title=u'Link URL',
- description=u'When specified, the cell becomes a link to that URL.',
- required=False)
-
- destination = attr.Text(
- title=u'Link Destination',
- description=(u'When specified, the cell becomes a link to that '
- u'destination.'),
- required=False)
-
-
-class TableCell(directive.RMLDirective):
- signature = ITableCell
- styleAttributesMapping = (
- ('FONTNAME', ('fontName',)),
- ('FONTSIZE', ('fontSize',)),
- ('TEXTCOLOR', ('fontColor',)),
- ('LEADING', ('leading',)),
- ('LEFTPADDING', ('leftPadding',)),
- ('RIGHTPADDING', ('rightPadding',)),
- ('TOPPADDING', ('topPadding',)),
- ('BOTTOMPADDING', ('bottomPadding',)),
- ('BACKGROUND', ('background',)),
- ('ALIGNMENT', ('align',)),
- ('VALIGN', ('vAlign',)),
- ('LINEBELOW', ('lineBelowThickness', 'lineBelowColor',
- 'lineBelowCap', 'lineBelowCount', 'lineBelowSpace')),
- ('LINEABOVE', ('lineAboveThickness', 'lineAboveColor',
- 'lineAboveCap', 'lineAboveCount', 'lineAboveSpace')),
- ('LINEBEFORE', ('lineLeftThickness', 'lineLeftColor',
- 'lineLeftCap', 'lineLeftCount', 'lineLeftSpace')),
- ('LINEAFTER', ('lineRightThickness', 'lineRightColor',
- 'lineRightCap', 'lineRightCount', 'lineRightSpace')),
- ('HREF', ('href',)),
- ('DESTINATION', ('destination',)),
- )
-
- def processStyle(self):
- row = len(self.parent.parent.rows)
- col = len(self.parent.cols)
- for styleAction, attrNames in self.styleAttributesMapping:
- attrs = []
- for attr in attrNames:
- if self.element.get(attr) is not None:
- attrs.append(attr)
- if not attrs:
- continue
- args = self.getAttributeValues(select=attrs, valuesOnly=True)
- if args:
- self.parent.parent.style.add(
- styleAction, [col, row], [col, row], *args)
-
- def process(self):
- # Produce style
- self.processStyle()
- # Produce cell data
- flow = Flow(self.element, self.parent)
- flow.process()
- content = flow.flow
- if len(content) == 0:
- content = self.getAttributeValues(
- select=('content',), valuesOnly=True)[0]
- self.parent.cols.append(content)
-
-
-class ITableRow(interfaces.IRMLDirectiveSignature):
- """A table row in the block table."""
- occurence.containing(
- occurence.OneOrMore('td', ITableCell),
- )
-
-class TableRow(directive.RMLDirective):
- signature = ITableRow
- factories = {'td': TableCell}
-
- def process(self):
- self.cols = []
- self.processSubDirectives()
- self.parent.rows.append(self.cols)
-
-
-class ITableBulkData(interfaces.IRMLDirectiveSignature):
- """Bulk Data allows one to quickly create a table."""
-
- content = attr.TextNodeSequence(
- title=u'Content',
- description=u'The bulk data.',
- splitre=re.compile('\n'),
- value_type=attr.Sequence(splitre=re.compile(','),
- value_type=attr.Text())
- )
-
-class TableBulkData(directive.RMLDirective):
- signature = ITableBulkData
-
- def process(self):
- self.parent.rows = self.getAttributeValues(valuesOnly=True)[0]
-
-
-class BlockTableStyle(stylesheet.BlockTableStyle):
-
- def process(self):
- self.style = copy.deepcopy(self.parent.style)
- attrs = self.getAttributeValues()
- for name, value in attrs:
- setattr(self.style, name, value)
- self.processSubDirectives()
- self.parent.style = self.style
-
-
-class IBlockTable(interfaces.IRMLDirectiveSignature):
- """A typical block table."""
- occurence.containing(
- occurence.ZeroOrMore('tr', ITableRow),
- occurence.ZeroOrOne('bulkData', ITableBulkData),
- occurence.ZeroOrMore('blockTableStyle', stylesheet.IBlockTableStyle),
- )
-
- style = attr.Style(
- title=u'Style',
- description=(u'The table style that is applied to the table. '),
- required=False)
-
- rowHeights = attr.Sequence(
- title=u'Row Heights',
- description=u'A list of row heights in the table.',
- value_type=attr.Measurement(),
- required=False)
-
- colWidths = attr.Sequence(
- title=u'Column Widths',
- description=u'A list of column widths in the table.',
- value_type=attr.Measurement(allowPercentage=True, allowStar=True),
- required=False)
-
- repeatRows = attr.Integer(
- title=u'Repeat Rows',
- description=u'A flag to repeat rows upon table splits.',
- required=False)
-
- alignment = attr.Choice(
- title=u'Alignment',
- description=u'The alignment of whole table.',
- choices=interfaces.ALIGN_TEXT_CHOICES,
- required=False)
-
-class BlockTable(Flowable):
- signature = IBlockTable
- klass = reportlab.platypus.Table
- factories = {
- 'tr': TableRow,
- 'bulkData': TableBulkData,
- 'blockTableStyle': BlockTableStyle}
-
- def process(self):
- attrs = dict(self.getAttributeValues())
- # Get the table style; create a new one, if none is found
- style = attrs.pop('style', None)
- if style is None:
- self.style = reportlab.platypus.tables.TableStyle()
- else:
- self.style = copy.deepcopy(style)
- hAlign = attrs.pop('alignment', None)
- # Extract all table rows and cells
- self.rows = []
- self.processSubDirectives(None)
- # Create the table
- repeatRows = attrs.pop('repeatRows', None)
- table = self.klass(self.rows, style=self.style, **attrs)
- if repeatRows:
- table.repeatRows = repeatRows
- if hAlign:
- table.hAlign = hAlign
- # Must set keepWithNext on table, since the style is not stored corr.
- if hasattr(self.style, 'keepWithNext'):
- table.keepWithNext = self.style.keepWithNext
- self.parent.flow.append(table)
-
-
-class INextFrame(interfaces.IRMLDirectiveSignature):
- """Switch to the next frame."""
- name = attr.StringOrInt(
- title=u'Name',
- description=(u'The name or index of the next frame.'),
- required=False)
-
-class NextFrame(Flowable):
- signature = INextFrame
- klass = reportlab.platypus.doctemplate.FrameBreak
- attrMapping = {'name': 'ix'}
-
-
-class ISetNextFrame(interfaces.IRMLDirectiveSignature):
- """Define the next frame to switch to."""
- name = attr.StringOrInt(
- title=u'Name',
- description=(u'The name or index of the next frame.'),
- required=True)
-
-class SetNextFrame(Flowable):
- signature = INextFrame
- klass = reportlab.platypus.doctemplate.NextFrameFlowable
- attrMapping = {'name': 'ix'}
-
-
-class INextPage(interfaces.IRMLDirectiveSignature):
- """Switch to the next page."""
-
-class NextPage(Flowable):
- signature = INextPage
- klass = reportlab.platypus.PageBreak
-
-
-class ISetNextTemplate(interfaces.IRMLDirectiveSignature):
- """Define the next page template to use."""
- name = attr.StringOrInt(
- title=u'Name',
- description=u'The name or index of the next page template.',
- required=True)
-
-class SetNextTemplate(Flowable):
- signature = ISetNextTemplate
- klass = reportlab.platypus.doctemplate.NextPageTemplate
- attrMapping = {'name': 'pt'}
-
-
-class IConditionalPageBreak(interfaces.IRMLDirectiveSignature):
- """Switch to the next page if not enough vertical space is available."""
- height = attr.Measurement(
- title=u'height',
- description=u'The minimal height that must be remaining on the page.',
- required=True)
-
-class ConditionalPageBreak(Flowable):
- signature = IConditionalPageBreak
- klass = reportlab.platypus.CondPageBreak
-
-
-class IKeepInFrame(interfaces.IRMLDirectiveSignature):
- """Ask a flowable to stay within the frame."""
-
- maxWidth = attr.Measurement(
- title=u'Maximum Width',
- description=u'The maximum width the flowables are allotted.',
- default=None,
- required=False)
-
- maxHeight = attr.Measurement(
- title=u'Maximum Height',
- description=u'The maximum height the flowables are allotted.',
- default=None,
- required=False)
-
- mergeSpace = attr.Boolean(
- title=u'Merge Space',
- description=u'A flag to set whether the space should be merged.',
- required=False)
-
- onOverflow = attr.Choice(
- title=u'On Overflow',
- description=u'Defines what has to be done, if an overflow is detected.',
- choices=('error', 'overflow', 'shrink', 'truncate'),
- required=False)
-
- id = attr.Text(
- title=u'Name/Id',
- description=u'The name/id of the flowable.',
- required=False)
-
- frame = attr.StringOrInt(
- title=u'Frame',
- description=u'The frame to which the flowable should be fitted.',
- required=False)
-
-class KeepInFrame(Flowable):
- signature = IKeepInFrame
- klass = platypus.KeepInFrame
- attrMapping = {'onOverflow': 'mode', 'id': 'name'}
-
- def process(self):
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- # Circumvent broken-ness in zope.schema
- args['maxWidth'] = args.get('maxWidth', None)
- args['maxHeight'] = args.get('maxHeight', None)
- # If the frame was specifed, get us there
- frame = args.pop('frame', None)
- if frame:
- self.parent.flow.append(
- reportlab.platypus.doctemplate.FrameBreak(frame))
- # Create the content of the container
- flow = Flow(self.element, self.parent)
- flow.process()
- args['content'] = flow.flow
- # Create the keep in frame container
- frame = self.klass(**args)
- self.parent.flow.append(frame)
-
-class IKeepTogether(interfaces.IRMLDirectiveSignature):
- """Keep the child flowables in the same frame. Add frame break when
- necessary."""
-
- maxHeight = attr.Measurement(
- title=u'Maximum Height',
- description=u'The maximum height the flowables are allotted.',
- default=None,
- required=False)
-
-class KeepTogether(Flowable):
- signature = IKeepTogether
- klass = reportlab.platypus.flowables.KeepTogether
-
- def process(self):
- args = dict(self.getAttributeValues())
-
- # Create the content of the container
- flow = Flow(self.element, self.parent)
- flow.process()
-
- # Create the keep in frame container
- frame = self.klass(flow.flow, **args)
- self.parent.flow.append(frame)
-
-class IImage(interfaces.IRMLDirectiveSignature):
- """An image."""
-
- src = attr.Image(
- title=u'Image Source',
- description=u'The file that is used to extract the image data.',
- onlyOpen=True,
- required=True)
-
- width = attr.Measurement(
- title=u'Image Width',
- description=u'The width of the image.',
- required=False)
-
- height = attr.Measurement(
- title=u'Image Height',
- description=u'The height the image.',
- required=False)
-
- preserveAspectRatio = attr.Boolean(
- title=u'Preserve Aspect Ratio',
- description=(u'If set, the aspect ratio of the image is kept. When '
- u'both, width and height, are specified, the image '
- u'will be fitted into that bounding box.'),
- default=False,
- required=False)
-
- mask = attr.Color(
- title=u'Mask',
- description=u'The color mask used to render the image.',
- required=False)
-
- align = attr.Choice(
- title=u'Alignment',
- description=u'The alignment of the image within the frame.',
- choices=interfaces.ALIGN_TEXT_CHOICES,
- required=False)
-
- vAlign = attr.Choice(
- title=u'Vertical Alignment',
- description=u'The vertical alignment of the image.',
- choices=interfaces.VALIGN_TEXT_CHOICES,
- required=False)
-
-class Image(Flowable):
- signature = IImage
- klass = reportlab.platypus.flowables.Image
- attrMapping = {'src': 'filename', 'align': 'hAlign'}
-
- def process(self):
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- preserveAspectRatio = args.pop('preserveAspectRatio', False)
- if preserveAspectRatio:
- img = utils.ImageReader(args['filename'])
- args['filename'].seek(0)
- iw, ih = img.getSize()
- if 'width' in args and 'height' not in args:
- args['height'] = args['width'] * ih / iw
- elif 'width' not in args and 'height' in args:
- args['width'] = args['height'] * iw / ih
- elif 'width' in args and 'height' in args:
- # In this case, the width and height specify a bounding box
- # and the size of the image within that box is maximized.
- if args['width'] * ih / iw <= args['height']:
- args['height'] = args['width'] * ih / iw
- elif args['height'] * iw / ih < args['width']:
- args['width'] = args['height'] * iw / ih
- else:
- # This should not happen.
- raise ValueError('Cannot keep image in bounding box.')
- else:
- # No size was specified, so do nothing.
- pass
-
- vAlign = args.pop('vAlign', None)
- hAlign = args.pop('hAlign', None)
- img = self.klass(**args)
- if hAlign:
- img.hAlign = hAlign
- if vAlign:
- img.vAlign = vAlign
- self.parent.flow.append(img)
-
-
-class IImageAndFlowables(interfaces.IRMLDirectiveSignature):
- """An image with flowables around it."""
-
- imageName = attr.Image(
- title=u'Image',
- description=u'The file that is used to extract the image data.',
- onlyOpen=True,
- required=True)
-
- imageWidth = attr.Measurement(
- title=u'Image Width',
- description=u'The width of the image.',
- required=False)
-
- imageHeight = attr.Measurement(
- title=u'Image Height',
- description=u'The height the image.',
- required=False)
-
- imageMask = attr.Color(
- title=u'Mask',
- description=u'The height the image.',
- required=False)
-
- imageLeftPadding = attr.Measurement(
- title=u'Image Left Padding',
- description=u'The padding on the left side of the image.',
- required=False)
-
- imageRightPadding = attr.Measurement(
- title=u'Image Right Padding',
- description=u'The padding on the right side of the image.',
- required=False)
-
- imageTopPadding = attr.Measurement(
- title=u'Image Top Padding',
- description=u'The padding on the top of the image.',
- required=False)
-
- imageBottomPadding = attr.Measurement(
- title=u'Image Bottom Padding',
- description=u'The padding on the bottom of the image.',
- required=False)
-
- imageSide = attr.Choice(
- title=u'Image Side',
- description=u'The side at which the image will be placed.',
- choices=('left', 'right'),
- required=False)
-
-class ImageAndFlowables(Flowable):
- signature = IImageAndFlowables
- klass = reportlab.platypus.flowables.ImageAndFlowables
- attrMapping = {'imageWidth': 'width', 'imageHeight': 'height',
- 'imageMask': 'mask', 'imageName': 'filename'}
-
- def process(self):
- flow = Flow(self.element, self.parent)
- flow.process()
- # Create the image
- args = dict(self.getAttributeValues(
- select=('imageName', 'imageWidth', 'imageHeight', 'imageMask'),
- attrMapping=self.attrMapping))
- img = reportlab.platypus.flowables.Image(**args)
- # Create the flowable and add it
- args = dict(self.getAttributeValues(
- ignore=('imageName', 'imageWidth', 'imageHeight', 'imageMask'),
- attrMapping=self.attrMapping))
- self.parent.flow.append(
- self.klass(img, flow.flow, **args))
-
-
-class IPTO(interfaces.IRMLDirectiveSignature):
- '''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.'''
-
-class PTO(Flowable):
- signature = IPTO
- klass = reportlab.platypus.flowables.PTOContainer
-
- def process(self):
- # Get Content
- flow = Flow(self.element, self.parent)
- flow.process()
- # Get the header
- ptoHeader = self.element.find('pto_header')
- header = None
- if ptoHeader is not None:
- header = Flow(ptoHeader, self.parent)
- header.process()
- header = header.flow
- # Get the trailer
- ptoTrailer = self.element.find('pto_trailer')
- trailer = None
- if ptoTrailer is not None:
- trailer = Flow(ptoTrailer, self.parent)
- trailer.process()
- trailer = trailer.flow
- # Create and add the PTO Container
- self.parent.flow.append(self.klass(flow.flow, trailer, header))
-
-
-class IIndent(interfaces.IRMLDirectiveSignature):
- """Indent the contained flowables."""
-
- left = attr.Measurement(
- title=u'Left',
- description=u'The indentation to the left.',
- required=False)
-
- right = attr.Measurement(
- title=u'Right',
- description=u'The indentation to the right.',
- required=False)
-
-class Indent(Flowable):
- signature = IIndent
-
- def process(self):
- kw = dict(self.getAttributeValues())
- # Indent
- self.parent.flow.append(reportlab.platypus.doctemplate.Indenter(**kw))
- # Add Content
- flow = Flow(self.element, self.parent)
- flow.process()
- self.parent.flow += flow.flow
- # Dedent
- for name, value in kw.items():
- kw[name] = -value
- self.parent.flow.append(reportlab.platypus.doctemplate.Indenter(**kw))
-
-
-class IFixedSize(interfaces.IRMLDirectiveSignature):
- """Create a container flowable of a fixed size."""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width the flowables are allotted.',
- required=True)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height the flowables are allotted.',
- required=True)
-
-class FixedSize(Flowable):
- signature = IFixedSize
- klass = reportlab.platypus.flowables.KeepInFrame
- attrMapping = {'width': 'maxWidth', 'height': 'maxHeight'}
-
- def process(self):
- flow = Flow(self.element, self.parent)
- flow.process()
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- frame = self.klass(content=flow.flow, mode='shrink', **args)
- self.parent.flow.append(frame)
-
-
-class IBookmarkPage(interfaces.IRMLDirectiveSignature):
- """
- This creates a bookmark to the current page which can be referred to with
- the given key elsewhere.
-
- PDF offers very fine grained control over how Acrobat reader is zoomed
- when people link to this. The default is to keep the user's current zoom
- settings. the last arguments may or may not be needed depending on the
- choice of 'fitType'.
- """
-
- name = attr.Text(
- title=u'Name',
- description=u'The name of the bookmark.',
- required=True)
-
- fit = attr.Choice(
- title=u'Fit',
- description=u'The Fit Type.',
- choices=('XYZ', 'Fit', 'FitH', 'FitV', 'FitR'),
- required=False)
-
- top = attr.Measurement(
- title=u'Top',
- description=u'The top position.',
- required=False)
-
- bottom = attr.Measurement(
- title=u'Bottom',
- description=u'The bottom position.',
- required=False)
-
- left = attr.Measurement(
- title=u'Left',
- description=u'The left position.',
- required=False)
-
- right = attr.Measurement(
- title=u'Right',
- description=u'The right position.',
- required=False)
-
- zoom = attr.Float(
- title=u'Zoom',
- description=u'The zoom level when clicking on the bookmark.',
- required=False)
-
-class BookmarkPage(Flowable):
- signature = IBookmarkPage
- klass = platypus.BookmarkPage
- attrMapping = {'name': 'key', 'fitType': 'fit'}
-
-
-class IBookmark(interfaces.IRMLDirectiveSignature):
- """
- This creates a bookmark to the current page which can be referred to with
- the given key elsewhere. (Used inside a story.)
- """
-
- name = attr.Text(
- title=u'Name',
- description=u'The name of the bookmark.',
- required=True)
-
- x = attr.Measurement(
- title=u'X Coordinate',
- description=u'The x-position of the bookmark.',
- default=0,
- required=False)
-
- y = attr.Measurement(
- title=u'Y Coordinate',
- description=u'The y-position of the bookmark.',
- default=0,
- required=False)
-
-class Bookmark(Flowable):
- signature = IBookmark
- klass = platypus.Bookmark
- attrMapping = {'name': 'key', 'x': 'relativeX', 'y': 'relativeY'}
-
-
-class ILink(interfaces.IRMLDirectiveSignature):
- """Place an internal link around a set of flowables."""
-
- destination = attr.Text(
- title=u'Destination',
- description=u'The name of the destination to link to.',
- required=False)
-
- url = attr.Text(
- title=u'URL',
- description=u'The URL to link to.',
- required=False)
-
- boxStrokeWidth = attr.Measurement(
- title=u'Box Stroke Width',
- description=u'The width of the box border line.',
- required=False)
-
- boxStrokeDashArray = attr.Sequence(
- title=u'Box Stroke Dash Array',
- description=u'The dash array of the box border line.',
- value_type=attr.Float(),
- required=False)
-
- boxStrokeColor = attr.Color(
- title=u'Box Stroke Color',
- description=(u'The color in which the box border is drawn.'),
- required=False)
-
-
-class Link(Flowable):
- signature = ILink
- attrMapping = {'destination': 'destinationname',
- 'boxStrokeWidth': 'thickness',
- 'boxStrokeDashArray': 'dashArray',
- 'boxStrokeColor': 'color'}
-
- def process(self):
- flow = Flow(self.element, self.parent)
- flow.process()
- args = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- self.parent.flow.append(platypus.Link(flow.flow, **args))
-
-
-class IHorizontalRow(interfaces.IRMLDirectiveSignature):
- """Create a horizontal line on the page."""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the line on the page.',
- allowPercentage=True,
- required=False)
-
- thickness = attr.Measurement(
- title=u'Thickness',
- description=u'Line Thickness',
- required=False)
-
- color = attr.Color(
- title=u'Color',
- description=u'The color of the line.',
- required=False)
-
- lineCap = attr.Choice(
- title=u'Cap',
- description=u'The cap at the end of the line.',
- choices=interfaces.CAP_CHOICES.keys(),
- required=False)
-
- spaceBefore = attr.Measurement(
- title=u'Space Before',
- description=u'The vertical space before the line.',
- required=False)
-
- spaceAfter = attr.Measurement(
- title=u'Space After',
- description=u'The vertical space after the line.',
- required=False)
-
- align = attr.Choice(
- title=u'Alignment',
- description=u'The alignment of the line within the frame.',
- choices=interfaces.ALIGN_TEXT_CHOICES,
- required=False)
-
- valign = attr.Choice(
- title=u'Vertical Alignment',
- description=u'The vertical alignment of the line.',
- choices=interfaces.VALIGN_TEXT_CHOICES,
- required=False)
-
- dash = attr.Sequence(
- title=u'Dash-Pattern',
- description=u'The dash-pattern of a line.',
- value_type=attr.Measurement(),
- default=None,
- required=False)
-
-class HorizontalRow(Flowable):
- signature = IHorizontalRow
- klass = reportlab.platypus.flowables.HRFlowable
- attrMapping = {'align': 'hAlign'}
-
-
-class IOutlineAdd(interfaces.IRMLDirectiveSignature):
- """Add a new entry to the outline of the PDF."""
-
- title = attr.TextNode(
- title=u'Title',
- description=u'The text displayed for this item.',
- required=True)
-
- key = attr.String(
- title=u'Key',
- description=u'The unique key of the item.',
- required=False)
-
- level = attr.Integer(
- title=u'Level',
- description=u'The level in the outline tree.',
- required=False)
-
- closed = attr.Boolean(
- title=u'Closed',
- description=(u'A flag to determine whether the sub-tree is closed '
- u'by default.'),
- required=False)
-
-
-class OutlineAdd(Flowable):
- signature = IOutlineAdd
- klass = platypus.OutlineAdd
-
-
-class NamedStringFlowable(reportlab.platypus.flowables.Flowable,
- special.TextFlowables):
-
- def __init__(self, manager, id, value):
- reportlab.platypus.flowables.Flowable.__init__(self)
- self.manager = manager
- self.id = id
- self._value = value
- self.value = u''
-
- def wrap(self, *args):
- return (0, 0)
-
- def draw(self):
- text = self._getText(self._value, self.manager.canvas,
- include_final_tail=False)
- self.manager.names[self.id] = text
-
-
-class INamedString(interfaces.IRMLDirectiveSignature):
- """Defines a name for a string."""
-
- id = attr.String(
- title=u'Id',
- description=u'The id under which the value will be known.',
- required=True)
-
- value = attr.XMLContent(
- title=u'Value',
- description=u'The text that is displayed if the id is called.',
- required=True)
-
-class NamedString(directive.RMLDirective):
- signature = INamedString
-
- def process(self):
- id, value = self.getAttributeValues(valuesOnly=True)
- manager = attr.getManager(self)
- # We have to delay assigning values, otherwise the last one wins.
- self.parent.flow.append(NamedStringFlowable(manager, id, self.element))
-
-
-class IShowIndex(interfaces.IRMLDirectiveSignature):
- """Creates an index in the document."""
-
- name = attr.String(
- title=u'Name',
- description=u'The name of the index.',
- default='index',
- required=False)
-
- dot = attr.String(
- title=u'Dot',
- description=u'The character to use as a dot.',
- required=False)
-
- style = attr.Style(
- title=u'Style',
- description=u'The paragraph style that is applied to the index. ',
- required=False)
-
- tableStyle = attr.Style(
- title=u'Table Style',
- description=u'The table style that is applied to the index layout. ',
- required=False)
-
-class ShowIndex(directive.RMLDirective):
- signature = IShowIndex
-
- def process(self):
- args = dict(self.getAttributeValues())
- manager = attr.getManager(self)
- index = manager.indexes[args['name']]
- args['format'] = index.formatFunc.__name__[8:]
- args['offset'] = index.offset
- index.setup(**args)
- self.parent.flow.append(index)
-
-
-class IBaseLogCall(interfaces.IRMLDirectiveSignature):
-
- message = attr.RawXMLContent(
- title=u'Message',
- description=u'The message to be logged.',
- required=True)
-
-class LogCallFlowable(reportlab.platypus.flowables.Flowable):
-
- def __init__(self, logger, level, message):
- self.logger = logger
- self.level = level
- self.message = message
-
- def wrap(self, *args):
- return (0, 0)
-
- def draw(self):
- self.logger.log(self.level, self.message)
-
-class BaseLogCall(directive.RMLDirective):
- signature = IBaseLogCall
- level = None
-
- def process(self):
- message = self.getAttributeValues(
- select=('message',), valuesOnly=True)[0]
- manager = attr.getManager(self)
- self.parent.flow.append(
- LogCallFlowable(manager.logger, self.level, message))
-
-class ILog(IBaseLogCall):
- """Log message at DEBUG level."""
-
- level = attr.Choice(
- title=u'Level',
- description=u'The default log level.',
- choices=interfaces.LOG_LEVELS,
- doLower=False,
- default=logging.INFO,
- required=True)
-
-class Log(BaseLogCall):
- signature = ILog
-
- @property
- def level(self):
- return self.getAttributeValues(select=('level',), valuesOnly=True)[0]
-
-class IDebug(IBaseLogCall):
- """Log message at DEBUG level."""
-
-class Debug(BaseLogCall):
- signature = IDebug
- level = logging.DEBUG
-
-
-class IInfo(IBaseLogCall):
- """Log message at INFO level."""
-
-class Info(BaseLogCall):
- signature = IInfo
- level = logging.INFO
-
-
-class IWarning(IBaseLogCall):
- """Log message at WARNING level."""
-
-class Warning(BaseLogCall):
- signature = IWarning
- level = logging.WARNING
-
-
-class IError(IBaseLogCall):
- """Log message at ERROR level."""
-
-class Error(BaseLogCall):
- signature = IError
- level = logging.ERROR
-
-
-class ICritical(IBaseLogCall):
- """Log message at CRITICAL level."""
-
-class Critical(BaseLogCall):
- signature = ICritical
- level = logging.CRITICAL
-
-
-class IFlow(interfaces.IRMLDirectiveSignature):
- """A list of flowables."""
- occurence.containing(
- occurence.ZeroOrMore('spacer', ISpacer),
- occurence.ZeroOrMore('illustration', IIllustration),
- occurence.ZeroOrMore('pre', IPreformatted),
- occurence.ZeroOrMore('xpre', IXPreformatted),
- occurence.ZeroOrMore('codesnippet', ICodeSnippet),
- occurence.ZeroOrMore('plugInFlowable', IPluginFlowable),
- occurence.ZeroOrMore('barCodeFlowable', IBarCodeFlowable),
- occurence.ZeroOrMore('outlineAdd', IOutlineAdd),
- occurence.ZeroOrMore('title', ITitle),
- occurence.ZeroOrMore('h1', IHeading1),
- occurence.ZeroOrMore('h2', IHeading2),
- occurence.ZeroOrMore('h3', IHeading3),
- occurence.ZeroOrMore('h4', IHeading4),
- occurence.ZeroOrMore('h5', IHeading5),
- occurence.ZeroOrMore('h6', IHeading6),
- occurence.ZeroOrMore('para', IParagraph),
- occurence.ZeroOrMore('blockTable', IBlockTable),
- occurence.ZeroOrMore('nextFrame', INextFrame),
- occurence.ZeroOrMore('setNextFrame', ISetNextFrame),
- occurence.ZeroOrMore('nextPage', INextPage),
- occurence.ZeroOrMore('setNextTemplate', ISetNextTemplate),
- occurence.ZeroOrMore('condPageBreak', IConditionalPageBreak),
- occurence.ZeroOrMore('keepInFrame', IKeepInFrame),
- occurence.ZeroOrMore('keepTogether', IKeepTogether),
- occurence.ZeroOrMore('img', IImage),
- occurence.ZeroOrMore('imageAndFlowables', IImageAndFlowables),
- occurence.ZeroOrMore('pto', IPTO),
- occurence.ZeroOrMore('indent', IIndent),
- occurence.ZeroOrMore('fixedSize', IFixedSize),
- occurence.ZeroOrMore('bookmarkPage', IBookmarkPage),
- occurence.ZeroOrMore('bookmark', IBookmark),
- occurence.ZeroOrMore('link', ILink),
- occurence.ZeroOrMore('hr', IHorizontalRow),
- occurence.ZeroOrMore('showIndex', IShowIndex),
- occurence.ZeroOrMore('name', special.IName),
- occurence.ZeroOrMore('namedString', INamedString),
- occurence.ZeroOrMore('log', ILog),
- occurence.ZeroOrMore('debug', IDebug),
- occurence.ZeroOrMore('info', IInfo),
- occurence.ZeroOrMore('warning', IWarning),
- occurence.ZeroOrMore('error', IError),
- occurence.ZeroOrMore('critical', ICritical),
- )
-
-class Flow(directive.RMLDirective):
-
- factories = {
- # Generic Flowables
- 'spacer': Spacer,
- 'illustration': Illustration,
- 'pre': Preformatted,
- 'xpre': XPreformatted,
- 'codesnippet': CodeSnippet,
- 'plugInFlowable': PluginFlowable,
- 'barCodeFlowable': BarCodeFlowable,
- 'outlineAdd': OutlineAdd,
- # Paragraph-Like Flowables
- 'title': Title,
- 'h1': Heading1,
- 'h2': Heading2,
- 'h3': Heading3,
- 'h4': Heading4,
- 'h5': Heading5,
- 'h6': Heading6,
- 'para': Paragraph,
- # Table Flowable
- 'blockTable': BlockTable,
- # Page-level Flowables
- 'nextFrame': NextFrame,
- 'setNextFrame': SetNextFrame,
- 'nextPage': NextPage,
- 'setNextTemplate': SetNextTemplate,
- 'condPageBreak': ConditionalPageBreak,
- 'keepInFrame': KeepInFrame,
- 'keepTogether': KeepTogether,
- 'img': Image,
- 'imageAndFlowables': ImageAndFlowables,
- 'pto': PTO,
- 'indent': Indent,
- 'fixedSize': FixedSize,
- 'bookmarkPage': BookmarkPage,
- 'bookmark': Bookmark,
- 'link': Link,
- 'hr': HorizontalRow,
- 'showIndex': ShowIndex,
- # Special Elements
- 'name': special.Name,
- 'namedString': NamedString,
- # Logging
- 'log': Log,
- 'debug': Debug,
- 'info': Info,
- 'warning': Warning,
- 'error': Error,
- 'critical': Critical,
- }
-
- def __init__(self, *args, **kw):
- super(Flow, self).__init__(*args, **kw)
- self.flow = []
-
- def process(self):
- self.processSubDirectives()
- return self.flow
diff --git a/z3c/rml/form.py b/z3c/rml/form.py
deleted file mode 100644
index c6cce9f2..00000000
--- a/z3c/rml/form.py
+++ /dev/null
@@ -1,356 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Page Drawing Related Element Processing
-"""
-import types
-import reportlab.pdfbase.pdfform
-from z3c.rml import attr, directive, interfaces, occurence
-
-try:
- import reportlab.graphics.barcode
-except ImportError:
- # barcode package has not been installed
- import types
- import reportlab.graphics
- reportlab.graphics.barcode = types.ModuleType('barcode')
- reportlab.graphics.barcode.getCodeNames = lambda : ()
-
-
-class IBarCodeBase(interfaces.IRMLDirectiveSignature):
- """Create a bar code."""
-
- code = attr.Choice(
- title=u'Code',
- description=u'The name of the type of code to use.',
- choices=reportlab.graphics.barcode.getCodeNames(),
- required=True)
-
- value = attr.TextNode(
- title=u'Value',
- description=u'The value represented by the code.',
- required=True)
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the barcode.',
- required=False)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the barcode.',
- required=False)
-
- barStrokeColor = attr.Color(
- title=u'Bar Stroke Color',
- description=(u'The color of the line strokes in the barcode.'),
- required=False)
-
- barStrokeWidth = attr.Measurement(
- title=u'Bar Stroke Width',
- description=u'The width of the line strokes in the barcode.',
- required=False)
-
- barFillColor = attr.Color(
- title=u'Bar Fill Color',
- description=(u'The color of the filled shapes in the barcode.'),
- required=False)
-
- gap = attr.Measurement(
- title=u'Gap',
- description=u'The width of the inter-character gaps.',
- required=False)
-
- # Bar code dependent attributes
- # I2of5, Code128, Standard93, FIM, POSTNET, Ean13B
- barWidth = attr.Measurement(
- title=u'Bar Width',
- description=u'The width of the smallest bar within the barcode',
- required=False)
-
- # I2of5, Code128, Standard93, FIM, POSTNET
- barHeight = attr.Measurement(
- title=u'Bar Height',
- description=u'The height of the symbol.',
- required=False)
-
- # I2of5
- ratio = attr.Float(
- title=u'Ratio',
- description=(u'The ratio of wide elements to narrow elements. '
- u'Must be between 2.0 and 3.0 (or 2.2 and 3.0 if the '
- u'barWidth is greater than 20 mils (.02 inch)).'),
- min=2.0,
- max=3.0,
- required=False)
-
- # I2of5
- # Should be boolean, but some code want it as int; will still work
- checksum = attr.Integer(
- title=u'Ratio',
- description=(u'A flag that enables the computation and inclusion of '
- u'the check digit.'),
- required=False)
-
- # I2of5
- bearers = attr.Float(
- title=u'Bearers',
- description=(u'Height of bearer bars (horizontal bars along the top '
- u'and bottom of the barcode). Default is 3 '
- u'x-dimensions. Set to zero for no bearer bars.'
- u'(Bearer bars help detect misscans, so it is '
- u'suggested to leave them on).'),
- required=False)
-
- # I2of5, Code128, Standard93, FIM, Ean13
- quiet = attr.Boolean(
- title=u'Quiet Zone',
- description=(u'A flag to include quiet zones in the symbol.'),
- required=False)
-
- # I2of5, Code128, Standard93, FIM, Ean13
- lquiet = attr.Measurement(
- title=u'Left Quiet Zone',
- description=(u"Quiet zone size to the left of code, if quiet is "
- u"true. Default is the greater of .25 inch or .15 times "
- u"the symbol's length."),
- required=False)
-
- # I2of5, Code128, Standard93, FIM, Ean13
- rquiet = attr.Measurement(
- title=u'Right Quiet Zone',
- description=(u"Quiet zone size to the right of code, if quiet is "
- u"true. Default is the greater of .25 inch or .15 times "
- u"the symbol's length."),
- required=False)
-
- # I2of5, Code128, Standard93, FIM, POSTNET, Ean13
- fontName = attr.String(
- title=u'Font Name',
- description=(u'The font used to print the value.'),
- required=False)
-
- # I2of5, Code128, Standard93, FIM, POSTNET, Ean13
- fontSize = attr.Measurement(
- title=u'Font Size',
- description=(u'The size of the value text.'),
- required=False)
-
- # I2of5, Code128, Standard93, FIM, POSTNET, Ean13
- humanReadable = attr.Boolean(
- title=u'Human Readable',
- description=(u'A flag when set causes the value to be printed below '
- u'the bar code.'),
- required=False)
-
- # I2of5, Standard93
- stop = attr.Boolean(
- title=u'Show Start/Stop',
- description=(u'A flag to specify whether the start/stop symbols '
- u'are to be shown.'),
- required=False)
-
- # FIM, POSTNET
- spaceWidth = attr.Measurement(
- title=u'Space Width',
- description=u'The space of the inter-character gaps.',
- required=False)
-
- # POSTNET
- shortHeight = attr.Measurement(
- title=u'Short Height',
- description=u'The height of the short bar.',
- required=False)
-
- # Ean13
- textColor = attr.Color(
- title=u'Text Color',
- description=(u'The color of human readable text.'),
- required=False)
-
- # USPS4S
- routing = attr.String(
- title=u'Routing',
- description=u'The routing information string.',
- required=False)
-
- # QR
- barLevel = attr.Choice(
- title=u'Bar Level',
- description=u'The error correction level for QR code',
- choices=['L', 'M', 'Q', 'H'],
- required=False)
-
-
-class IBarCode(IBarCodeBase):
- """A barcode graphic."""
-
- x = attr.Measurement(
- title=u'X-Position',
- description=u'The x-position of the lower-left corner of the barcode.',
- default=0,
- required=False)
-
- y = attr.Measurement(
- title=u'Y-Position',
- description=u'The y-position of the lower-left corner of the barcode.',
- default=0,
- required=False)
-
- isoScale = attr.Boolean(
- title=u'Isometric Scaling',
- description=u'When set, the aspect ration of the barcode is enforced.',
- required=False)
-
-class BarCode(directive.RMLDirective):
- signature = IBarCode
-
- def process(self):
- kw = dict(self.getAttributeValues())
- name = kw.pop('code')
- kw['value'] = str(kw['value'])
- x = kw.pop('x', 0)
- y = kw.pop('y', 0)
- code = reportlab.graphics.barcode.createBarcodeDrawing(name, **kw)
- manager = attr.getManager(self, interfaces.ICanvasManager)
- code.drawOn(manager.canvas, x, y)
-
-
-class IField(interfaces.IRMLDirectiveSignature):
- """A field."""
-
- title = attr.Text(
- title=u'Title',
- description=u'The title of the field.',
- required=True)
-
- x = attr.Measurement(
- title=u'X-Position',
- description=u'The x-position of the lower-left corner of the field.',
- default=0,
- required=True)
-
- y = attr.Measurement(
- title=u'Y-Position',
- description=u'The y-position of the lower-left corner of the field.',
- default=0,
- required=True)
-
-
-class Field(directive.RMLDirective):
- signature = IField
- callable = None
- attrMapping = {}
-
- def process(self):
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- getattr(reportlab.pdfbase.pdfform, self.callable)(canvas, **kwargs)
-
-
-class ITextField(IField):
- """A text field within the PDF"""
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the text field.',
- required=True)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the text field.',
- required=True)
-
- value = attr.Text(
- title=u'Value',
- description=u'The default text value of the field.',
- required=False)
-
- maxLength = attr.Integer(
- title=u'Maximum Length',
- description=u'The maximum amount of characters allowed in the field.',
- required=False)
-
- multiline = attr.Boolean(
- title=u'Multiline',
- description=u'A flag when set allows multiple lines within the field.',
- required=False)
-
-class TextField(Field):
- signature = ITextField
- callable = 'textFieldAbsolute'
- attrMapping = {'maxLength': 'maxlen'}
-
-
-class IButtonField(IField):
- """A button field within the PDF"""
-
- value = attr.Choice(
- title=u'Value',
- description=u'The value of the button.',
- choices=('Yes', 'Off'),
- required=True)
-
-class ButtonField(Field):
- signature = IButtonField
- callable = 'buttonFieldAbsolute'
-
-
-class IOption(interfaces.IRMLDirectiveSignature):
- """An option in the select field."""
-
- value = attr.TextNode(
- title=u'Value',
- description=u'The value of the option.',
- required=True)
-
-class Option(directive.RMLDirective):
- signature = IOption
-
- def process(self):
- value = self.getAttributeValues(valuesOnly=True)[0]
- self.parent.options.append(value)
-
-
-class ISelectField(IField):
- """A selection field within the PDF"""
- occurence.containing(
- occurence.ZeroOrMore('option', IOption))
-
- width = attr.Measurement(
- title=u'Width',
- description=u'The width of the select field.',
- required=True)
-
- height = attr.Measurement(
- title=u'Height',
- description=u'The height of the select field.',
- required=True)
-
- value = attr.Text(
- title=u'Value',
- description=u'The default value of the field.',
- required=False)
-
-class SelectField(Field):
- signature = ISelectField
- callable = 'selectFieldAbsolute'
- factories = {'option': Option}
-
- def process(self):
- self.options = []
- self.processSubDirectives()
- kwargs = dict(self.getAttributeValues(attrMapping=self.attrMapping))
- kwargs['options'] = self.options
- canvas = attr.getManager(self, interfaces.ICanvasManager).canvas
- getattr(reportlab.pdfbase.pdfform, self.callable)(canvas, **kwargs)
diff --git a/z3c/rml/interfaces.py b/z3c/rml/interfaces.py
deleted file mode 100644
index c92ee9d7..00000000
--- a/z3c/rml/interfaces.py
+++ /dev/null
@@ -1,148 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""RML to PDF Converter Interfaces
-"""
-__docformat__ = "reStructuredText"
-import logging
-import reportlab.lib.enums
-import zope.interface
-import zope.schema
-
-from z3c.rml.occurence import ZeroOrMore, ZeroOrOne, OneOrMore
-
-JOIN_CHOICES = {'round': 1, 'mitered': 0, 'bevelled': 2}
-CAP_CHOICES = {'default': 0, 'butt': 0, 'round': 1, 'square': 2}
-ALIGN_CHOICES = {
- 'left': reportlab.lib.enums.TA_LEFT,
- 'right': reportlab.lib.enums.TA_RIGHT,
- 'center': reportlab.lib.enums.TA_CENTER,
- 'centre': reportlab.lib.enums.TA_CENTER,
- 'justify': reportlab.lib.enums.TA_JUSTIFY}
-ALIGN_TEXT_CHOICES = {
- 'left': 'LEFT', 'right': 'RIGHT', 'center': 'CENTER', 'centre': 'CENTER',
- 'decimal': 'DECIMAL'}
-VALIGN_TEXT_CHOICES = {
- 'top': 'TOP', 'middle': 'MIDDLE', 'bottom': 'BOTTOM'}
-SPLIT_CHOICES = ('splitfirst', 'splitlast')
-TEXT_TRANSFORM_CHOICES = ('uppercase', 'lowercase')
-LIST_FORMATS = ('I', 'i', '123', 'ABC', 'abc')
-ORDERED_LIST_TYPES = ('I', 'i', '1', 'A', 'a')
-UNORDERED_BULLET_VALUES = ('bullet', 'circle', 'square', 'disc', 'diamond',
- 'rarrowhead')
-LOG_LEVELS = {
- 'DEBUG': logging.DEBUG,
- 'INFO': logging.INFO,
- 'WARNING': logging.WARNING,
- 'ERROR': logging.ERROR,
- 'CRITICAL': logging.CRITICAL}
-
-class IRML2PDF(zope.interface.Interface):
- """This is the main public API of z3c.rml"""
-
- def parseString(xml):
- """Parse an XML string and convert it to PDF.
-
- The output is a ``StringIO`` object.
- """
-
- def go(xmlInputName, outputFileName=None, outDir=None, dtdDir=None):
- """Convert RML 2 PDF.
-
- The generated file will be located in the ``outDir`` under the name
- ``outputFileName``.
- """
-
-class IManager(zope.interface.Interface):
- """A manager of all document-global variables."""
- names = zope.interface.Attribute("Names dict")
- styles = zope.interface.Attribute("Styles dict")
- colors = zope.interface.Attribute("Colors dict")
-
-class IPostProcessorManager(zope.interface.Interface):
- """Manages all post processors"""
-
- postProcessors = zope.interface.Attribute(
- "List of tuples of the form: (name, processor)")
-
-class ICanvasManager(zope.interface.Interface):
- """A manager for the canvas."""
- canvas = zope.interface.Attribute("Canvas")
-
-class IRMLDirectiveSignature(zope.interface.Interface):
- """The attribute and sub-directives signature of the current
- RML directive."""
-
-
-class IRMLDirective(zope.interface.Interface):
- """A directive in RML extracted from an Element Tree element."""
-
- signature = zope.schema.Field(
- title=u'Signature',
- description=(u'The signature of the RML directive.'),
- required=True)
-
- parent = zope.schema.Field(
- title=u'Parent RML Element',
- description=u'The parent in the RML element hierarchy',
- required=True,)
-
- element = zope.schema.Field(
- title=u'Element',
- description=(u'The Element Tree element from which the data '
- u'is retrieved.'),
- required=True)
-
- def getAttributeValues(ignore=None, select=None, includeMissing=False):
- """Return a list of name-value-tuples based on the signature.
-
- If ``ignore`` is specified, all attributes are returned except the
- ones listed in the argument. The values of the sequence are the
- attribute names.
-
- If ``select`` is specified, only attributes listed in the argument are
- returned. The values of the sequence are the attribute names.
-
- If ``includeMissing`` is set to true, then even missing attributes are
- included in the value list.
- """
-
- def processSubDirectives(self):
- """Process all sub-directives."""
-
- def process(self):
- """Process the directive.
-
- The main task for this method is to interpret the available data and
- to make the corresponding calls in the Reportlab document.
-
- This call should also process all sub-directives and process them.
- """
-
-
-class IDeprecated(zope.interface.Interface):
- """Mark an attribute as being compatible."""
-
- deprecatedName = zope.schema.TextLine(
- title=u'Name',
- description=u'The name of the original attribute.',
- required=True)
-
- deprecatedReason = zope.schema.Text(
- title=u'Reason',
- description=u'The reason the attribute has been deprecated.',
- required=False)
-
-
-class IDeprecatedDirective(zope.interface.interfaces.IInterface):
- """A directive that is deprecated."""
diff --git a/z3c/rml/list.py b/z3c/rml/list.py
deleted file mode 100644
index d6de49da..00000000
--- a/z3c/rml/list.py
+++ /dev/null
@@ -1,181 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2012 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""``ul``, ``ol``, and ``li`` directives.
-"""
-__docformat__ = "reStructuredText"
-import copy
-import reportlab.lib.styles
-import reportlab.platypus
-import zope.schema
-from reportlab.platypus import flowables
-
-from z3c.rml import attr, directive, flowable, interfaces, occurence, stylesheet
-
-
-class IListItem(stylesheet.IMinimalListStyle, flowable.IFlow):
- """A list item in an ordered or unordered list."""
-
- style = attr.Style(
- title=u'Style',
- description=u'The list style that is applied to the list.',
- required=False)
-
-class ListItem(flowable.Flow):
- signature = IListItem
- klass = reportlab.platypus.ListItem
- attrMapping = {}
-
- styleAttributes = zope.schema.getFieldNames(stylesheet.IMinimalListStyle)
-
- def processStyle(self, style):
- attrs = self.getAttributeValues(select=self.styleAttributes)
- if attrs or not hasattr(style, 'value'):
- style = copy.deepcopy(style)
- # Sigh, this is needed since unordered list items expect the value.
- style.value = style.start
- for name, value in attrs:
- setattr(style, name, value)
- return style
-
- def process(self):
- self.processSubDirectives()
- args = dict(self.getAttributeValues(ignore=self.styleAttributes))
- if 'style' not in args:
- args['style'] = self.parent.baseStyle
- args['style'] = self.processStyle(args['style'])
- li = self.klass(self.flow, **args)
- self.parent.flow.append(li)
-
-
-class IOrderedListItem(IListItem):
- """An ordered list item."""
-
- value = attr.Integer(
- title=u'Bullet Value',
- description=u'The counter value.',
- required=False)
-
-class OrderedListItem(ListItem):
- signature = IOrderedListItem
-
-
-class IUnorderedListItem(IListItem):
- """An ordered list item."""
-
- value = attr.Choice(
- title=u'Bullet Value',
- description=u'The type of bullet character.',
- choices=interfaces.UNORDERED_BULLET_VALUES,
- required=False)
-
-class UnorderedListItem(ListItem):
- signature = IUnorderedListItem
-
- styleAttributes = ListItem.styleAttributes + ['value']
-
-
-class IListBase(stylesheet.IBaseListStyle):
-
- style = attr.Style(
- title=u'Style',
- description=u'The list style that is applied to the list.',
- required=False)
-
-class ListBase(directive.RMLDirective):
- klass = reportlab.platypus.ListFlowable
- factories = {'li': ListItem}
- attrMapping = {}
-
- styleAttributes = zope.schema.getFieldNames(stylesheet.IBaseListStyle)
-
- def __init__(self, *args, **kw):
- super(ListBase, self).__init__(*args, **kw)
- self.flow = []
-
- def processStyle(self, style):
- attrs = self.getAttributeValues(
- select=self.styleAttributes, attrMapping=self.attrMapping)
- if attrs:
- style = copy.deepcopy(style)
- for name, value in attrs:
- setattr(style, name, value)
- return style
-
- def process(self):
- args = dict(self.getAttributeValues(
- ignore=self.styleAttributes, attrMapping=self.attrMapping))
- if 'style' not in args:
- args['style'] = reportlab.lib.styles.ListStyle('List')
- args['style'] = self.baseStyle = self.processStyle(args['style'])
- self.processSubDirectives()
- li = self.klass(self.flow, **args)
- self.parent.flow.append(li)
-
-
-class IOrderedList(IListBase):
- """An ordered list."""
- occurence.containing(
- occurence.ZeroOrMore('li', IOrderedListItem),
- )
-
- bulletType = attr.Choice(
- title=u'Bullet Type',
- description=u'The type of bullet formatting.',
- choices=interfaces.ORDERED_LIST_TYPES,
- doLower=False,
- required=False)
-
-class OrderedList(ListBase):
- signature = IOrderedList
- factories = {'li': OrderedListItem}
-
- styleAttributes = ListBase.styleAttributes + ['bulletType']
-
-
-class IUnorderedList(IListBase):
- """And unordered list."""
- occurence.containing(
- occurence.ZeroOrMore('li', IUnorderedListItem),
- )
-
- value = attr.Choice(
- title=u'Bullet Value',
- description=u'The type of bullet character.',
- choices=interfaces.UNORDERED_BULLET_VALUES,
- default='disc',
- required=False)
-
-class UnorderedList(ListBase):
- signature = IUnorderedList
- attrMapping = {'value': 'start'}
- factories = {'li': UnorderedListItem}
-
- def getAttributeValues(self, *args, **kw):
- res = super(UnorderedList, self).getAttributeValues(*args, **kw)
- res.append(('bulletType', 'bullet'))
- return res
-
-flowable.Flow.factories['ol'] = OrderedList
-flowable.IFlow.setTaggedValue(
- 'directives',
- flowable.IFlow.getTaggedValue('directives') +
- (occurence.ZeroOrMore('ol', IOrderedList),)
- )
-
-flowable.Flow.factories['ul'] = UnorderedList
-flowable.IFlow.setTaggedValue(
- 'directives',
- flowable.IFlow.getTaggedValue('directives') +
- (occurence.ZeroOrMore('ul', IUnorderedList),)
- )
diff --git a/z3c/rml/occurence.py b/z3c/rml/occurence.py
deleted file mode 100644
index b4f3fe29..00000000
--- a/z3c/rml/occurence.py
+++ /dev/null
@@ -1,113 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Condition Implementation
-"""
-import reportlab
-import sys
-import zope.interface
-import zope.schema
-from zope.schema import fieldproperty
-
-class ICondition(zope.interface.Interface):
- """Condition that is checked before a directive is available."""
-
- __doc__ = zope.schema.TextLine(
- title=u'Description',
- description=u'The description of the condition.',
- required=True)
-
- def __call__(directive):
- """Check whether the condition is fulfilled for the given directive."""
-
-
-class IOccurence(zope.interface.Interface):
- """Description of the occurence of a sub-directive."""
-
- __doc__ = zope.schema.TextLine(
- title=u'Description',
- description=u'The description of the occurence.',
- required=True)
-
- tag = zope.schema.BytesLine(
- title=u'Tag',
- description=u'The tag of the sub-directive within the directive',
- required=True)
-
- signature = zope.schema.Field(
- title=u'Signature',
- description=u'The signature of the sub-directive.',
- required=True)
-
- condition = zope.schema.Field(
- title=u'Condition',
- description=u'The condition that the directive is available.',
- required=False)
-
-
-@zope.interface.implementer(ICondition)
-def laterThanReportlab21(directive):
- """The directive is only available in Reportlab 2.1 and higher."""
- return [int(num) for num in reportlab.Version.split('.')] >= (2, 0)
-
-
-def containing(*occurences):
- frame = sys._getframe(1)
- f_locals = frame.f_locals
- f_globals = frame.f_globals
-
- if not (f_locals is not f_globals
- and f_locals.get('__module__')
- and f_locals.get('__module__') == f_globals.get('__name__')
- ):
- raise TypeError("contains not called from signature interface")
-
- f_locals['__interface_tagged_values__'] = {'directives': occurences}
-
-
-class Occurence(object):
- zope.interface.implements(IOccurence)
-
- tag = fieldproperty.FieldProperty(IOccurence['tag'])
- signature = fieldproperty.FieldProperty(IOccurence['signature'])
- condition = fieldproperty.FieldProperty(IOccurence['condition'])
-
- def __init__(self, tag, signature, condition=None):
- self.tag = tag
- self.signature = signature
- self.condition = condition
-
-
-class ZeroOrMore(Occurence):
- """Zero or More
-
- This sub-directive can occur zero or more times.
- """
-
-class ZeroOrOne(Occurence):
- """Zero or one
-
- This sub-directive can occur zero or one time.
- """
-
-class OneOrMore(Occurence):
- """One or More
-
- This sub-directive can occur one or more times.
- """
-
-class One(Occurence):
- """One
-
- This sub-directive must occur exactly one time.
- """
diff --git a/z3c/rml/page.py b/z3c/rml/page.py
deleted file mode 100644
index 8ad54bcd..00000000
--- a/z3c/rml/page.py
+++ /dev/null
@@ -1,115 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Page Drawing Related Element Processing
-"""
-import cStringIO
-from z3c.rml import attr, directive, interfaces
-
-try:
- import PyPDF2
- from PyPDF2.generic import NameObject
-except ImportError:
- # We don't want to require pyPdf, if you do not want to use the features
- # in this module.
- PyPDF2 = None
-
-
-class MergePostProcessor(object):
-
- def __init__(self):
- self.operations = {}
-
- def process(self, inputFile1):
- input1 = PyPDF2.PdfFileReader(inputFile1)
- output = PyPDF2.PdfFileWriter()
- # TODO: Do not access protected classes
- output._info.getObject().update(input1.documentInfo)
- if output._root:
- # Backwards-compatible with PyPDF2 version 1.21
- output._root.getObject()[NameObject("/Outlines")] = (
- output._addObject(input1.trailer["/Root"]["/Outlines"]))
- else:
- # Compatible with PyPDF2 version 1.22+
- output._root_object[NameObject("/Outlines")] = (
- output._addObject(input1.trailer["/Root"]["/Outlines"]))
- for (num, page) in enumerate(input1.pages):
- if num in self.operations:
- for mergeFile, mergeNumber in self.operations[num]:
- merger = PyPDF2.PdfFileReader(mergeFile)
- mergerPage = merger.getPage(mergeNumber)
- mergerPage.mergePage(page)
- page = mergerPage
- output.addPage(page)
-
- outputFile = cStringIO.StringIO()
- output.write(outputFile)
- return outputFile
-
-
-class IMergePage(interfaces.IRMLDirectiveSignature):
- """Merges an existing PDF Page into the one to be generated."""
-
- filename = attr.File(
- title=u'File',
- description=(u'Reference to the PDF file to extract the page from.'),
- required=True)
-
- page = attr.Integer(
- title=u'Page Number',
- description=u'The page number of the PDF file that is used to merge..',
- required=True)
-
-
-class MergePage(directive.RMLDirective):
- signature = IMergePage
-
- def getProcessor(self):
- manager = attr.getManager(self, interfaces.IPostProcessorManager)
- procs = dict(manager.postProcessors)
- if 'MERGE' not in procs:
- proc = MergePostProcessor()
- manager.postProcessors.append(('MERGE', proc))
- return proc
- return procs['MERGE']
-
- def process(self):
- if PyPDF2 is None:
- raise Exception(
- 'pyPdf is not installed, so this feature is not available.')
- inputFile, inPage = self.getAttributeValues(valuesOnly=True)
- manager = attr.getManager(self, interfaces.ICanvasManager)
- outPage = manager.canvas.getPageNumber()-1
-
- proc = self.getProcessor()
- pageOperations = proc.operations.setdefault(outPage, [])
- pageOperations.append((inputFile, inPage))
-
-
-class MergePageInPageTemplate(MergePage):
-
- def process(self):
- if PyPDF2 is None:
- raise Exception(
- 'pyPdf is not installed, so this feature is not available.')
- inputFile, inPage = self.getAttributeValues(valuesOnly=True)
-
- onPage = self.parent.pt.onPage
- def drawOnCanvas(canvas, doc):
- onPage(canvas, doc)
- outPage = canvas.getPageNumber()-1
- proc = self.getProcessor()
- pageOperations = proc.operations.setdefault(outPage, [])
- pageOperations.append((inputFile, inPage))
-
- self.parent.pt.onPage = drawOnCanvas
diff --git a/z3c/rml/pagetemplate.py b/z3c/rml/pagetemplate.py
deleted file mode 100644
index 65440c77..00000000
--- a/z3c/rml/pagetemplate.py
+++ /dev/null
@@ -1,45 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Page Template Support
-"""
-import zope
-from z3c.rml import rml2pdf
-
-try:
- import zope.pagetemplate.pagetemplatefile
-except ImportError, err:
- raise
- # zope.pagetemplate package has not been installed
- import types
- zope.pagetemplate = types.ModuleType('pagetemplate')
- zope.pagetemplate.pagetemplatefile = types.ModuleType('pagetemplatefile')
- zope.pagetemplate.pagetemplatefile.PageTemplateFile = object
-
-
-class RMLPageTemplateFile(zope.pagetemplate.pagetemplatefile.PageTemplateFile):
-
- def pt_getContext(self, args=(), options=None, **ignore):
- rval = {'template': self,
- 'args': args,
- 'nothing': None,
- 'context': options
- }
- rval.update(self.pt_getEngine().getBaseNames())
- return rval
-
- def __call__(self, *args, **kwargs):
- rml = super(RMLPageTemplateFile, self).__call__(*args, **kwargs)
-
- return rml2pdf.parseString(
- rml, filename=self.pt_source_file()).getvalue()
diff --git a/z3c/rml/pagetemplate.txt b/z3c/rml/pagetemplate.txt
deleted file mode 100644
index 9f4aca43..00000000
--- a/z3c/rml/pagetemplate.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-==================
-RML Page Templates
-==================
-
-This package also provides optional support a helper class to use page
-templates with RML without using the entire Zope framework. This document will
-demonstrate how to use page templates and RML together.
-
-In this example, we will simply iterate through a list of names and display
-them in the PDF.
-
-The first step is to create a page template:
-
- >>> import tempfile
- >>> ptFileName = tempfile.mktemp('.pt')
- >>> open(ptFileName, 'w').write('''\
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ...
- ... ''')
-
-The ``context`` namespace will be created during rendering. I get back to this
-later. In th enext step we instantiate the page template:
-
- >>> from z3c.rml import pagetemplate
- >>> rmlPageTemplate = pagetemplate.RMLPageTemplateFile(ptFileName)
-
-All we have to do now is to render the template. The context of the template
-is effectively the keyword arguments dictionary:
-
- >>> rmlPageTemplate(names=(u'Roy', u'Daniel', u'Julian', u'Stephan'))
- '%PDF-1.4...'
-
-You can uncomment the following line to write out the PDF in the current
-working directory:
-
- #>>> open('pagetemplate-test.pdf', 'w').write(
- #... rmlPageTemplate(names=(u'Roy', u'Daniel', u'Julian', u'Stephan')))
diff --git a/z3c/rml/paraparser.py b/z3c/rml/paraparser.py
deleted file mode 100644
index 2c90c168..00000000
--- a/z3c/rml/paraparser.py
+++ /dev/null
@@ -1,181 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007-2008 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Paragraph-internal XML parser extensions.
-"""
-import copy
-import inspect
-
-import reportlab.lib.fonts
-import reportlab.platypus.paraparser
-
-
-class PageNumberFragment(reportlab.platypus.paraparser.ParaFrag):
- """A fragment whose `text` is computed at access time."""
-
- def __init__(self, **attributes):
- reportlab.platypus.paraparser.ParaFrag.__init__(self, **attributes)
- self.counting_from = attributes.get('countingFrom', 1)
-
- @property
- def text(self):
- # Guess 1: We're in a paragraph in a story.
- frame = inspect.currentframe(4)
- canvas = frame.f_locals.get('canvas', None)
-
- if canvas is None:
- # Guess 2: We're in a template
- canvas = frame.f_locals.get('canv', None)
-
- if canvas is None:
- # Guess 3: We're in evalString or namedString
- canvas = getattr(frame.f_locals.get('self', None), 'canv', None)
-
- if canvas is None:
- raise Exception("Can't use in this location.")
-
- return str(canvas.getPageNumber() + int(self.counting_from) - 1)
-
-
-class GetNameFragment(reportlab.platypus.paraparser.ParaFrag):
- """A fragment whose `text` is computed at access time."""
-
- def __init__(self, **attributes):
- reportlab.platypus.paraparser.ParaFrag.__init__(self, **attributes)
- self.id = attributes['id']
- self.default = attributes.get('default')
-
- @property
- def text(self):
- # Guess 1: We're in a paragraph in a story.
- frame = inspect.currentframe(4)
- canvas = frame.f_locals.get('canvas', None)
-
- if canvas is None:
- # Guess 2: We're in a template
- canvas = frame.f_locals.get('canv', None)
-
- if canvas is None:
- # Guess 3: We're in evalString or namedString
- canvas = getattr(frame.f_locals.get('self', None), 'canv', None)
-
- if canvas is None:
- raise Exception("Can't use in this location.")
-
- return canvas.manager.get_name(self.id, self.default)
-
-
-class EvalStringFragment(reportlab.platypus.paraparser.ParaFrag):
- """A fragment whose `text` is evaluated at access time."""
-
- def __init__(self, **attributes):
- reportlab.platypus.paraparser.ParaFrag.__init__(self, **attributes)
- self.frags = []
-
- @property
- def text(self):
- text = u''
- for frag in self.frags:
- if isinstance(frag, basestring):
- text += frag
- else:
- text += frag.text
- from z3c.rml.special import do_eval
- return do_eval(text)
-
-
-class NameFragment(reportlab.platypus.paraparser.ParaFrag):
- """A fragment whose attribute `value` is set to a variable."""
-
- def __init__(self, **attributes):
- reportlab.platypus.paraparser.ParaFrag.__init__(self, **attributes)
-
- @property
- def text(self):
- # Guess 1: We're in a paragraph in a story.
- frame = inspect.currentframe(4)
- canvas = frame.f_locals.get('canvas', None)
-
- if canvas is None:
- # Guess 2: We're in a template
- canvas = frame.f_locals.get('canv', None)
-
- if canvas is None:
- # Guess 3: We're in evalString or namedString
- canvas = getattr(frame.f_locals.get('self', None), 'canv', None)
-
- if canvas is None:
- raise Exception("Can't use in this location.")
-
- canvas.manager.names[self.id] = self.value
- return u''
-
-
-class Z3CParagraphParser(reportlab.platypus.paraparser.ParaParser):
- """Extensions to paragraph-internal XML parsing."""
-
- def __init__(self, *args, **kwargs):
- reportlab.platypus.paraparser.ParaParser.__init__(self, *args, **kwargs)
- self.in_eval = False
-
- def startDynamic(self, attributes, klass):
- frag = klass(**attributes)
- frag.__dict__.update(self._stack[-1].__dict__)
- frag.fontName = reportlab.lib.fonts.tt2ps(
- frag.fontName, frag.bold, frag.italic)
- if self.in_eval:
- self._stack[-1].frags.append(frag)
- else:
- self.fragList.append(frag)
- self._stack.append(frag)
-
- def endDynamic(self):
- if not self.in_eval:
- self._pop()
-
- def start_pagenumber(self, attributes):
- self.startDynamic(attributes, PageNumberFragment)
-
- def end_pagenumber(self):
- self.endDynamic()
-
- def start_getname(self, attributes):
- self.startDynamic(attributes, GetNameFragment)
-
- def end_getname(self):
- self.endDynamic()
-
- def start_name(self, attributes):
- self.startDynamic(attributes, NameFragment)
-
- def end_name(self):
- self.endDynamic()
-
- def start_evalstring(self, attributes):
- self.startDynamic(attributes, EvalStringFragment)
- self.in_eval = True
-
- def end_evalstring(self):
- self.in_eval = False
- self.endDynamic()
-
- def handle_data(self, data):
- if not self.in_eval:
- reportlab.platypus.paraparser.ParaParser.handle_data(self, data)
- else:
- frag = self._stack[-1].frags.append(data)
-
-
-# Monkey-patch reportlabs global parser instance. Wah.
-import reportlab.platypus.paragraph
-reportlab.platypus.paragraph.ParaParser = Z3CParagraphParser
diff --git a/z3c/rml/pdfinclude.py b/z3c/rml/pdfinclude.py
deleted file mode 100644
index ddb529c8..00000000
--- a/z3c/rml/pdfinclude.py
+++ /dev/null
@@ -1,149 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2012 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""``pdfInclude`` Directive.
-"""
-__docformat__ = "reStructuredText"
-import cStringIO
-try:
- import PyPDF2
- from PyPDF2.generic import NameObject
-except ImportError:
- PyPDF2 = None
-from reportlab.platypus import flowables
-
-from z3c.rml import attr, flowable, interfaces, occurence, page
-
-class ConcatenationPostProcessor(object):
-
- def __init__(self):
- self.operations = []
-
- def process(self, inputFile1):
- input1 = PyPDF2.PdfFileReader(inputFile1)
- merger = PyPDF2.PdfFileMerger()
- merger.output._info.getObject().update(input1.documentInfo)
-
- prev_insert = 0
- for start_page, inputFile2, pages, num_pages in self.operations:
- if prev_insert < start_page:
- merger.append(inputFile1, pages=(prev_insert, start_page))
- if not pages:
- merger.append(inputFile2)
- else:
- # Note, users start counting at 1. ;-)
- for page in pages:
- merger.append(inputFile2, pages=(page-1, page))
- prev_insert = start_page + num_pages
-
- input1 = PyPDF2.PdfFileReader(inputFile1)
- num_pages = input1.getNumPages()
- if prev_insert < num_pages:
- merger.append(
- inputFile1, pages=(prev_insert, num_pages))
-
- outputFile = cStringIO.StringIO()
- merger.write(outputFile)
- return outputFile
-
-
-class PDFPageFlowable(flowables.Flowable):
-
- def __init__(self, width, height):
- flowables.Flowable.__init__(self)
- self.width = width
- self.height = height
-
- def draw(self):
- pass
-
- def split(self, availWidth, availheight):
- return [self]
-
-
-class IncludePdfPagesFlowable(flowables.Flowable):
-
- def __init__(self, pdf_file, pages, concatprocessor):
- flowables.Flowable.__init__(self)
- self.pdf_file = pdf_file
- self.proc = concatprocessor
- self.pages = pages
-
- self.width = 10<<32
- self.height = 10<<32
-
- def draw():
- return NotImplementedError('PDFPages shall be drawn not me')
-
- def split(self, availWidth, availheight):
- pages = self.pages
- if not pages:
- pdf = PyPDF2.PdfFileReader(self.pdf_file)
- num_pages = pdf.getNumPages()
- pages = range(num_pages)
- else:
- num_pages = len(pages)
-
- start_page = self.canv.getPageNumber()
- self.proc.operations.append(
- (start_page, self.pdf_file, self.pages, num_pages))
-
- result = []
- for i in pages:
- result.append(flowables.PageBreak())
- result.append(PDFPageFlowable(availWidth, availheight))
- return result
-
-
-class IIncludePdfPages(interfaces.IRMLDirectiveSignature):
- """Inserts a set of pages from a given PDF."""
-
- filename = attr.File(
- title=u'Path to file',
- description=u'The pdf file to include.',
- required=True)
-
- pages = attr.IntegerSequence(
- title=u'Pages',
- description=u'A list of pages to insert.',
- required=False)
-
-
-class IncludePdfPages(flowable.Flowable):
- signature = IIncludePdfPages
-
- def getProcessor(self):
- manager = attr.getManager(self, interfaces.IPostProcessorManager)
- procs = dict(manager.postProcessors)
- if 'CONCAT' not in procs:
- proc = ConcatenationPostProcessor()
- manager.postProcessors.append(('CONCAT', proc))
- return proc
- return procs['CONCAT']
-
- def process(self):
- if PyPDF2 is None:
- raise Exception(
- 'PyPDF2 is not installed, so this feature is not available.')
- args = dict(self.getAttributeValues())
- proc = self.getProcessor()
- self.parent.flow.append(
- IncludePdfPagesFlowable(args['filename'], args.get('pages'), proc))
-
-
-flowable.Flow.factories['includePdfPages'] = IncludePdfPages
-flowable.IFlow.setTaggedValue(
- 'directives',
- flowable.IFlow.getTaggedValue('directives') +
- (occurence.ZeroOrMore('includePdfPages', IIncludePdfPages),)
- )
diff --git a/z3c/rml/platypus.py b/z3c/rml/platypus.py
deleted file mode 100644
index 288ce604..00000000
--- a/z3c/rml/platypus.py
+++ /dev/null
@@ -1,135 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Style Related Element Processing
-"""
-import reportlab.platypus.flowables
-import reportlab.rl_config
-from reportlab.rl_config import overlapAttachedSpace
-import zope.interface
-
-from z3c.rml import interfaces
-
-# Fix problem with reportlab 2.0
-class KeepInFrame(reportlab.platypus.flowables.KeepInFrame):
-
- def __init__(self, maxWidth, maxHeight, content=[], mergeSpace=1,
- mode='shrink', name=''):
- self.name = name
- self.maxWidth = maxWidth
- self.maxHeight = maxHeight
- self.mode = mode
- assert mode in ('error','overflow','shrink','truncate'), \
- '%s invalid mode value %s' % (self.identity(),mode)
- # This is an unnecessary check, since wrap() handles None just fine!
- #assert maxHeight>=0, \
- # '%s invalid maxHeight value %s' % (self.identity(),maxHeight)
- if mergeSpace is None: mergeSpace = overlapAttachedSpace
- self.mergespace = mergeSpace
- self._content = content
-
-
-class BaseFlowable(reportlab.platypus.flowables.Flowable):
- def __init__(self, *args, **kw):
- reportlab.platypus.flowables.Flowable.__init__(self)
- self.args = args
- self.kw = kw
-
- def wrap(self, *args):
- return (0, 0)
-
- def draw(self):
- pass
-
-class Illustration(reportlab.platypus.flowables.Flowable):
- def __init__(self, processor, width, height):
- self.processor = processor
- self.width = width
- self.height = height
-
- def wrap(self, *args):
- return (self.width, self.height)
-
- def draw(self):
- # Import here to avoid recursive imports
- from z3c.rml import canvas
- self.canv.saveState()
- drawing = canvas.Drawing(
- self.processor.element, self.processor)
- zope.interface.alsoProvides(drawing, interfaces.ICanvasManager)
- drawing.canvas = self.canv
- drawing.process()
- self.canv.restoreState()
-
-class BookmarkPage(BaseFlowable):
- def draw(self):
- self.canv.bookmarkPage(*self.args, **self.kw)
-
-
-class Bookmark(BaseFlowable):
- def draw(self):
- self.canv.bookmarkHorizontal(*self.args, **self.kw)
-
-
-class OutlineAdd(BaseFlowable):
- def draw(self):
- if self.kw.get('key', None) is None:
- self.kw['key'] = str(hash(self))
- self.canv.bookmarkPage(self.kw['key'])
- self.canv.addOutlineEntry(**self.kw)
-
-
-class Link(reportlab.platypus.flowables._Container,
- reportlab.platypus.flowables.Flowable):
-
- def __init__(self, content, **args):
- self._content = content
- self.args = args
-
- def wrap(self, availWidth, availHeight):
- self.width, self.height = reportlab.platypus.flowables._listWrapOn(
- self._content, availWidth, self.canv)
- return self.width, self.height
-
- def drawOn(self, canv, x, y, _sW=0, scale=1.0, content=None, aW=None):
- '''we simulate being added to a frame'''
- pS = 0
- if aW is None: aW = self.width
- aW = scale*(aW+_sW)
- if content is None:
- content = self._content
- y += self.height*scale
-
- startX = x
- startY = y
- totalWidth = 0
- totalHeight = 0
-
- for c in content:
- w, h = c.wrapOn(canv,aW,0xfffffff)
- if w < reportlab.rl_config._FUZZ or h < reportlab.rl_config._FUZZ:
- continue
- if c is not content[0]: h += max(c.getSpaceBefore()-pS,0)
- y -= h
- c.drawOn(canv,x,y,_sW=aW-w)
- if c is not content[-1]:
- pS = c.getSpaceAfter()
- y -= pS
- totalWidth += w
- totalHeight += h
- rectangle = [startX, startY-totalHeight,
- startX+totalWidth, startY]
- if 'url' in self.args:
- canv.linkURL(rect=rectangle, **self.args)
- else:
- canv.linkAbsolute('', Rect=rectangle, **self.args)
diff --git a/z3c/rml/reference.pt b/z3c/rml/reference.pt
deleted file mode 100644
index 1d5879e2..00000000
--- a/z3c/rml/reference.pt
+++ /dev/null
@@ -1,294 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- z3c.RML Reference
-
-
-
- Version 2.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Introduction
-
-
- RML is a XML dialect for generating PDF files. Like HTML produces a page
- within the browser, RML produces a PDF file. The RML processor uses the
- ReportLab library to convert the RML text into a full PDF template.
-
-
- The original version of RML was developed by ReportLab, Inc. as a
- commercial extension to the free ReportLab library. This original
- version of RML is still available and supported by ReportLab, Inc. This
- version of RML, z3c.RML, is a free implementation of the XML dialect
- based on the available documentation. While it tries to keep some level
- of compatibility with the original version of RML, it is intended to
- provde a as clean and feature-rich API as possible.
-
-
- The contents of this document is auto-generated from the code itself and
- should thus be very accurate and complete.
-
-
-
-
- Attribute Types
-
- Attribute Types
-
- This section list the types of attributes used for the attributes within
- the RML elements.
-
-
-
-
- Attribute Name
-
- Attribute Name
-
- Attribute purpose and data description.
-
-
-
-
-
- Directives
-
- Directives
-
-
- Element Name
-
-
- Element Name
-
-
-
- Deprecated:
- Reason
-
-
- What is this element doing?
-
-
-
-
- Attributes
-
-
-
- para
-
- (required)
-
- -
- Type
-
-
- Deprecated:
- Reason
-
-
- Title:
- Description
-
-
-
-
-
-
- Content
-
-
- Type
-
- (required)
-
-
-
- Title:
- Description
-
-
-
-
-
- Sub-Directives
-
-
-
-
- para
-
-
- (ZeroOrMore)
-
-
- (Deprecated)
-
-
-
-
-
-
-
- Examples
-
-
-
- Example Code
-
-
-
- |
-
- (Extracted from file
-
- File,
-
- line )
-
- |
-
-
-
- [PDF]
-
-
- |
-
-
-
-
-
-
-
-
-
-
diff --git a/z3c/rml/reference.py b/z3c/rml/reference.py
deleted file mode 100644
index e5aeda69..00000000
--- a/z3c/rml/reference.py
+++ /dev/null
@@ -1,242 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""RML Reference Generator
-"""
-import copy
-import re
-import os
-import pygments.token
-import zope.schema
-import zope.schema.interfaces
-from lxml import etree
-from xml.sax import saxutils
-from pygments.lexers import XmlLexer
-from z3c.rml import attr, document, interfaces, pagetemplate
-
-
-INPUT_URL = ('https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/'
- 'rml/tests/input/%s')
-EXPECTED_URL = ('https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/'
- 'rml/tests/expected/%s?raw=true')
-
-EXAMPLES_DIRECTORY = os.path.join(os.path.dirname(__file__), 'tests', 'input')
-IGNORE_ATTRIBUTES = ('RMLAttribute', 'BaseChoice')
-CONTENT_FIELD_TYPES = (
- attr.TextNode, attr.TextNodeSequence, attr.TextNodeGrid,
- attr.RawXMLContent, attr.XMLContent)
-STYLES_FORMATTING = {
- pygments.token.Name.Tag : ('', ''),
- pygments.token.Literal.String : ('', ''),
- }
-EXAMPLE_NS = 'http://namespaces.zope.org/rml/doc'
-EXAMPLE_ATTR_NAME = '{%s}example' %EXAMPLE_NS
-
-
-def dedent(rml):
- spaces = re.findall('\n( *)<', rml)
- if not spaces:
- return rml
- least = min([len(s) for s in spaces if s != ''])
- return rml.replace('\n'+' '*least, '\n')
-
-
-def enforceColumns(rml, columns=80):
- result = []
- for line in rml.split('\n'):
- if len(line) <= columns:
- result.append(line)
- continue
- # Determine the indentation for all other lines
- lineStart = re.findall('^( *<[a-zA-Z0-9]+ )', line)
- lineIndent = 0
- if lineStart:
- lineIndent = len(lineStart[0])
- # Create lines having at most the specified number of columns
- while len(line) > columns:
- end = line[:columns].rfind(' ')
- result.append(line[:end])
- line = ' '*lineIndent + line[end+1:]
- result.append(line)
-
- return '\n'.join(result)
-
-def highlightRML(rml):
- lexer = XmlLexer()
- styledRml = ''
- for ttype, token in lexer.get_tokens(rml):
- start, end = STYLES_FORMATTING.get(ttype, ('', ''))
- styledRml += start + saxutils.escape(token) + end
- return styledRml
-
-
-def removeDocAttributes(elem):
- for name in elem.attrib.keys():
- if name.startswith('{'+EXAMPLE_NS+'}'):
- del elem.attrib[name]
- for child in elem.getchildren():
- removeDocAttributes(child)
-
-
-def getAttributeTypes():
- types = []
- candidates = sorted(attr.__dict__.items(), key=lambda e: e[0])
- for name, candidate in candidates:
- if not (isinstance(candidate, type) and
- zope.schema.interfaces.IField.implementedBy(candidate) and
- name not in IGNORE_ATTRIBUTES):
- continue
- types.append({
- 'name': name,
- 'description': candidate.__doc__
- })
- return types
-
-
-def formatField(field):
- return field.__class__.__name__
-
-def formatChoice(field):
- choices = ', '.join([repr(choice) for choice in field.choices.keys()])
- return '%s of (%s)' %(field.__class__.__name__, choices)
-
-def formatSequence(field):
- vtFormatter = typeFormatters.get(field.value_type.__class__, formatField)
- return '%s of %s' %(field.__class__.__name__, vtFormatter(field.value_type))
-
-def formatGrid(field):
- vtFormatter = typeFormatters.get(field.value_type.__class__, formatField)
- return '%s with %i cols of %s' %(
- field.__class__.__name__, field.columns, vtFormatter(field.value_type))
-
-def formatCombination(field):
- vts = [typeFormatters.get(vt.__class__, formatField)(vt)
- for vt in field.value_types]
- return '%s of %s' %(field.__class__.__name__, ', '.join(vts))
-
-typeFormatters = {
- attr.Choice: formatChoice,
- attr.Sequence: formatSequence,
- attr.Combination: formatCombination,
- attr.TextNodeSequence: formatSequence,
- attr.TextNodeGrid: formatGrid}
-
-def processSignature(name, signature, examples, directives=None):
- if directives is None:
- directives = {}
- # Process this directive
- if signature not in directives:
- info = {'name': name, 'description': signature.getDoc(),
- 'id': str(hash(signature)), 'deprecated': False}
- # If directive is deprecated, then add some info
- if interfaces.IDeprecatedDirective.providedBy(signature):
- info['deprecated'] = True
- info['reason'] = signature.getTaggedValue('deprecatedReason')
- attrs = []
- content = None
- for fname, field in zope.schema.getFieldsInOrder(signature):
- # Handle the case, where the field describes the content
- typeFormatter = typeFormatters.get(field.__class__, formatField)
- fieldInfo = {
- 'name': fname,
- 'type': typeFormatter(field),
- 'title': field.title,
- 'description': field.description,
- 'required': field.required,
- 'deprecated': False,
- }
- if field.__class__ in CONTENT_FIELD_TYPES:
- content = fieldInfo
- else:
- attrs.append(fieldInfo)
-
- # Add a separate entry for the deprecated field
- if interfaces.IDeprecated.providedBy(field):
- deprFieldInfo = fieldInfo.copy()
- deprFieldInfo['deprecated'] = True
- deprFieldInfo['name'] = field.deprecatedName
- deprFieldInfo['reason'] = field.deprecatedReason
- attrs.append(deprFieldInfo)
-
- info['attributes'] = attrs
- info['content'] = content
- # Examples can be either gotten by interface path or tag name
- ifacePath = signature.__module__ + '.' + signature.__name__
- if ifacePath in examples:
- info['examples'] = examples[ifacePath]
- else:
- info['examples'] = examples.get(name, None)
-
- subs = []
- for occurence in signature.queryTaggedValue('directives', ()):
- subs.append({
- 'name': occurence.tag,
- 'occurence': occurence.__class__.__name__,
- 'deprecated': interfaces.IDeprecatedDirective.providedBy(
- occurence.signature),
- 'id': str(hash(occurence.signature))
- })
- info['sub-directives'] = subs
- directives[signature] = info
- # Process Children
- for occurence in signature.queryTaggedValue('directives', ()):
- processSignature(occurence.tag, occurence.signature,
- examples, directives)
-
-
-def extractExamples(directory):
- examples = {}
- for filename in os.listdir(directory):
- if not filename.endswith('.rml'):
- continue
- rmlFile = open(os.path.join(directory, filename), 'r')
- root = etree.parse(rmlFile).getroot()
- elements = root.xpath('//@doc:example/parent::*',
- namespaces={'doc': EXAMPLE_NS})
- # Phase 1: Collect all elements
- for elem in elements:
- demoTag = elem.get(EXAMPLE_ATTR_NAME) or elem.tag
- elemExamples = examples.setdefault(demoTag, [])
- elemExamples.append({
- 'filename': filename,
- 'line': elem.sourceline,
- 'element': elem,
- 'rmlurl': INPUT_URL %filename,
- 'pdfurl': EXPECTED_URL %(filename[:-4]+'.pdf')
- })
- # Phase 2: Render all elements
- removeDocAttributes(root)
- for dirExamples in examples.values():
- for example in dirExamples:
- xml = etree.tounicode(example['element']).strip()
- xml = re.sub(
- ' ?xmlns:doc="http://namespaces.zope.org/rml/doc"', '', xml)
- xml = dedent(xml)
- xml = enforceColumns(xml, 80)
- xml = highlightRML(xml)
- example['code'] = xml
-
- return examples
-
-
-def main(outPath=None):
- examples = extractExamples(EXAMPLES_DIRECTORY)
-
- template = pagetemplate.RMLPageTemplateFile('reference.pt')
-
- directives = {}
- processSignature('document', document.IDocument, examples, directives)
- directives = sorted(directives.values(), key=lambda d: d['name'])
-
- pdf = template(types=getAttributeTypes(), directives=directives)
- open(outPath or 'rml-reference.pdf', 'wb').write(pdf)
diff --git a/z3c/rml/rlfix.py b/z3c/rml/rlfix.py
deleted file mode 100644
index 78001c99..00000000
--- a/z3c/rml/rlfix.py
+++ /dev/null
@@ -1,50 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2012 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""ReportLab fixups.
-"""
-__docformat__ = "reStructuredText"
-from reportlab.pdfbase import pdfform, pdfmetrics, ttfonts
-from reportlab.pdfbase.pdfpattern import PDFPattern
-from reportlab.graphics import testshapes
-
-def resetPdfForm():
- pdfform.PDFDOCENC = PDFPattern(pdfform.PDFDocEncodingPattern)
- pdfform.ENCODING = PDFPattern(
- pdfform.EncodingPattern, PDFDocEncoding=pdfform.PDFDOCENC)
- pdfform.GLOBALFONTSDICTIONARY = pdfform.FormFontsDictionary()
- pdfform.GLOBALRESOURCES = pdfform.FormResources()
- pdfform.ZADB = PDFPattern(pdfform.ZaDbPattern)
-
-def resetFonts():
- # testshapes._setup registers the Vera fonts every time which is a little
- # slow on all platforms. On Windows it lists the entire system font
- # directory and registers them all which is very slow.
- pdfmetrics.registerFont(ttfonts.TTFont("Vera", "Vera.ttf"))
- pdfmetrics.registerFont(ttfonts.TTFont("VeraBd", "VeraBd.ttf"))
- pdfmetrics.registerFont(ttfonts.TTFont("VeraIt", "VeraIt.ttf"))
- pdfmetrics.registerFont(ttfonts.TTFont("VeraBI", "VeraBI.ttf"))
- for f in ('Times-Roman','Courier','Helvetica','Vera', 'VeraBd', 'VeraIt',
- 'VeraBI'):
- if f not in testshapes._FONTS:
- testshapes._FONTS.append(f)
-
-def setSideLabels():
- from reportlab.graphics.charts import piecharts
- piecharts.Pie3d.sideLabels = 0
-setSideLabels()
-
-from reportlab.rl_config import register_reset
-register_reset(resetPdfForm)
-register_reset(resetFonts)
-del register_reset
diff --git a/z3c/rml/rml-reference.pdf b/z3c/rml/rml-reference.pdf
deleted file mode 100644
index 863fb038..00000000
--- a/z3c/rml/rml-reference.pdf
+++ /dev/null
@@ -1,5978 +0,0 @@
-%PDF-1.4
-%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
-1 0 obj
-<< /F1 2 0 R /F2 4 0 R /F3 5 0 R /F4 7 0 R /F5 10 0 R /F6 11 0 R
- /F7 12 0 R >>
-endobj
-2 0 obj
-<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
-endobj
-3 0 obj
-<< /Contents 1294 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-4 0 obj
-<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >>
-endobj
-5 0 obj
-<< /BaseFont /Times-Roman /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >>
-endobj
-6 0 obj
-<< /Contents 1295 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-7 0 obj
-<< /BaseFont /Times-Bold /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font >>
-endobj
-8 0 obj
-<< /Contents 1296 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-9 0 obj
-<< /Contents 1297 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-10 0 obj
-<< /BaseFont /Times-BoldItalic /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font >>
-endobj
-11 0 obj
-<< /BaseFont /Times-Italic /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font >>
-endobj
-12 0 obj
-<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F7 /Subtype /Type1 /Type /Font >>
-endobj
-13 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-addMapping.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 482.9469 241.3961 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-14 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-addMapping.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 482.9469 297.6378 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-15 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-addMapping.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 482.9469 323.1978 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-16 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-addMapping.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 482.9469 323.1978 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-17 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-alias.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 306.9469 209.7361 318.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-18 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-alias.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 306.9469 297.6378 318.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-19 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-alias.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 306.9469 323.1978 318.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-20 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-alias.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 306.9469 323.1978 318.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-21 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 101.9469 227.5161 113.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-22 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 101.9469 297.6378 113.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-23 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 101.9469 323.1978 113.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-24 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 101.9469 323.1978 113.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-25 0 obj
-<< /Annots [ 13 0 R 14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R 21 0 R 22 0 R
- 23 0 R 24 0 R ] /Contents 1298 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-26 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 183.1969 538.5827 195.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-27 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /Fit ] /Rect [ 56.69291 171.1969 538.5827 183.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-28 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 166 0 R /Fit ] /Rect [ 56.69291 159.1969 538.5827 171.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-29 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1058 0 R /Fit ] /Rect [ 56.69291 147.1969 538.5827 159.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-30 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /Fit ] /Rect [ 56.69291 135.1969 538.5827 147.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-31 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 123.1969 538.5827 135.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-32 0 obj
-<< /Annots [ 26 0 R 27 0 R 28 0 R 29 0 R 30 0 R 31 0 R ] /Contents 1299 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-33 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 518.9469 227.5161 530.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-34 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 518.9469 297.6378 530.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-35 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 518.9469 323.1978 530.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-36 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 518.9469 323.1978 530.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-37 0 obj
-<< /Annots [ 33 0 R 34 0 R 35 0 R 36 0 R ] /Contents 1300 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-38 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 473.1969 538.5827 485.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-39 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 69 0 R /Fit ] /Rect [ 56.69291 461.1969 538.5827 473.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-40 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 166 0 R /Fit ] /Rect [ 56.69291 449.1969 538.5827 461.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-41 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1058 0 R /Fit ] /Rect [ 56.69291 437.1969 538.5827 449.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-42 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 67 0 R /Fit ] /Rect [ 56.69291 425.1969 538.5827 437.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-43 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 413.1969 538.5827 425.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-44 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart3d.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 119.9469 237.5161 131.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-45 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 119.9469 297.6378 131.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-46 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 119.9469 323.1978 131.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-47 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 119.9469 323.1978 131.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-48 0 obj
-<< /Annots [ 38 0 R 39 0 R 40 0 R 41 0 R 42 0 R 43 0 R 44 0 R 45 0 R 46 0 R 47 0 R ] /Contents 1301 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-49 0 obj
-<< /Contents 1302 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-50 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barcode.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 516.9469 223.0561 528.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-51 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barcode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 516.9469 297.6378 528.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-52 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barcode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 516.9469 323.1978 528.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-53 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barcode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 516.9469 323.1978 528.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-54 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barcode.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 426.9469 223.0561 438.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-55 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barcode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 426.9469 297.6378 438.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-56 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barcode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 426.9469 323.1978 438.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-57 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barcode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 426.9469 323.1978 438.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-58 0 obj
-<< /Annots [ 50 0 R 51 0 R 52 0 R 53 0 R 54 0 R 55 0 R 56 0 R 57 0 R ] /Contents 1303 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-59 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barCodeFlowable.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 224.9469 263.0661 236.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-60 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barCodeFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 212.9469 297.6378 224.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-61 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barCodeFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 212.9469 323.1978 224.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-62 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barCodeFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 212.9469 323.1978 224.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-63 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barCodeFlowable.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 146.9469 263.0661 158.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-64 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barCodeFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 134.9469 297.6378 146.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-65 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barCodeFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 134.9469 323.1978 146.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-66 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barCodeFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 134.9469 323.1978 146.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-67 0 obj
-<< /Annots [ 59 0 R 60 0 R 61 0 R 62 0 R 63 0 R 64 0 R 65 0 R 66 0 R ] /Contents 1304 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-68 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 474 0 R /Fit ] /Rect [ 56.69291 84.19685 538.5827 96.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-69 0 obj
-<< /Annots [ 68 0 R ] /Contents 1305 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-70 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 25 0 R /Fit ] /Rect [ 56.69291 625.1969 538.5827 637.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-71 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 423.9469 254.1661 435.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-72 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 423.9469 297.6378 435.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-73 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 423.9469 323.1978 435.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-74 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 423.9469 323.1978 435.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-75 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 160.9469 254.1661 172.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-76 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 160.9469 297.6378 172.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-77 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 160.9469 323.1978 172.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-78 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 160.9469 323.1978 172.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-79 0 obj
-<< /Annots [ 70 0 R 71 0 R 72 0 R 73 0 R 74 0 R 75 0 R 76 0 R 77 0 R 78 0 R ] /Contents 1306 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-80 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 678.9469 254.1661 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-81 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 678.9469 297.6378 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-82 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 678.9469 323.1978 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-83 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 678.9469 323.1978 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-84 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 473.9469 254.1661 485.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-85 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 473.9469 297.6378 485.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-86 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 473.9469 323.1978 485.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-87 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 473.9469 323.1978 485.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-88 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 210.9469 254.1661 222.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-89 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 210.9469 297.6378 222.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-90 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 210.9469 323.1978 222.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-91 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 210.9469 323.1978 222.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-92 0 obj
-<< /Annots [ 80 0 R 81 0 R 82 0 R 83 0 R 84 0 R 85 0 R 86 0 R 87 0 R 88 0 R 89 0 R
- 90 0 R 91 0 R ] /Contents 1307 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-93 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 741.9469 254.1661 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-94 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 297.6378 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-95 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-96 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-97 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 536.9469 254.1661 548.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-98 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 536.9469 297.6378 548.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-99 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 536.9469 323.1978 548.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-100 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 536.9469 323.1978 548.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-101 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 331.9469 254.1661 343.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-102 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 331.9469 297.6378 343.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-103 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 331.9469 323.1978 343.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-104 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 331.9469 323.1978 343.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-105 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 126.9469 254.1661 138.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-106 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 126.9469 297.6378 138.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-107 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 126.9469 323.1978 138.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-108 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 126.9469 323.1978 138.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-109 0 obj
-<< /Annots [ 93 0 R 94 0 R 95 0 R 96 0 R 97 0 R 98 0 R 99 0 R 100 0 R 101 0 R 102 0 R
- 103 0 R 104 0 R 105 0 R 106 0 R 107 0 R 108 0 R ] /Contents 1308 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-110 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 678.9469 254.1661 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-111 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 678.9469 297.6378 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-112 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 678.9469 323.1978 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-113 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 678.9469 323.1978 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-114 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1043 0 R /Fit ] /Rect [ 56.69291 430.1969 538.5827 442.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-115 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 166 0 R /Fit ] /Rect [ 56.69291 418.1969 538.5827 430.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-116 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 124 0 R /Fit ] /Rect [ 56.69291 406.1969 538.5827 418.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-117 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTable-1.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 244.9469 243.0561 256.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-118 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 244.9469 297.6378 256.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-119 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 244.9469 323.1978 256.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-120 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 244.9469 323.1978 256.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-121 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 92 0 R /Fit ] /Rect [ 56.69291 83.19685 538.5827 95.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-122 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 92 0 R /Fit ] /Rect [ 56.69291 71.19685 538.5827 83.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-123 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 148 0 R /Fit ] /Rect [ 56.69291 59.19685 538.5827 71.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-124 0 obj
-<< /Annots [ 110 0 R 111 0 R 112 0 R 113 0 R 114 0 R 115 0 R 116 0 R 117 0 R 118 0 R 119 0 R
- 120 0 R 121 0 R 122 0 R 123 0 R ] /Contents 1309 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-125 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /Fit ] /Rect [ 56.69291 773.1969 538.5827 785.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-126 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 109 0 R /Fit ] /Rect [ 56.69291 761.1969 538.5827 773.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-127 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 109 0 R /Fit ] /Rect [ 56.69291 749.1969 538.5827 761.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-128 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /Fit ] /Rect [ 56.69291 737.1969 538.5827 749.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-129 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 148 0 R /Fit ] /Rect [ 56.69291 725.1969 538.5827 737.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-130 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 79 0 R /Fit ] /Rect [ 56.69291 713.1969 538.5827 725.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-131 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 109 0 R /Fit ] /Rect [ 56.69291 701.1969 538.5827 713.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-132 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 92 0 R /Fit ] /Rect [ 56.69291 689.1969 538.5827 701.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-133 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 148 0 R /Fit ] /Rect [ 56.69291 677.1969 538.5827 689.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-134 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 109 0 R /Fit ] /Rect [ 56.69291 665.1969 538.5827 677.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-135 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 543 0 R /Fit ] /Rect [ 56.69291 653.1969 538.5827 665.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-136 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 575.9469 254.1661 587.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-137 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 575.9469 297.6378 587.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-138 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 575.9469 323.1978 587.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-139 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 575.9469 323.1978 587.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-140 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 370.9469 254.1661 382.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-141 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 370.9469 297.6378 382.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-142 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 370.9469 323.1978 382.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-143 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 370.9469 323.1978 382.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-144 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 165.9469 254.1661 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-145 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 165.9469 297.6378 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-146 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 165.9469 323.1978 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-147 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 165.9469 323.1978 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-148 0 obj
-<< /Annots [ 125 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R 134 0 R
- 135 0 R 136 0 R 137 0 R 138 0 R 139 0 R 140 0 R 141 0 R 142 0 R 143 0 R 144 0 R
- 145 0 R 146 0 R 147 0 R ] /Contents 1310 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-149 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTableStyle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 678.9469 254.1661 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-150 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 678.9469 297.6378 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-151 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 678.9469 323.1978 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-152 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTableStyle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 678.9469 323.1978 690.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-153 0 obj
-<< /Annots [ 149 0 R 150 0 R 151 0 R 152 0 R ] /Contents 1311 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-154 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-bookmark.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 661.9469 230.2761 673.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-155 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 661.9469 297.6378 673.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-156 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 661.9469 323.1978 673.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-157 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 661.9469 323.1978 673.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-158 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-bookmark.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 619.9469 230.2761 631.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-159 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 619.9469 297.6378 631.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-160 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 619.9469 323.1978 631.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-161 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 619.9469 323.1978 631.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-162 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTable-bulkData.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 388.9469 275.2761 400.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-163 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-bulkData.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 297.6378 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-164 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-bulkData.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-165 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-bulkData.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-166 0 obj
-<< /Annots [ 154 0 R 155 0 R 156 0 R 157 0 R 158 0 R 159 0 R 160 0 R 161 0 R 162 0 R 163 0 R
- 164 0 R 165 0 R ] /Contents 1312 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-167 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 183 0 R /Fit ] /Rect [ 56.69291 241.1969 538.5827 253.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-168 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 476 0 R /Fit ] /Rect [ 56.69291 229.1969 538.5827 241.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-169 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 79.94685 227.5161 91.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-170 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 79.94685 297.6378 91.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-171 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 79.94685 323.1978 91.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-172 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 79.94685 323.1978 91.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-173 0 obj
-<< /Annots [ 167 0 R 168 0 R 169 0 R 170 0 R 171 0 R 172 0 R ] /Contents 1313 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-174 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 583 0 R /Fit ] /Rect [ 56.69291 717.1969 538.5827 729.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-175 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 603.9469 227.5161 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-176 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 603.9469 297.6378 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-177 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 603.9469 323.1978 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-178 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 603.9469 323.1978 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-179 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-circle.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 340.9469 213.0561 352.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-180 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-circle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 340.9469 297.6378 352.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-181 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-circle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 340.9469 323.1978 352.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-182 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-circle.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 340.9469 323.1978 352.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-183 0 obj
-<< /Annots [ 174 0 R 175 0 R 176 0 R 177 0 R 178 0 R 179 0 R 180 0 R 181 0 R 182 0 R ] /Contents 1314 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-184 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-codesnippet.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 698.9469 238.0561 710.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-185 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-codesnippet.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 698.9469 297.6378 710.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-186 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-codesnippet.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 698.9469 323.1978 710.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-187 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-codesnippet.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 698.9469 323.1978 710.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-188 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-codesnippet.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 620.9469 238.0561 632.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-189 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-codesnippet.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 620.9469 297.6378 632.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-190 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-codesnippet.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 620.9469 323.1978 632.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-191 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-codesnippet.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 620.9469 323.1978 632.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-192 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-color.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 270.9469 211.3961 282.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-193 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-color.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 270.9469 297.6378 282.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-194 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-color.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 270.9469 323.1978 282.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-195 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-color.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 270.9469 323.1978 282.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-196 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-condPageBreak.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 123.9469 254.1561 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-197 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-condPageBreak.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 123.9469 297.6378 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-198 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-condPageBreak.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 123.9469 323.1978 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-199 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-condPageBreak.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 123.9469 323.1978 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-200 0 obj
-<< /Annots [ 184 0 R 185 0 R 186 0 R 187 0 R 188 0 R 189 0 R 190 0 R 191 0 R 192 0 R 193 0 R
- 194 0 R 195 0 R 196 0 R 197 0 R 198 0 R 199 0 R ] /Contents 1315 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-201 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 707.9469 203.0661 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-202 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 707.9469 297.6378 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-203 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 707.9469 323.1978 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-204 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 707.9469 323.1978 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-205 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-cropMarks.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 374.9469 234.1661 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-206 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-cropMarks.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 374.9469 297.6378 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-207 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-cropMarks.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 374.9469 323.1978 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-208 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-cropMarks.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 374.9469 323.1978 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-209 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-curves.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 179.9469 216.3861 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-210 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-curves.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 179.9469 297.6378 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-211 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-curves.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 179.9469 323.1978 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-212 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-curves.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 179.9469 323.1978 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-213 0 obj
-<< /Annots [ 201 0 R 202 0 R 203 0 R 204 0 R 205 0 R 206 0 R 207 0 R 208 0 R 209 0 R 210 0 R
- 211 0 R 212 0 R ] /Contents 1316 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-214 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-path.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 627.9469 208.0661 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-215 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 627.9469 297.6378 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-216 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 627.9469 323.1978 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-217 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 627.9469 323.1978 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-218 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 814 0 R /Fit ] /Rect [ 56.69291 546.1969 538.5827 558.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-219 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 456.9469 227.5161 468.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-220 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 456.9469 297.6378 468.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-221 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 456.9469 323.1978 468.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-222 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 456.9469 323.1978 468.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-223 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 814 0 R /Fit ] /Rect [ 56.69291 375.1969 538.5827 387.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-224 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 141.9469 221.9561 153.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-225 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 141.9469 297.6378 153.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-226 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 141.9469 323.1978 153.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-227 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 141.9469 323.1978 153.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-228 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 814 0 R /Fit ] /Rect [ 56.69291 60.19685 538.5827 72.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-229 0 obj
-<< /Annots [ 214 0 R 215 0 R 216 0 R 217 0 R 218 0 R 219 0 R 220 0 R 221 0 R 222 0 R 223 0 R
- 224 0 R 225 0 R 226 0 R 227 0 R 228 0 R ] /Contents 1317 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-230 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 717.9469 225.8461 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-231 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 717.9469 297.6378 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-232 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 717.9469 323.1978 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-233 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 717.9469 323.1978 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-234 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 570.9469 203.0661 582.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-235 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 570.9469 297.6378 582.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-236 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 570.9469 323.1978 582.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-237 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 570.9469 323.1978 582.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-238 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 394.9469 204.7261 406.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-239 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 394.9469 297.6378 406.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-240 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 394.9469 323.1978 406.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-241 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 394.9469 323.1978 406.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-242 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 364.9469 204.7261 376.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-243 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 364.9469 297.6378 376.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-244 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 364.9469 323.1978 376.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-245 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 364.9469 323.1978 376.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-246 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 268.9469 204.7261 280.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-247 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 268.9469 297.6378 280.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-248 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 268.9469 323.1978 280.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-249 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 268.9469 323.1978 280.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-250 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 121.9469 204.7261 133.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-251 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 121.9469 297.6378 133.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-252 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 121.9469 323.1978 133.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-253 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 121.9469 323.1978 133.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-254 0 obj
-<< /Annots [ 230 0 R 231 0 R 232 0 R 233 0 R 234 0 R 235 0 R 236 0 R 237 0 R 238 0 R 239 0 R
- 240 0 R 241 0 R 242 0 R 243 0 R 244 0 R 245 0 R 246 0 R 247 0 R 248 0 R 249 0 R
- 250 0 R 251 0 R 252 0 R 253 0 R ] /Contents 1318 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-255 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 659.9469 204.7261 671.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-256 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 659.9469 297.6378 671.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-257 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 659.9469 323.1978 671.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-258 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 659.9469 323.1978 671.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-259 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 425.9469 204.7261 437.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-260 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 425.9469 297.6378 437.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-261 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 425.9469 323.1978 437.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-262 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 425.9469 323.1978 437.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-263 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-doc.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 242.9469 204.7261 254.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-264 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 242.9469 297.6378 254.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-265 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 242.9469 323.1978 254.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-266 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-doc.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 242.9469 323.1978 254.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-267 0 obj
-<< /Annots [ 255 0 R 256 0 R 257 0 R 258 0 R 259 0 R 260 0 R 261 0 R 262 0 R 263 0 R 264 0 R
- 265 0 R 266 0 R ] /Contents 1319 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-268 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 200 0 R /Fit ] /Rect [ 56.69291 415.1969 538.5827 427.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-269 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 583 0 R /Fit ] /Rect [ 56.69291 403.1969 538.5827 415.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-270 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 783 0 R /Fit ] /Rect [ 56.69291 391.1969 538.5827 403.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-271 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 766 0 R /Fit ] /Rect [ 56.69291 379.1969 538.5827 391.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-272 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 766 0 R /Fit ] /Rect [ 56.69291 367.1969 538.5827 379.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-273 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 783 0 R /Fit ] /Rect [ 56.69291 355.1969 538.5827 367.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-274 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 783 0 R /Fit ] /Rect [ 56.69291 343.1969 538.5827 355.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-275 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 25 0 R /Fit ] /Rect [ 56.69291 331.1969 538.5827 343.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-276 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 570 0 R /Fit ] /Rect [ 56.69291 319.1969 538.5827 331.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-277 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 213 0 R /Fit ] /Rect [ 56.69291 307.1969 538.5827 319.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-278 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 909 0 R /Fit ] /Rect [ 56.69291 295.1969 538.5827 307.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-279 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-docinit-viewer-options.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 181.9469 278.3361 193.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-280 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-docinit-viewer-options.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 169.9469 297.6378 181.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-281 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-docinit-viewer-options.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 169.9469 323.1978 181.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-282 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-docinit-viewer-options.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 169.9469 323.1978 181.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-283 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-addMapping.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 103.9469 241.3961 115.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-284 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-addMapping.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 103.9469 297.6378 115.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-285 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-addMapping.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 103.9469 323.1978 115.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-286 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-addMapping.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 103.9469 323.1978 115.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-287 0 obj
-<< /Annots [ 268 0 R 269 0 R 270 0 R 271 0 R 272 0 R 273 0 R 274 0 R 275 0 R 276 0 R 277 0 R
- 278 0 R 279 0 R 280 0 R 281 0 R 282 0 R 283 0 R 284 0 R 285 0 R 286 0 R ] /Contents 1320 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-288 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerTTFont.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 746.9469 251.4061 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-289 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 746.9469 297.6378 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-290 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 746.9469 323.1978 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-291 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 746.9469 323.1978 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-292 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 267 0 R /Fit ] /Rect [ 56.69291 411.1969 538.5827 423.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-293 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 985 0 R /Fit ] /Rect [ 56.69291 399.1969 538.5827 411.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-294 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 995 0 R /Fit ] /Rect [ 56.69291 387.1969 538.5827 399.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-295 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 909 0 R /Fit ] /Rect [ 56.69291 375.1969 538.5827 387.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-296 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 683 0 R /Fit ] /Rect [ 56.69291 363.1969 538.5827 375.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-297 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 614 0 R /Fit ] /Rect [ 56.69291 351.1969 538.5827 363.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-298 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-annotations.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 165.9469 277.2261 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-299 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 153.9469 297.6378 165.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-300 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 153.9469 323.1978 165.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-301 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 153.9469 323.1978 165.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-302 0 obj
-<< /Annots [ 288 0 R 289 0 R 290 0 R 291 0 R 292 0 R 293 0 R 294 0 R 295 0 R 296 0 R 297 0 R
- 298 0 R 299 0 R 300 0 R 301 0 R ] /Contents 1321 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-303 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-story.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 734.9469 252.4961 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-304 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 734.9469 297.6378 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-305 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 734.9469 323.1978 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-306 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 734.9469 323.1978 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-307 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-pageDrawing.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 656.9469 284.9961 668.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-308 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-pageDrawing.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 644.9469 297.6378 656.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-309 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-pageDrawing.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 644.9469 323.1978 656.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-310 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-pageDrawing.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 644.9469 323.1978 656.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-311 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-drawAlignedString.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 388.9469 266.4061 400.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-312 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawAlignedString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 297.6378 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-313 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawAlignedString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-314 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawAlignedString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-315 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-drawCenteredString.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 149.9469 271.9561 161.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-316 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawCenteredString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 137.9469 297.6378 149.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-317 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawCenteredString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 137.9469 323.1978 149.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-318 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawCenteredString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 137.9469 323.1978 149.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-319 0 obj
-<< /Annots [ 303 0 R 304 0 R 305 0 R 306 0 R 307 0 R 308 0 R 309 0 R 310 0 R 311 0 R 312 0 R
- 313 0 R 314 0 R 315 0 R 316 0 R 317 0 R 318 0 R ] /Contents 1322 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-320 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-drawRightString.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 627.9469 256.9661 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-321 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawRightString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 627.9469 297.6378 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-322 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawRightString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 627.9469 323.1978 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-323 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawRightString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 627.9469 323.1978 639.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-324 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-drawString.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 400.9469 235.2961 412.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-325 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 400.9469 297.6378 412.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-326 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 400.9469 323.1978 412.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-327 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 400.9469 323.1978 412.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-328 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ellipse.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 96.94685 216.3961 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-329 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ellipse.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 96.94685 297.6378 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-330 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ellipse.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 96.94685 323.1978 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-331 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ellipse.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 96.94685 323.1978 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-332 0 obj
-<< /Annots [ 320 0 R 321 0 R 322 0 R 323 0 R 324 0 R 325 0 R 326 0 R 327 0 R 328 0 R 329 0 R
- 330 0 R 331 0 R ] /Contents 1323 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-333 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 668.9469 203.0661 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-334 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 668.9469 297.6378 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-335 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 668.9469 323.1978 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-336 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 668.9469 323.1978 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-337 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-fill.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 521.9469 201.4061 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-338 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-fill.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 521.9469 297.6378 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-339 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-fill.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 521.9469 323.1978 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-340 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-fill.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 521.9469 323.1978 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-341 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-fixedSize.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 201.9469 225.8361 213.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-342 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-fixedSize.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 201.9469 297.6378 213.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-343 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-fixedSize.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 201.9469 323.1978 213.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-344 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-fixedSize.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 201.9469 323.1978 213.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-345 0 obj
-<< /Annots [ 333 0 R 334 0 R 335 0 R 336 0 R 337 0 R 338 0 R 339 0 R 340 0 R 341 0 R 342 0 R
- 343 0 R 344 0 R ] /Contents 1324 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-346 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-annotations.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 516.9469 277.2261 528.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-347 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 504.9469 297.6378 516.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-348 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 504.9469 323.1978 516.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-349 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 504.9469 323.1978 516.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-350 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-story.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 474.9469 252.4961 486.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-351 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 474.9469 297.6378 486.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-352 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 474.9469 323.1978 486.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-353 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 474.9469 323.1978 486.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-354 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-grid.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 298.9469 206.9561 310.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-355 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-grid.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 298.9469 297.6378 310.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-356 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-grid.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 298.9469 323.1978 310.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-357 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-grid.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 298.9469 323.1978 310.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-358 0 obj
-<< /Annots [ 346 0 R 347 0 R 348 0 R 349 0 R 350 0 R 351 0 R 352 0 R 353 0 R 354 0 R 355 0 R
- 356 0 R 357 0 R ] /Contents 1325 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-359 0 obj
-<< /Contents 1326 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-360 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 741.9469 209.1761 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-361 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 297.6378 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-362 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-363 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-364 0 obj
-<< /Annots [ 360 0 R 361 0 R 362 0 R 363 0 R ] /Contents 1327 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-365 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 453.9469 209.1761 465.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-366 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 453.9469 297.6378 465.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-367 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 453.9469 323.1978 465.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-368 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 453.9469 323.1978 465.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-369 0 obj
-<< /Annots [ 365 0 R 366 0 R 367 0 R 368 0 R ] /Contents 1328 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-370 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 163.9469 209.1761 175.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-371 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 163.9469 297.6378 175.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-372 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 163.9469 323.1978 175.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-373 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 163.9469 323.1978 175.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-374 0 obj
-<< /Annots [ 370 0 R 371 0 R 372 0 R 373 0 R ] /Contents 1329 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-375 0 obj
-<< /Contents 1330 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-376 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 598.9469 209.1761 610.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-377 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 598.9469 297.6378 610.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-378 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 598.9469 323.1978 610.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-379 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 598.9469 323.1978 610.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-380 0 obj
-<< /Annots [ 376 0 R 377 0 R 378 0 R 379 0 R ] /Contents 1331 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-381 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 308.9469 209.1761 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-382 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 308.9469 297.6378 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-383 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 308.9469 323.1978 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-384 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 308.9469 323.1978 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-385 0 obj
-<< /Annots [ 381 0 R 382 0 R 383 0 R 384 0 R ] /Contents 1332 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-386 0 obj
-<< /Contents 1333 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-387 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 741.9469 209.1761 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-388 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 297.6378 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-389 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-390 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-391 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-hr.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 350.9469 199.1761 362.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-392 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-hr.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 350.9469 297.6378 362.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-393 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-hr.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 350.9469 323.1978 362.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-394 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-hr.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 350.9469 323.1978 362.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-395 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-illustration.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 90.94685 234.7461 102.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-396 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-illustration.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 90.94685 297.6378 102.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-397 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-illustration.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 90.94685 323.1978 102.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-398 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-illustration.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 90.94685 323.1978 102.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-399 0 obj
-<< /Annots [ 387 0 R 388 0 R 389 0 R 390 0 R 391 0 R 392 0 R 393 0 R 394 0 R 395 0 R 396 0 R
- 397 0 R 398 0 R ] /Contents 1334 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-400 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-image.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 470.9469 214.7261 482.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-401 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-image.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 470.9469 297.6378 482.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-402 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-image.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 470.9469 323.1978 482.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-403 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-image.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 470.9469 323.1978 482.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-404 0 obj
-<< /Annots [ 400 0 R 401 0 R 402 0 R 403 0 R ] /Contents 1335 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-405 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-imageAndFlowables.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 770.9469 272.5061 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-406 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-imageAndFlowables.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 297.6378 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-407 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-imageAndFlowables.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-408 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-imageAndFlowables.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-409 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-imageAndFlowables-svg.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 680.9469 286.6661 692.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-410 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-imageAndFlowables-svg.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 668.9469 297.6378 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-411 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-imageAndFlowables-svg.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 668.9469 323.1978 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-412 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-imageAndFlowables-svg.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 668.9469 323.1978 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-413 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-img.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 335.9469 205.2861 347.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-414 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 335.9469 297.6378 347.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-415 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 335.9469 323.1978 347.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-416 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 335.9469 323.1978 347.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-417 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-img.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 305.9469 205.2861 317.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-418 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 305.9469 297.6378 317.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-419 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 305.9469 323.1978 317.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-420 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 305.9469 323.1978 317.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-421 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-img.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 263.9469 205.2861 275.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-422 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 263.9469 297.6378 275.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-423 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 263.9469 323.1978 275.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-424 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-img.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 263.9469 323.1978 275.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-425 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-includePdfPages.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 87.94685 258.0561 99.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-426 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-includePdfPages.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 87.94685 297.6378 99.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-427 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-includePdfPages.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 87.94685 323.1978 99.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-428 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-includePdfPages.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 87.94685 323.1978 99.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-429 0 obj
-<< /Annots [ 405 0 R 406 0 R 407 0 R 408 0 R 409 0 R 410 0 R 411 0 R 412 0 R 413 0 R 414 0 R
- 415 0 R 416 0 R 417 0 R 418 0 R 419 0 R 420 0 R 421 0 R 422 0 R 423 0 R 424 0 R
- 425 0 R 426 0 R 427 0 R 428 0 R ] /Contents 1336 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-430 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-indent.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 495.9469 215.2861 507.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-431 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-indent.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 495.9469 297.6378 507.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-432 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-indent.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 495.9469 323.1978 507.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-433 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-indent.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 495.9469 323.1978 507.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-434 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 348.9469 203.0661 360.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-435 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 348.9469 297.6378 360.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-436 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 348.9469 323.1978 360.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-437 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 348.9469 323.1978 360.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-438 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 583 0 R /Fit ] /Rect [ 56.69291 267.1969 538.5827 279.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-439 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 25 0 R /Fit ] /Rect [ 56.69291 255.1969 538.5827 267.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-440 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 200 0 R /Fit ] /Rect [ 56.69291 243.1969 538.5827 255.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-441 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-alias.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 165.9469 209.7361 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-442 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-alias.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 165.9469 297.6378 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-443 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-alias.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 165.9469 323.1978 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-444 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-alias.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 165.9469 323.1978 177.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-445 0 obj
-<< /Annots [ 430 0 R 431 0 R 432 0 R 433 0 R 434 0 R 435 0 R 436 0 R 437 0 R 438 0 R 439 0 R
- 440 0 R 441 0 R 442 0 R 443 0 R 444 0 R ] /Contents 1337 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-446 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-keepInFrame.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 543.9469 243.5961 555.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-447 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-keepInFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 543.9469 297.6378 555.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-448 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-keepInFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 543.9469 323.1978 555.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-449 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-keepInFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 543.9469 323.1978 555.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-450 0 obj
-<< /Annots [ 446 0 R 447 0 R 448 0 R 449 0 R ] /Contents 1338 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-451 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-keepTogether.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 746.9469 244.7161 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-452 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-keepTogether.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 746.9469 297.6378 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-453 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-keepTogether.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 746.9469 323.1978 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-454 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-keepTogether.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 746.9469 323.1978 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-455 0 obj
-<< /Annots [ 451 0 R 452 0 R 453 0 R 454 0 R ] /Contents 1339 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-456 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 511.9469 238.6261 523.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-457 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 511.9469 297.6378 523.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-458 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 511.9469 323.1978 523.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-459 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 511.9469 323.1978 523.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-460 0 obj
-<< /Annots [ 456 0 R 457 0 R 458 0 R 459 0 R ] /Contents 1340 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-461 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 395.9469 225.8461 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-462 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 395.9469 297.6378 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-463 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 395.9469 323.1978 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-464 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 395.9469 323.1978 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-465 0 obj
-<< /Annots [ 461 0 R 462 0 R 463 0 R 464 0 R ] /Contents 1341 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-466 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 279.9469 238.6261 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-467 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 279.9469 297.6378 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-468 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 279.9469 323.1978 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-469 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 279.9469 323.1978 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-470 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart3d.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 132.9469 235.8461 144.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-471 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 132.9469 297.6378 144.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-472 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 132.9469 323.1978 144.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-473 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 132.9469 323.1978 144.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-474 0 obj
-<< /Annots [ 466 0 R 467 0 R 468 0 R 469 0 R 470 0 R 471 0 R 472 0 R 473 0 R ] /Contents 1342 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-475 0 obj
-<< /Contents 1343 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-476 0 obj
-<< /Contents 1344 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-477 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 474 0 R /Fit ] /Rect [ 56.69291 647.1969 538.5827 659.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-478 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 593.9469 227.5161 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-479 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 593.9469 297.6378 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-480 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 593.9469 323.1978 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-481 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 593.9469 323.1978 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-482 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 474 0 R /Fit ] /Rect [ 56.69291 512.1969 538.5827 524.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-483 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart3d.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 374.9469 235.8461 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-484 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 374.9469 297.6378 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-485 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 374.9469 323.1978 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-486 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 374.9469 323.1978 386.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-487 0 obj
-<< /Annots [ 477 0 R 478 0 R 479 0 R 480 0 R 481 0 R 482 0 R 483 0 R 484 0 R 485 0 R 486 0 R ] /Contents 1345 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-488 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ul-ol-li.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 608.9469 218.0661 620.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-489 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 608.9469 297.6378 620.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-490 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 608.9469 323.1978 620.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-491 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 608.9469 323.1978 620.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-492 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ul-ol-li.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 118.9469 218.0661 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-493 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 118.9469 297.6378 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-494 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 118.9469 323.1978 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-495 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 118.9469 323.1978 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-496 0 obj
-<< /Annots [ 488 0 R 489 0 R 490 0 R 491 0 R 492 0 R 493 0 R 494 0 R 495 0 R ] /Contents 1346 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-497 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 574.9469 221.9561 586.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-498 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 574.9469 297.6378 586.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-499 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 574.9469 323.1978 586.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-500 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 574.9469 323.1978 586.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-501 0 obj
-<< /Annots [ 497 0 R 498 0 R 499 0 R 500 0 R ] /Contents 1347 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-502 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 474 0 R /Fit ] /Rect [ 56.69291 473.1969 538.5827 485.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-503 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 419.9469 221.9561 431.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-504 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 419.9469 297.6378 431.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-505 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 419.9469 323.1978 431.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-506 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 419.9469 323.1978 431.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-507 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-lineMode.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 156.9469 228.0561 168.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-508 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-lineMode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 156.9469 297.6378 168.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-509 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-lineMode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 156.9469 323.1978 168.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-510 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-lineMode.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 156.9469 323.1978 168.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-511 0 obj
-<< /Annots [ 502 0 R 503 0 R 504 0 R 505 0 R 506 0 R 507 0 R 508 0 R 509 0 R 510 0 R ] /Contents 1348 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-512 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 287.1969 538.5827 299.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-513 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 543 0 R /Fit ] /Rect [ 56.69291 275.1969 538.5827 287.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-514 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1067 0 R /Fit ] /Rect [ 56.69291 263.1969 538.5827 275.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-515 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1077 0 R /Fit ] /Rect [ 56.69291 251.1969 538.5827 263.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-516 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 501 0 R /Fit ] /Rect [ 56.69291 239.1969 538.5827 251.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-517 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 227.1969 538.5827 239.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-518 0 obj
-<< /Annots [ 512 0 R 513 0 R 514 0 R 515 0 R 516 0 R 517 0 R ] /Contents 1349 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-519 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 542.9469 221.9561 554.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-520 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 542.9469 297.6378 554.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-521 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 542.9469 323.1978 554.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-522 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 542.9469 323.1978 554.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-523 0 obj
-<< /Annots [ 519 0 R 520 0 R 521 0 R 522 0 R ] /Contents 1350 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-524 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 548.1969 538.5827 560.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-525 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 543 0 R /Fit ] /Rect [ 56.69291 536.1969 538.5827 548.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-526 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1067 0 R /Fit ] /Rect [ 56.69291 524.1969 538.5827 536.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-527 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1077 0 R /Fit ] /Rect [ 56.69291 512.1969 538.5827 524.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-528 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 501 0 R /Fit ] /Rect [ 56.69291 500.1969 538.5827 512.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-529 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 488.1969 538.5827 500.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-530 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot3D.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 74.94685 234.1761 86.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-531 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot3D.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 74.94685 297.6378 86.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-532 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot3D.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 74.94685 323.1978 86.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-533 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot3D.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 74.94685 323.1978 86.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-534 0 obj
-<< /Annots [ 524 0 R 525 0 R 526 0 R 527 0 R 528 0 R 529 0 R 530 0 R 531 0 R 532 0 R 533 0 R ] /Contents 1351 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-535 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTable-5.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 395.9469 243.0561 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-536 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-5.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 395.9469 297.6378 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-537 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-5.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 395.9469 323.1978 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-538 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-5.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 395.9469 323.1978 407.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-539 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-lines.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 200.9469 209.1761 212.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-540 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-lines.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 200.9469 297.6378 212.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-541 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-lines.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 200.9469 323.1978 212.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-542 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-lines.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 200.9469 323.1978 212.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-543 0 obj
-<< /Annots [ 535 0 R 536 0 R 537 0 R 538 0 R 539 0 R 540 0 R 541 0 R 542 0 R ] /Contents 1352 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-544 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 496 0 R /Fit ] /Rect [ 56.69291 705.1969 538.5827 717.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-545 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 615.9469 221.9561 627.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-546 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 615.9469 297.6378 627.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-547 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 615.9469 323.1978 627.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-548 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 615.9469 323.1978 627.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-549 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-bookmark.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 316.9469 230.2761 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-550 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 316.9469 297.6378 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-551 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 316.9469 323.1978 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-552 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 316.9469 323.1978 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-553 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-bookmark.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 262.9469 230.2761 274.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-554 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 262.9469 297.6378 274.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-555 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 262.9469 323.1978 274.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-556 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-bookmark.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 262.9469 323.1978 274.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-557 0 obj
-<< /Annots [ 544 0 R 545 0 R 546 0 R 547 0 R 548 0 R 549 0 R 550 0 R 551 0 R 552 0 R 553 0 R
- 554 0 R 555 0 R 556 0 R ] /Contents 1353 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-558 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ul-ol-li.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 475.9469 218.0661 487.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-559 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 475.9469 297.6378 487.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-560 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 475.9469 323.1978 487.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-561 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 475.9469 323.1978 487.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-562 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ul-ol-li.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 433.9469 218.0661 445.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-563 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 433.9469 297.6378 445.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-564 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 433.9469 323.1978 445.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-565 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 433.9469 323.1978 445.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-566 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 235.9469 203.0661 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-567 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 235.9469 297.6378 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-568 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 235.9469 323.1978 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-569 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 235.9469 323.1978 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-570 0 obj
-<< /Annots [ 558 0 R 559 0 R 560 0 R 561 0 R 562 0 R 563 0 R 564 0 R 565 0 R 566 0 R 567 0 R
- 568 0 R 569 0 R ] /Contents 1354 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-571 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 666.9469 203.0661 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-572 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 666.9469 297.6378 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-573 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 666.9469 323.1978 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-574 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 666.9469 323.1978 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-575 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-path.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 376.9469 208.0661 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-576 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 297.6378 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-577 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-578 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-579 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 229.9469 227.5161 241.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-580 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 229.9469 297.6378 241.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-581 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 229.9469 323.1978 241.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-582 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 229.9469 323.1978 241.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-583 0 obj
-<< /Annots [ 571 0 R 572 0 R 573 0 R 574 0 R 575 0 R 576 0 R 577 0 R 578 0 R 579 0 R 580 0 R
- 581 0 R 582 0 R ] /Contents 1355 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-584 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-name.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 770.9469 211.9461 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-585 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-name.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 770.9469 297.6378 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-586 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-name.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 770.9469 323.1978 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-587 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-name.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 770.9469 323.1978 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-588 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-nextFrame.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 482.9469 233.6061 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-589 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-nextFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 482.9469 297.6378 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-590 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-nextFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 482.9469 323.1978 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-591 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-nextFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 482.9469 323.1978 494.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-592 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-nextPage.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 386.9469 227.4961 398.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-593 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-nextPage.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 386.9469 297.6378 398.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-594 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-nextPage.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 386.9469 323.1978 398.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-595 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-nextPage.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 386.9469 323.1978 398.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-596 0 obj
-<< /Annots [ 584 0 R 585 0 R 586 0 R 587 0 R 588 0 R 589 0 R 590 0 R 591 0 R 592 0 R 593 0 R
- 594 0 R 595 0 R ] /Contents 1356 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-597 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 496 0 R /Fit ] /Rect [ 56.69291 664.1969 538.5827 676.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-598 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ul-ol-li.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 526.9469 218.0661 538.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-599 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 526.9469 297.6378 538.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-600 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 526.9469 323.1978 538.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-601 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 526.9469 323.1978 538.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-602 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-selectField.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 379.9469 234.1661 391.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-603 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-selectField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 379.9469 297.6378 391.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-604 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-selectField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 379.9469 323.1978 391.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-605 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-selectField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 379.9469 323.1978 391.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-606 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-outlineAdd.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 123.9469 234.1761 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-607 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-outlineAdd.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 123.9469 297.6378 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-608 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-outlineAdd.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 123.9469 323.1978 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-609 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-outlineAdd.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 123.9469 323.1978 135.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-610 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-outlineAdd.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 93.94685 234.1761 105.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-611 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-outlineAdd.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 93.94685 297.6378 105.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-612 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-outlineAdd.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 93.94685 323.1978 105.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-613 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-outlineAdd.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 93.94685 323.1978 105.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-614 0 obj
-<< /Annots [ 597 0 R 598 0 R 599 0 R 600 0 R 601 0 R 602 0 R 603 0 R 604 0 R 605 0 R 606 0 R
- 607 0 R 608 0 R 609 0 R 610 0 R 611 0 R 612 0 R 613 0 R ] /Contents 1357 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-615 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 800 0 R /Fit ] /Rect [ 56.69291 734.1969 538.5827 746.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-616 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 783 0 R /Fit ] /Rect [ 56.69291 722.1969 538.5827 734.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-617 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 332 0 R /Fit ] /Rect [ 56.69291 710.1969 538.5827 722.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-618 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 319 0 R /Fit ] /Rect [ 56.69291 698.1969 538.5827 710.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-619 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 319 0 R /Fit ] /Rect [ 56.69291 686.1969 538.5827 698.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-620 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 319 0 R /Fit ] /Rect [ 56.69291 674.1969 538.5827 686.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-621 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 319 0 R /Fit ] /Rect [ 56.69291 662.1969 538.5827 674.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-622 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 332 0 R /Fit ] /Rect [ 56.69291 650.1969 538.5827 662.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-623 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 183 0 R /Fit ] /Rect [ 56.69291 638.1969 538.5827 650.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-624 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 753 0 R /Fit ] /Rect [ 56.69291 626.1969 538.5827 638.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-625 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 358 0 R /Fit ] /Rect [ 56.69291 614.1969 538.5827 626.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-626 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 543 0 R /Fit ] /Rect [ 56.69291 602.1969 538.5827 614.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-627 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 213 0 R /Fit ] /Rect [ 56.69291 590.1969 538.5827 602.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-628 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 399 0 R /Fit ] /Rect [ 56.69291 578.1969 538.5827 590.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-629 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 731 0 R /Fit ] /Rect [ 56.69291 566.1969 538.5827 578.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-630 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 554.1969 538.5827 566.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-631 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 698 0 R /Fit ] /Rect [ 56.69291 542.1969 538.5827 554.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-632 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 345 0 R /Fit ] /Rect [ 56.69291 530.1969 538.5827 542.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-633 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 985 0 R /Fit ] /Rect [ 56.69291 518.1969 538.5827 530.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-634 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 814 0 R /Fit ] /Rect [ 56.69291 506.1969 538.5827 518.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-635 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 835 0 R /Fit ] /Rect [ 56.69291 494.1969 538.5827 506.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-636 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 800 0 R /Fit ] /Rect [ 56.69291 482.1969 538.5827 494.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-637 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1052 0 R /Fit ] /Rect [ 56.69291 470.1969 538.5827 482.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-638 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 800 0 R /Fit ] /Rect [ 56.69291 458.1969 538.5827 470.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-639 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 850 0 R /Fit ] /Rect [ 56.69291 446.1969 538.5827 458.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-640 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1052 0 R /Fit ] /Rect [ 56.69291 434.1969 538.5827 446.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-641 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 511 0 R /Fit ] /Rect [ 56.69291 422.1969 538.5827 434.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-642 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 48 0 R /Fit ] /Rect [ 56.69291 410.1969 538.5827 422.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-643 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 398.1969 538.5827 410.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-644 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 166 0 R /Fit ] /Rect [ 56.69291 386.1969 538.5827 398.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-645 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 800 0 R /Fit ] /Rect [ 56.69291 374.1969 538.5827 386.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-646 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 25 0 R /Fit ] /Rect [ 56.69291 362.1969 538.5827 374.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-647 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 37 0 R /Fit ] /Rect [ 56.69291 350.1969 538.5827 362.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-648 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 511 0 R /Fit ] /Rect [ 56.69291 338.1969 538.5827 350.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-649 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 523 0 R /Fit ] /Rect [ 56.69291 326.1969 538.5827 338.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-650 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 710 0 R /Fit ] /Rect [ 56.69291 314.1969 538.5827 326.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-651 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 720 0 R /Fit ] /Rect [ 56.69291 302.1969 538.5827 314.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-652 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 878 0 R /Fit ] /Rect [ 56.69291 290.1969 538.5827 302.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-653 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 153 0 R /Fit ] /Rect [ 56.69291 278.1969 538.5827 290.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-654 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 740 0 R /Fit ] /Rect [ 56.69291 266.1969 538.5827 278.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-655 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-drawString.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 188.9469 235.2961 200.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-656 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 188.9469 297.6378 200.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-657 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 188.9469 323.1978 200.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-658 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-drawString.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 188.9469 323.1978 200.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-659 0 obj
-<< /Annots [ 615 0 R 616 0 R 617 0 R 618 0 R 619 0 R 620 0 R 621 0 R 622 0 R 623 0 R 624 0 R
- 625 0 R 626 0 R 627 0 R 628 0 R 629 0 R 630 0 R 631 0 R 632 0 R 633 0 R 634 0 R
- 635 0 R 636 0 R 637 0 R 638 0 R 639 0 R 640 0 R 641 0 R 642 0 R 643 0 R 644 0 R
- 645 0 R 646 0 R 647 0 R 648 0 R 649 0 R 650 0 R 651 0 R 652 0 R 653 0 R 654 0 R
- 655 0 R 656 0 R 657 0 R 658 0 R ] /Contents 1358 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-660 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pageGraphics.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 770.9469 246.9461 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-661 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageGraphics.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 770.9469 297.6378 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-662 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageGraphics.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 770.9469 323.1978 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-663 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageGraphics.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 770.9469 323.1978 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-664 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pageInfo-2.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 623.9469 234.1661 635.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-665 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageInfo-2.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 623.9469 297.6378 635.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-666 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageInfo-2.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 623.9469 323.1978 635.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-667 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageInfo-2.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 623.9469 323.1978 635.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-668 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pageInfo.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 593.9469 225.8361 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-669 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageInfo.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 593.9469 297.6378 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-670 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageInfo.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 593.9469 323.1978 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-671 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageInfo.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 593.9469 323.1978 605.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-672 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 345 0 R /Fit ] /Rect [ 56.69291 403.1969 538.5827 415.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-673 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 659 0 R /Fit ] /Rect [ 56.69291 391.1969 538.5827 403.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-674 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 583 0 R /Fit ] /Rect [ 56.69291 379.1969 538.5827 391.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-675 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-annotations.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 301.9469 277.2261 313.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-676 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 289.9469 297.6378 301.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-677 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 289.9469 323.1978 301.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-678 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 289.9469 323.1978 301.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-679 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-story.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 235.9469 252.4961 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-680 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 235.9469 297.6378 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-681 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 235.9469 323.1978 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-682 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 235.9469 323.1978 247.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-683 0 obj
-<< /Annots [ 660 0 R 661 0 R 662 0 R 663 0 R 664 0 R 665 0 R 666 0 R 667 0 R 668 0 R 669 0 R
- 670 0 R 671 0 R 672 0 R 673 0 R 674 0 R 675 0 R 676 0 R 677 0 R 678 0 R 679 0 R
- 680 0 R 681 0 R 682 0 R ] /Contents 1359 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-684 0 obj
-<< /Contents 1360 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-685 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 668.9469 209.1761 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-686 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 668.9469 297.6378 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-687 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 668.9469 323.1978 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-688 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 668.9469 323.1978 680.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-689 0 obj
-<< /Annots [ 685 0 R 686 0 R 687 0 R 688 0 R ] /Contents 1361 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-690 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/simple-layout.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 429.9469 228.6161 441.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-691 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 429.9469 297.6378 441.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-692 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 429.9469 323.1978 441.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-693 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 429.9469 323.1978 441.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-694 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-textAnnotation.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 231.9469 249.1761 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-695 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textAnnotation.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 231.9469 297.6378 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-696 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textAnnotation.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 231.9469 323.1978 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-697 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textAnnotation.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 231.9469 323.1978 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-698 0 obj
-<< /Annots [ 690 0 R 691 0 R 692 0 R 693 0 R 694 0 R 695 0 R 696 0 R 697 0 R ] /Contents 1362 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-699 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 583 0 R /Fit ] /Rect [ 56.69291 625.1969 538.5827 637.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-700 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 613.1969 538.5827 625.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-701 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 213 0 R /Fit ] /Rect [ 56.69291 601.1969 538.5827 613.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-702 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-path.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 439.9469 208.0661 451.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-703 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 439.9469 297.6378 451.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-704 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 439.9469 323.1978 451.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-705 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 439.9469 323.1978 451.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-706 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-path.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 361.9469 208.0661 373.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-707 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 361.9469 297.6378 373.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-708 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 361.9469 323.1978 373.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-709 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-path.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 361.9469 323.1978 373.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-710 0 obj
-<< /Annots [ 699 0 R 700 0 R 701 0 R 702 0 R 703 0 R 704 0 R 705 0 R 706 0 R 707 0 R 708 0 R
- 709 0 R ] /Contents 1363 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-711 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 374.1969 538.5827 386.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-712 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 866 0 R /Fit ] /Rect [ 56.69291 362.1969 538.5827 374.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-713 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 487 0 R /Fit ] /Rect [ 56.69291 350.1969 538.5827 362.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-714 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 338.1969 538.5827 350.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-715 0 obj
-<< /Annots [ 711 0 R 712 0 R 713 0 R 714 0 R ] /Contents 1364 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-716 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 746.9469 225.8461 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-717 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 746.9469 297.6378 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-718 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 746.9469 323.1978 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-719 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 746.9469 323.1978 758.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-720 0 obj
-<< /Annots [ 716 0 R 717 0 R 718 0 R 719 0 R ] /Contents 1365 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-721 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 856 0 R /Fit ] /Rect [ 56.69291 664.1969 538.5827 676.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-722 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 652.1969 538.5827 664.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-723 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart3d.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 334.9469 235.8461 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-724 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 334.9469 297.6378 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-725 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 334.9469 323.1978 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-726 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 334.9469 323.1978 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-727 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-place.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 76.94685 211.9461 88.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-728 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-place.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 76.94685 297.6378 88.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-729 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-place.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 76.94685 323.1978 88.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-730 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-place.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 76.94685 323.1978 88.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-731 0 obj
-<< /Annots [ 721 0 R 722 0 R 723 0 R 724 0 R 725 0 R 726 0 R 727 0 R 728 0 R 729 0 R 730 0 R ] /Contents 1366 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-732 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-plugInFlowable.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 547.9469 254.1761 559.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-733 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-plugInFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 547.9469 297.6378 559.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-734 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-plugInFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 547.9469 323.1978 559.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-735 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-plugInFlowable.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 547.9469 323.1978 559.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-736 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-plugInGraphic.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 272.9469 249.7261 284.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-737 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-plugInGraphic.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 272.9469 297.6378 284.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-738 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-plugInGraphic.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 272.9469 323.1978 284.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-739 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-plugInGraphic.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 272.9469 323.1978 284.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-740 0 obj
-<< /Annots [ 732 0 R 733 0 R 734 0 R 735 0 R 736 0 R 737 0 R 738 0 R 739 0 R ] /Contents 1367 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-741 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 741.9469 225.8461 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-742 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 297.6378 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-743 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-744 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 741.9469 323.1978 753.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-745 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 427.9469 209.1761 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-746 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 427.9469 297.6378 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-747 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 427.9469 323.1978 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-748 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 427.9469 323.1978 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-749 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pto.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 139.9469 203.0661 151.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-750 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pto.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 139.9469 297.6378 151.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-751 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pto.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 139.9469 323.1978 151.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-752 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pto.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 139.9469 323.1978 151.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-753 0 obj
-<< /Annots [ 741 0 R 742 0 R 743 0 R 744 0 R 745 0 R 746 0 R 747 0 R 748 0 R 749 0 R 750 0 R
- 751 0 R 752 0 R ] /Contents 1368 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-754 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-rectange.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 487.9469 225.2761 499.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-755 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-rectange.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 487.9469 297.6378 499.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-756 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-rectange.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 487.9469 323.1978 499.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-757 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-rectange.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 487.9469 323.1978 499.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-758 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerCidFont.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 311.9469 254.7361 323.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-759 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerCidFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 311.9469 297.6378 323.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-760 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerCidFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 311.9469 323.1978 323.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-761 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerCidFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 311.9469 323.1978 323.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-762 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerCidFont.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 281.9469 254.7361 293.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-763 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerCidFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 281.9469 297.6378 293.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-764 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerCidFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 281.9469 323.1978 293.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-765 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerCidFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 281.9469 323.1978 293.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-766 0 obj
-<< /Annots [ 754 0 R 755 0 R 756 0 R 757 0 R 758 0 R 759 0 R 760 0 R 761 0 R 762 0 R 763 0 R
- 764 0 R 765 0 R ] /Contents 1369 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-767 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerType1Face.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 770.9469 265.8261 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-768 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerType1Face.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 297.6378 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-769 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerType1Face.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-770 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerType1Face.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-771 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerTTFont.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 376.9469 251.4061 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-772 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 297.6378 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-773 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-774 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 376.9469 323.1978 388.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-775 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerTTFont.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 334.9469 251.4061 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-776 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 334.9469 297.6378 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-777 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 334.9469 323.1978 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-778 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerTTFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 334.9469 323.1978 346.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-779 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-registerType1Face.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 158.9469 265.8261 170.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-780 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerType1Face.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 146.9469 297.6378 158.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-781 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerType1Face.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 146.9469 323.1978 158.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-782 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-registerType1Face.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 146.9469 323.1978 158.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-783 0 obj
-<< /Annots [ 767 0 R 768 0 R 769 0 R 770 0 R 771 0 R 772 0 R 773 0 R 774 0 R 775 0 R 776 0 R
- 777 0 R 778 0 R 779 0 R 780 0 R 781 0 R 782 0 R ] /Contents 1370 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-784 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-saveState-restoreState.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 770.9469 277.2161 782.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-785 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-saveState-restoreState.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 297.6378 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-786 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-saveState-restoreState.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-787 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-saveState-restoreState.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-788 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-rotate.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 611.9469 214.1761 623.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-789 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-rotate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 611.9469 297.6378 623.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-790 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-rotate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 611.9469 323.1978 623.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-791 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-rotate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 611.9469 323.1978 623.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-792 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-saveState-restoreState.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 419.9469 277.2161 431.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-793 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-saveState-restoreState.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 407.9469 297.6378 419.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-794 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-saveState-restoreState.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 407.9469 323.1978 419.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-795 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-saveState-restoreState.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 407.9469 323.1978 419.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-796 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-scale.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 231.9469 210.8361 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-797 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-scale.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 231.9469 297.6378 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-798 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-scale.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 231.9469 323.1978 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-799 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-scale.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 231.9469 323.1978 243.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-800 0 obj
-<< /Annots [ 784 0 R 785 0 R 786 0 R 787 0 R 788 0 R 789 0 R 790 0 R 791 0 R 792 0 R 793 0 R
- 794 0 R 795 0 R 796 0 R 797 0 R 798 0 R 799 0 R ] /Contents 1371 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-801 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 614 0 R /Fit ] /Rect [ 56.69291 676.1969 538.5827 688.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-802 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-selectField.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 562.9469 234.1661 574.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-803 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-selectField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 562.9469 297.6378 574.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-804 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-selectField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 562.9469 323.1978 574.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-805 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-selectField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 562.9469 323.1978 574.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-806 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 415.9469 227.5161 427.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-807 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 415.9469 297.6378 427.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-808 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 415.9469 323.1978 427.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-809 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 415.9469 323.1978 427.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-810 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 196.9469 221.9561 208.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-811 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 196.9469 297.6378 208.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-812 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 196.9469 323.1978 208.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-813 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 196.9469 323.1978 208.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-814 0 obj
-<< /Annots [ 801 0 R 802 0 R 803 0 R 804 0 R 805 0 R 806 0 R 807 0 R 808 0 R 809 0 R 810 0 R
- 811 0 R 812 0 R 813 0 R ] /Contents 1372 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-815 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pageGraphics.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 719.9469 246.9461 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-816 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageGraphics.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 719.9469 297.6378 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-817 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageGraphics.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 719.9469 323.1978 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-818 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pageGraphics.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 719.9469 323.1978 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-819 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-setFont.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 689.9469 220.2861 701.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-820 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 689.9469 297.6378 701.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-821 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 689.9469 323.1978 701.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-822 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setFont.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 689.9469 323.1978 701.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-823 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-setFontSize.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 513.9469 236.3961 525.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-824 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setFontSize.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 513.9469 297.6378 525.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-825 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setFontSize.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 513.9469 323.1978 525.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-826 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setFontSize.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 513.9469 323.1978 525.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-827 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-setNextFrame.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 366.9469 246.3861 378.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-828 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setNextFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 366.9469 297.6378 378.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-829 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setNextFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 366.9469 323.1978 378.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-830 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setNextFrame.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 366.9469 323.1978 378.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-831 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-setNextTemplate.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 219.9469 256.9461 231.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-832 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setNextTemplate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 219.9469 297.6378 231.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-833 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setNextTemplate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 219.9469 323.1978 231.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-834 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-setNextTemplate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 219.9469 323.1978 231.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-835 0 obj
-<< /Annots [ 815 0 R 816 0 R 817 0 R 818 0 R 819 0 R 820 0 R 821 0 R 822 0 R 823 0 R 824 0 R
- 825 0 R 826 0 R 827 0 R 828 0 R 829 0 R 830 0 R 831 0 R 832 0 R 833 0 R 834 0 R ] /Contents 1373 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-836 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-index.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 707.9469 211.9461 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-837 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-index.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 707.9469 297.6378 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-838 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-index.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 707.9469 323.1978 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-839 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-index.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 707.9469 323.1978 719.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-840 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-skew.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 531.9469 209.7261 543.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-841 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-skew.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 531.9469 297.6378 543.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-842 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-skew.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 531.9469 323.1978 543.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-843 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-skew.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 531.9469 323.1978 543.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-844 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 460 0 R /Fit ] /Rect [ 56.69291 179.1969 538.5827 191.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-845 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 740 0 R /Fit ] /Rect [ 56.69291 167.1969 538.5827 179.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-846 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 113.9469 225.8461 125.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-847 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 113.9469 297.6378 125.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-848 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 113.9469 323.1978 125.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-849 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 113.9469 323.1978 125.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-850 0 obj
-<< /Annots [ 836 0 R 837 0 R 838 0 R 839 0 R 840 0 R 841 0 R 842 0 R 843 0 R 844 0 R 845 0 R
- 846 0 R 847 0 R 848 0 R 849 0 R ] /Contents 1374 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-851 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart3d.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 441.9469 235.8461 453.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-852 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 441.9469 297.6378 453.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-853 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 441.9469 323.1978 453.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-854 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 441.9469 323.1978 453.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-855 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 850 0 R /Fit ] /Rect [ 56.69291 89.19685 538.5827 101.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-856 0 obj
-<< /Annots [ 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R ] /Contents 1375 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-857 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart3d.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 662.9469 235.8461 674.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-858 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 662.9469 297.6378 674.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-859 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 662.9469 323.1978 674.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-860 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart3d.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 662.9469 323.1978 674.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-861 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 850 0 R /Fit ] /Rect [ 56.69291 327.1969 538.5827 339.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-862 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-pieChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 177.9469 225.8461 189.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-863 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 177.9469 297.6378 189.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-864 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 177.9469 323.1978 189.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-865 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-pieChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 177.9469 323.1978 189.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-866 0 obj
-<< /Annots [ 857 0 R 858 0 R 859 0 R 860 0 R 861 0 R 862 0 R 863 0 R 864 0 R 865 0 R ] /Contents 1376 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-867 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spacer.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 719.9469 216.9461 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-868 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spacer.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 719.9469 297.6378 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-869 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spacer.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 719.9469 323.1978 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-870 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spacer.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 719.9469 323.1978 731.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-871 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 229 0 R /Fit ] /Rect [ 56.69291 181.1969 538.5827 193.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-872 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 985 0 R /Fit ] /Rect [ 56.69291 169.1969 538.5827 181.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-873 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 965 0 R /Fit ] /Rect [ 56.69291 157.1969 538.5827 169.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-874 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 889 0 R /Fit ] /Rect [ 56.69291 145.1969 538.5827 157.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-875 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 883 0 R /Fit ] /Rect [ 56.69291 133.1969 538.5827 145.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-876 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 487 0 R /Fit ] /Rect [ 56.69291 121.1969 538.5827 133.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-877 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1023 0 R /Fit ] /Rect [ 56.69291 109.1969 538.5827 121.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-878 0 obj
-<< /Annots [ 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R 873 0 R 874 0 R 875 0 R 876 0 R
- 877 0 R ] /Contents 1377 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-879 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 530.9469 238.6261 542.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-880 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 530.9469 297.6378 542.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-881 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 530.9469 323.1978 542.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-882 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 530.9469 323.1978 542.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-883 0 obj
-<< /Annots [ 879 0 R 880 0 R 881 0 R 882 0 R ] /Contents 1378 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-884 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 465 0 R /Fit ] /Rect [ 56.69291 258.1969 538.5827 270.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-885 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 120.9469 238.6261 132.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-886 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 120.9469 297.6378 132.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-887 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 120.9469 323.1978 132.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-888 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 120.9469 323.1978 132.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-889 0 obj
-<< /Annots [ 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R ] /Contents 1379 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-890 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 883 0 R /Fit ] /Rect [ 56.69291 560.1969 538.5827 572.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-891 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 506.9469 238.6261 518.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-892 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 506.9469 297.6378 518.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-893 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 506.9469 323.1978 518.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-894 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 506.9469 323.1978 518.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-895 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-index.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 301.9469 211.9461 313.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-896 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-index.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 301.9469 297.6378 313.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-897 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-index.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 301.9469 323.1978 313.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-898 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-index.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 301.9469 323.1978 313.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-899 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 866 0 R /Fit ] /Rect [ 56.69291 169.1969 538.5827 181.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-900 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 399 0 R /Fit ] /Rect [ 56.69291 157.1969 538.5827 169.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-901 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 753 0 R /Fit ] /Rect [ 56.69291 145.1969 538.5827 157.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-902 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1077 0 R /Fit ] /Rect [ 56.69291 133.1969 538.5827 145.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-903 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 183 0 R /Fit ] /Rect [ 56.69291 121.1969 538.5827 133.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-904 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 740 0 R /Fit ] /Rect [ 56.69291 109.1969 538.5827 121.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-905 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 58 0 R /Fit ] /Rect [ 56.69291 97.19685 538.5827 109.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-906 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 614 0 R /Fit ] /Rect [ 56.69291 85.19685 538.5827 97.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-907 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1029 0 R /Fit ] /Rect [ 56.69291 73.19685 538.5827 85.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-908 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 358 0 R /Fit ] /Rect [ 56.69291 61.19685 538.5827 73.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-909 0 obj
-<< /Annots [ 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 897 0 R 898 0 R 899 0 R
- 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R ] /Contents 1380 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-910 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 364 0 R /Fit ] /Rect [ 56.69291 773.1969 538.5827 785.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-911 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 369 0 R /Fit ] /Rect [ 56.69291 761.1969 538.5827 773.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-912 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 374 0 R /Fit ] /Rect [ 56.69291 749.1969 538.5827 761.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-913 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 380 0 R /Fit ] /Rect [ 56.69291 737.1969 538.5827 749.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-914 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 385 0 R /Fit ] /Rect [ 56.69291 725.1969 538.5827 737.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-915 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 683 0 R /Fit ] /Rect [ 56.69291 713.1969 538.5827 725.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-916 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 124 0 R /Fit ] /Rect [ 56.69291 701.1969 538.5827 713.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-917 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 596 0 R /Fit ] /Rect [ 56.69291 689.1969 538.5827 701.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-918 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 835 0 R /Fit ] /Rect [ 56.69291 677.1969 538.5827 689.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-919 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 596 0 R /Fit ] /Rect [ 56.69291 665.1969 538.5827 677.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-920 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 835 0 R /Fit ] /Rect [ 56.69291 653.1969 538.5827 665.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-921 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 200 0 R /Fit ] /Rect [ 56.69291 641.1969 538.5827 653.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-922 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 445 0 R /Fit ] /Rect [ 56.69291 629.1969 538.5827 641.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-923 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 450 0 R /Fit ] /Rect [ 56.69291 617.1969 538.5827 629.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-924 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 429 0 R /Fit ] /Rect [ 56.69291 605.1969 538.5827 617.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-925 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 404 0 R /Fit ] /Rect [ 56.69291 593.1969 538.5827 605.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-926 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 753 0 R /Fit ] /Rect [ 56.69291 581.1969 538.5827 593.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-927 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 429 0 R /Fit ] /Rect [ 56.69291 569.1969 538.5827 581.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-928 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 345 0 R /Fit ] /Rect [ 56.69291 557.1969 538.5827 569.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-929 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 153 0 R /Fit ] /Rect [ 56.69291 545.1969 538.5827 557.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-930 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 153 0 R /Fit ] /Rect [ 56.69291 533.1969 538.5827 545.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-931 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 557 0 R /Fit ] /Rect [ 56.69291 521.1969 538.5827 533.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-932 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 399 0 R /Fit ] /Rect [ 56.69291 509.1969 538.5827 521.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-933 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 835 0 R /Fit ] /Rect [ 56.69291 497.1969 538.5827 509.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-934 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 583 0 R /Fit ] /Rect [ 56.69291 485.1969 538.5827 497.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-935 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 596 0 R /Fit ] /Rect [ 56.69291 473.1969 538.5827 485.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-936 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 570 0 R /Fit ] /Rect [ 56.69291 461.1969 538.5827 473.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-937 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 254 0 R /Fit ] /Rect [ 56.69291 449.1969 538.5827 461.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-938 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 445 0 R /Fit ] /Rect [ 56.69291 437.1969 538.5827 449.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-939 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1067 0 R /Fit ] /Rect [ 56.69291 425.1969 538.5827 437.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-940 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 332 0 R /Fit ] /Rect [ 56.69291 413.1969 538.5827 425.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-941 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 200 0 R /Fit ] /Rect [ 56.69291 401.1969 538.5827 413.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-942 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 254 0 R /Fit ] /Rect [ 56.69291 389.1969 538.5827 401.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-943 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 254 0 R /Fit ] /Rect [ 56.69291 377.1969 538.5827 389.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-944 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 267 0 R /Fit ] /Rect [ 56.69291 365.1969 538.5827 377.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-945 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 254 0 R /Fit ] /Rect [ 56.69291 353.1969 538.5827 365.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-946 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 254 0 R /Fit ] /Rect [ 56.69291 341.1969 538.5827 353.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-947 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 267 0 R /Fit ] /Rect [ 56.69291 329.1969 538.5827 341.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-948 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 596 0 R /Fit ] /Rect [ 56.69291 317.1969 538.5827 329.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-949 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1052 0 R /Fit ] /Rect [ 56.69291 305.1969 538.5827 317.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-950 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 429 0 R /Fit ] /Rect [ 56.69291 293.1969 538.5827 305.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-951 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 956 0 R /Fit ] /Rect [ 56.69291 281.1969 538.5827 293.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-952 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/simple-layout.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 203.9469 228.6161 215.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-953 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 203.9469 297.6378 215.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-954 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 203.9469 323.1978 215.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-955 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 203.9469 323.1978 215.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-956 0 obj
-<< /Annots [ 910 0 R 911 0 R 912 0 R 913 0 R 914 0 R 915 0 R 916 0 R 917 0 R 918 0 R 919 0 R
- 920 0 R 921 0 R 922 0 R 923 0 R 924 0 R 925 0 R 926 0 R 927 0 R 928 0 R 929 0 R
- 930 0 R 931 0 R 932 0 R 933 0 R 934 0 R 935 0 R 936 0 R 937 0 R 938 0 R 939 0 R
- 940 0 R 941 0 R 942 0 R 943 0 R 944 0 R 945 0 R 946 0 R 947 0 R 948 0 R 949 0 R
- 950 0 R 951 0 R 952 0 R 953 0 R 954 0 R 955 0 R ] /Contents 1381 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-957 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-storyPlace.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 637.9469 233.0561 649.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-958 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-storyPlace.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 637.9469 297.6378 649.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-959 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-storyPlace.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 637.9469 323.1978 649.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-960 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-storyPlace.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 637.9469 323.1978 649.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-961 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 316.9469 238.6261 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-962 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 316.9469 297.6378 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-963 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 316.9469 323.1978 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-964 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 316.9469 323.1978 328.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-965 0 obj
-<< /Annots [ 957 0 R 958 0 R 959 0 R 960 0 R 961 0 R 962 0 R 963 0 R 964 0 R ] /Contents 1382 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-966 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 455 0 R /Fit ] /Rect [ 56.69291 132.1969 538.5827 144.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-967 0 obj
-<< /Annots [ 966 0 R ] /Contents 1383 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-968 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 734.9469 238.6261 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-969 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 734.9469 297.6378 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-970 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 734.9469 323.1978 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-971 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 734.9469 323.1978 746.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-972 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 965 0 R /Fit ] /Rect [ 56.69291 428.1969 538.5827 440.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-973 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-spiderChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 326.9469 238.6261 338.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-974 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 326.9469 297.6378 338.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-975 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 326.9469 323.1978 338.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-976 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-spiderChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 326.9469 323.1978 338.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-977 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-stroke.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 179.9469 214.7261 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-978 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-stroke.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 179.9469 297.6378 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-979 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-stroke.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 179.9469 323.1978 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-980 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-stroke.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 179.9469 323.1978 191.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-981 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 445 0 R /Fit ] /Rect [ 56.69291 98.19685 538.5827 110.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-982 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 689 0 R /Fit ] /Rect [ 56.69291 86.19685 538.5827 98.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-983 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 124 0 R /Fit ] /Rect [ 56.69291 74.19685 538.5827 86.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-984 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 557 0 R /Fit ] /Rect [ 56.69291 62.19685 538.5827 74.19685 ] /Subtype /Link /Type /Annot >>
-endobj
-985 0 obj
-<< /Annots [ 968 0 R 969 0 R 970 0 R 971 0 R 972 0 R 973 0 R 974 0 R 975 0 R 976 0 R 977 0 R
- 978 0 R 979 0 R 980 0 R 981 0 R 982 0 R 983 0 R 984 0 R ] /Contents 1384 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-986 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/simple-layout.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 717.9469 228.6161 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-987 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 717.9469 297.6378 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-988 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 717.9469 323.1978 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-989 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/simple-layout.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 717.9469 323.1978 729.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-990 0 obj
-<< /Annots [ 986 0 R 987 0 R 988 0 R 989 0 R ] /Contents 1385 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-991 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTable-1.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 308.9469 243.0561 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-992 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 308.9469 297.6378 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-993 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 308.9469 323.1978 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-994 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 308.9469 323.1978 320.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-995 0 obj
-<< /Annots [ 991 0 R 992 0 R 993 0 R 994 0 R ] /Contents 1386 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-996 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 683 0 R /Fit ] /Rect [ 56.69291 635.1969 538.5827 647.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-997 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-annotations.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 533.9469 277.2261 545.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-998 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 521.9469 297.6378 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-999 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 521.9469 323.1978 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1000 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-annotations.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 521.9469 323.1978 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1001 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-document-story.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 443.9469 252.4961 455.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1002 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 443.9469 297.6378 455.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1003 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 443.9469 323.1978 455.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1004 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-document-story.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 443.9469 323.1978 455.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1005 0 obj
-<< /Annots [ 996 0 R 997 0 R 998 0 R 999 0 R 1000 0 R 1001 0 R 1002 0 R 1003 0 R 1004 0 R ] /Contents 1387 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1006 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 758.9469 221.9561 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1007 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 297.6378 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1008 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1009 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 758.9469 323.1978 770.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1010 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 698 0 R /Fit ] /Rect [ 56.69291 626.1969 538.5827 638.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-1011 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-textAnnotation.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 488.9469 249.1761 500.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1012 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textAnnotation.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 488.9469 297.6378 500.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1013 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textAnnotation.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 488.9469 323.1978 500.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1014 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textAnnotation.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 488.9469 323.1978 500.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1015 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-textField.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 138.9469 225.8361 150.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1016 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 138.9469 297.6378 150.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1017 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 138.9469 323.1978 150.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1018 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 138.9469 323.1978 150.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1019 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-textField.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 96.94685 225.8361 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1020 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 96.94685 297.6378 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1021 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 96.94685 323.1978 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1022 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-textField.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 96.94685 323.1978 108.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1023 0 obj
-<< /Annots [ 1006 0 R 1007 0 R 1008 0 R 1009 0 R 1010 0 R 1011 0 R 1012 0 R 1013 0 R 1014 0 R 1015 0 R
- 1016 0 R 1017 0 R 1018 0 R 1019 0 R 1020 0 R 1021 0 R 1022 0 R ] /Contents 1388 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1024 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 1005 0 R /Fit ] /Rect [ 56.69291 734.1969 538.5827 746.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-1025 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 572.9469 221.9561 584.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1026 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 572.9469 297.6378 584.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1027 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 572.9469 323.1978 584.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1028 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 572.9469 323.1978 584.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1029 0 obj
-<< /Annots [ 1024 0 R 1025 0 R 1026 0 R 1027 0 R 1028 0 R ] /Contents 1389 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1030 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 279.9469 209.1761 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1031 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 279.9469 297.6378 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1032 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 279.9469 323.1978 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1033 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 279.9469 323.1978 291.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1034 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-cropMarks.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 249.9469 234.1661 261.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1035 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-cropMarks.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 249.9469 297.6378 261.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1036 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-cropMarks.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 249.9469 323.1978 261.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1037 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-cropMarks.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 249.9469 323.1978 261.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1038 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 990 0 R /Fit ] /Rect [ 56.69291 168.1969 538.5827 180.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-1039 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-blockTable-1.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 78.94685 243.0561 90.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-1040 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 78.94685 297.6378 90.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-1041 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 78.94685 323.1978 90.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-1042 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-blockTable-1.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 78.94685 323.1978 90.94685 ] /Subtype /Link /Type /Annot >>
-endobj
-1043 0 obj
-<< /Annots [ 1030 0 R 1031 0 R 1032 0 R 1033 0 R 1034 0 R 1035 0 R 1036 0 R 1037 0 R 1038 0 R 1039 0 R
- 1040 0 R 1041 0 R 1042 0 R ] /Contents 1390 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1044 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-transform.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 603.9469 229.7361 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1045 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-transform.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 603.9469 297.6378 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1046 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-transform.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 603.9469 323.1978 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1047 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-transform.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 603.9469 323.1978 615.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1048 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-translate.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 427.9469 225.8461 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1049 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-translate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 427.9469 297.6378 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1050 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-translate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 427.9469 323.1978 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1051 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-translate.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 427.9469 323.1978 439.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1052 0 obj
-<< /Annots [ 1044 0 R 1045 0 R 1046 0 R 1047 0 R 1048 0 R 1049 0 R 1050 0 R 1051 0 R ] /Contents 1391 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1053 0 obj
-<< /Border [ 0 0 0 ] /Contents () /Dest [ 487 0 R /Fit ] /Rect [ 56.69291 664.1969 538.5827 676.1969 ] /Subtype /Link /Type /Annot >>
-endobj
-1054 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-ul-ol-li.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 442.9469 218.0661 454.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1055 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 442.9469 297.6378 454.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1056 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 442.9469 323.1978 454.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1057 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-ul-ol-li.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 442.9469 323.1978 454.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1058 0 obj
-<< /Annots [ 1053 0 R 1054 0 R 1055 0 R 1056 0 R 1057 0 R ] /Contents 1392 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1059 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-barChart.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 265.9469 227.5161 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1060 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 265.9469 297.6378 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1061 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 265.9469 323.1978 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1062 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-barChart.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 265.9469 323.1978 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1063 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-log.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 118.9469 203.0661 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1064 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 118.9469 297.6378 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1065 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 118.9469 323.1978 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1066 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-log.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 118.9469 323.1978 130.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1067 0 obj
-<< /Annots [ 1059 0 R 1060 0 R 1061 0 R 1062 0 R 1063 0 R 1064 0 R 1065 0 R 1066 0 R ] /Contents 1393 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1068 0 obj
-<< /Contents 1394 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-1069 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 521.9469 221.9561 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1070 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 521.9469 297.6378 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1071 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 521.9469 323.1978 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1072 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 521.9469 323.1978 533.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1073 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-para.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 265.9469 209.1761 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1074 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 265.9469 297.6378 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1075 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 265.9469 323.1978 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1076 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-para.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 265.9469 323.1978 277.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1077 0 obj
-<< /Annots [ 1069 0 R 1070 0 R 1071 0 R 1072 0 R 1073 0 R 1074 0 R 1075 0 R 1076 0 R ] /Contents 1395 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1078 0 obj
-<< /Contents 1396 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
- /Type /Page >>
-endobj
-1079 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/input/tag-linePlot.rml) >> /Border [ 0 0 0 ] /Rect [ 150.2861 666.9469 221.9561 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1080 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 666.9469 297.6378 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1081 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 297.6378 666.9469 323.1978 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1082 0 obj
-<< /A << /S /URI /Type /Action /URI (https://github.com/zopefoundation/z3c.rml/blob/master/src/z3c/rml/tests/expected/tag-linePlot.pdf?raw=true) >> /Border [ 0 0 0 ] /Rect [ 323.1978 666.9469 323.1978 678.9469 ] /Subtype /Link /Type /Annot >>
-endobj
-1083 0 obj
-<< /Annots [ 1079 0 R 1080 0 R 1081 0 R 1082 0 R ] /Contents 1397 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 1293 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0
- /Trans << >> /Type /Page >>
-endobj
-1084 0 obj
-<< /Outlines 1086 0 R /PageMode /UseNone /Pages 1293 0 R /Type /Catalog >>
-endobj
-1085 0 obj
-<< /Author (\(anonymous\)) /CreationDate (D:20140910123008+05'00') /Creator (\(unspecified\)) /Keywords () /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\))
- /Title (\(anonymous\)) >>
-endobj
-1086 0 obj
-<< /Count 208 /First 1087 0 R /Last 1114 0 R /Type /Outlines >>
-endobj
-1087 0 obj
-<< /Count 26 /Dest [ 8 0 R /Fit ] /First 1088 0 R /Last 1113 0 R /Next 1114 0 R /Parent 1086 0 R
- /Title (Attribute Types) >>
-endobj
-1088 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1089 0 R /Parent 1087 0 R /Title (Boolean) >>
-endobj
-1089 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1090 0 R /Parent 1087 0 R /Prev 1088 0 R /Title (BooleanWithDefault) >>
-endobj
-1090 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1091 0 R /Parent 1087 0 R /Prev 1089 0 R /Title (Choice) >>
-endobj
-1091 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1092 0 R /Parent 1087 0 R /Prev 1090 0 R /Title (Color) >>
-endobj
-1092 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1093 0 R /Parent 1087 0 R /Prev 1091 0 R /Title (Combination) >>
-endobj
-1093 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1094 0 R /Parent 1087 0 R /Prev 1092 0 R /Title (File) >>
-endobj
-1094 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1095 0 R /Parent 1087 0 R /Prev 1093 0 R /Title (FirstLevelTextNode) >>
-endobj
-1095 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1096 0 R /Parent 1087 0 R /Prev 1094 0 R /Title (Float) >>
-endobj
-1096 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1097 0 R /Parent 1087 0 R /Prev 1095 0 R /Title (Image) >>
-endobj
-1097 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1098 0 R /Parent 1087 0 R /Prev 1096 0 R /Title (Integer) >>
-endobj
-1098 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1099 0 R /Parent 1087 0 R /Prev 1097 0 R /Title (IntegerSequence) >>
-endobj
-1099 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1100 0 R /Parent 1087 0 R /Prev 1098 0 R /Title (Measurement) >>
-endobj
-1100 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1101 0 R /Parent 1087 0 R /Prev 1099 0 R /Title (Padding) >>
-endobj
-1101 0 obj
-<< /Dest [ 8 0 R /Fit ] /Next 1102 0 R /Parent 1087 0 R /Prev 1100 0 R /Title (PageSize) >>
-endobj
-1102 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1103 0 R /Parent 1087 0 R /Prev 1101 0 R /Title (RawXMLContent) >>
-endobj
-1103 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1104 0 R /Parent 1087 0 R /Prev 1102 0 R /Title (Sequence) >>
-endobj
-1104 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1105 0 R /Parent 1087 0 R /Prev 1103 0 R /Title (String) >>
-endobj
-1105 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1106 0 R /Parent 1087 0 R /Prev 1104 0 R /Title (StringOrInt) >>
-endobj
-1106 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1107 0 R /Parent 1087 0 R /Prev 1105 0 R /Title (Style) >>
-endobj
-1107 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1108 0 R /Parent 1087 0 R /Prev 1106 0 R /Title (Symbol) >>
-endobj
-1108 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1109 0 R /Parent 1087 0 R /Prev 1107 0 R /Title (Text) >>
-endobj
-1109 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1110 0 R /Parent 1087 0 R /Prev 1108 0 R /Title (TextBoolean) >>
-endobj
-1110 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1111 0 R /Parent 1087 0 R /Prev 1109 0 R /Title (TextNode) >>
-endobj
-1111 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1112 0 R /Parent 1087 0 R /Prev 1110 0 R /Title (TextNodeGrid) >>
-endobj
-1112 0 obj
-<< /Dest [ 9 0 R /Fit ] /Next 1113 0 R /Parent 1087 0 R /Prev 1111 0 R /Title (TextNodeSequence) >>
-endobj
-1113 0 obj
-<< /Dest [ 9 0 R /Fit ] /Parent 1087 0 R /Prev 1112 0 R /Title (XMLContent) >>
-endobj
-1114 0 obj
-<< /Count 178 /Dest [ 25 0 R /Fit ] /First 1115 0 R /Last 1292 0 R /Parent 1086 0 R /Prev 1087 0 R
- /Title (Directives) >>
-endobj
-1115 0 obj
-<< /Dest [ 25 0 R /Fit ] /Next 1116 0 R /Parent 1114 0 R /Title (addMapping) >>
-endobj
-1116 0 obj
-<< /Dest [ 25 0 R /Fit ] /Next 1117 0 R /Parent 1114 0 R /Prev 1115 0 R /Title (alias) >>
-endobj
-1117 0 obj
-<< /Dest [ 25 0 R /Fit ] /Next 1118 0 R /Parent 1114 0 R /Prev 1116 0 R /Title (bar) >>
-endobj
-1118 0 obj
-<< /Dest [ 25 0 R /Fit ] /Next 1119 0 R /Parent 1114 0 R /Prev 1117 0 R /Title (barChart) >>
-endobj
-1119 0 obj
-<< /Dest [ 37 0 R /Fit ] /Next 1120 0 R /Parent 1114 0 R /Prev 1118 0 R /Title (barChart3D) >>
-endobj
-1120 0 obj
-<< /Dest [ 48 0 R /Fit ] /Next 1121 0 R /Parent 1114 0 R /Prev 1119 0 R /Title (barCode) >>
-endobj
-1121 0 obj
-<< /Dest [ 58 0 R /Fit ] /Next 1122 0 R /Parent 1114 0 R /Prev 1120 0 R /Title (barCodeFlowable) >>
-endobj
-1122 0 obj
-<< /Dest [ 67 0 R /Fit ] /Next 1123 0 R /Parent 1114 0 R /Prev 1121 0 R /Title (barLabels) >>
-endobj
-1123 0 obj
-<< /Dest [ 69 0 R /Fit ] /Next 1124 0 R /Parent 1114 0 R /Prev 1122 0 R /Title (bars) >>
-endobj
-1124 0 obj
-<< /Dest [ 79 0 R /Fit ] /Next 1125 0 R /Parent 1114 0 R /Prev 1123 0 R /Title (blockAlignment) >>
-endobj
-1125 0 obj
-<< /Dest [ 79 0 R /Fit ] /Next 1126 0 R /Parent 1114 0 R /Prev 1124 0 R /Title (blockBackground) >>
-endobj
-1126 0 obj
-<< /Dest [ 79 0 R /Fit ] /Next 1127 0 R /Parent 1114 0 R /Prev 1125 0 R /Title (blockBottomPadding) >>
-endobj
-1127 0 obj
-<< /Dest [ 92 0 R /Fit ] /Next 1128 0 R /Parent 1114 0 R /Prev 1126 0 R /Title (blockColBackground) >>
-endobj
-1128 0 obj
-<< /Dest [ 92 0 R /Fit ] /Next 1129 0 R /Parent 1114 0 R /Prev 1127 0 R /Title (blockFont) >>
-endobj
-1129 0 obj
-<< /Dest [ 92 0 R /Fit ] /Next 1130 0 R /Parent 1114 0 R /Prev 1128 0 R /Title (blockLeading) >>
-endobj
-1130 0 obj
-<< /Dest [ 109 0 R /Fit ] /Next 1131 0 R /Parent 1114 0 R /Prev 1129 0 R /Title (blockLeftPadding) >>
-endobj
-1131 0 obj
-<< /Dest [ 109 0 R /Fit ] /Next 1132 0 R /Parent 1114 0 R /Prev 1130 0 R /Title (blockRightPadding) >>
-endobj
-1132 0 obj
-<< /Dest [ 109 0 R /Fit ] /Next 1133 0 R /Parent 1114 0 R /Prev 1131 0 R /Title (blockRowBackground) >>
-endobj
-1133 0 obj
-<< /Dest [ 109 0 R /Fit ] /Next 1134 0 R /Parent 1114 0 R /Prev 1132 0 R /Title (blockSpan) >>
-endobj
-1134 0 obj
-<< /Dest [ 124 0 R /Fit ] /Next 1135 0 R /Parent 1114 0 R /Prev 1133 0 R /Title (blockTable) >>
-endobj
-1135 0 obj
-<< /Dest [ 124 0 R /Fit ] /Next 1136 0 R /Parent 1114 0 R /Prev 1134 0 R /Title (blockTableStyle) >>
-endobj
-1136 0 obj
-<< /Dest [ 148 0 R /Fit ] /Next 1137 0 R /Parent 1114 0 R /Prev 1135 0 R /Title (blockTextColor) >>
-endobj
-1137 0 obj
-<< /Dest [ 148 0 R /Fit ] /Next 1138 0 R /Parent 1114 0 R /Prev 1136 0 R /Title (blockTopPadding) >>
-endobj
-1138 0 obj
-<< /Dest [ 148 0 R /Fit ] /Next 1139 0 R /Parent 1114 0 R /Prev 1137 0 R /Title (blockValign) >>
-endobj
-1139 0 obj
-<< /Dest [ 153 0 R /Fit ] /Next 1140 0 R /Parent 1114 0 R /Prev 1138 0 R /Title (bookmark) >>
-endobj
-1140 0 obj
-<< /Dest [ 153 0 R /Fit ] /Next 1141 0 R /Parent 1114 0 R /Prev 1139 0 R /Title (bookmark) >>
-endobj
-1141 0 obj
-<< /Dest [ 153 0 R /Fit ] /Next 1142 0 R /Parent 1114 0 R /Prev 1140 0 R /Title (bookmarkPage) >>
-endobj
-1142 0 obj
-<< /Dest [ 166 0 R /Fit ] /Next 1143 0 R /Parent 1114 0 R /Prev 1141 0 R /Title (bulkData) >>
-endobj
-1143 0 obj
-<< /Dest [ 166 0 R /Fit ] /Next 1144 0 R /Parent 1114 0 R /Prev 1142 0 R /Title (buttonField) >>
-endobj
-1144 0 obj
-<< /Dest [ 166 0 R /Fit ] /Next 1145 0 R /Parent 1114 0 R /Prev 1143 0 R /Title (categoryAxis) >>
-endobj
-1145 0 obj
-<< /Dest [ 183 0 R /Fit ] /Next 1146 0 R /Parent 1114 0 R /Prev 1144 0 R /Title (categoryNames) >>
-endobj
-1146 0 obj
-<< /Dest [ 183 0 R /Fit ] /Next 1147 0 R /Parent 1114 0 R /Prev 1145 0 R /Title (circle) >>
-endobj
-1147 0 obj
-<< /Dest [ 183 0 R /Fit ] /Next 1148 0 R /Parent 1114 0 R /Prev 1146 0 R /Title (codesnippet) >>
-endobj
-1148 0 obj
-<< /Dest [ 200 0 R /Fit ] /Next 1149 0 R /Parent 1114 0 R /Prev 1147 0 R /Title (color) >>
-endobj
-1149 0 obj
-<< /Dest [ 200 0 R /Fit ] /Next 1150 0 R /Parent 1114 0 R /Prev 1148 0 R /Title (condPageBreak) >>
-endobj
-1150 0 obj
-<< /Dest [ 200 0 R /Fit ] /Next 1151 0 R /Parent 1114 0 R /Prev 1149 0 R /Title (critical) >>
-endobj
-1151 0 obj
-<< /Dest [ 213 0 R /Fit ] /Next 1152 0 R /Parent 1114 0 R /Prev 1150 0 R /Title (cropMarks) >>
-endobj
-1152 0 obj
-<< /Dest [ 213 0 R /Fit ] /Next 1153 0 R /Parent 1114 0 R /Prev 1151 0 R /Title (curves) >>
-endobj
-1153 0 obj
-<< /Dest [ 213 0 R /Fit ] /Next 1154 0 R /Parent 1114 0 R /Prev 1152 0 R /Title (curvesto) >>
-endobj
-1154 0 obj
-<< /Dest [ 229 0 R /Fit ] /Next 1155 0 R /Parent 1114 0 R /Prev 1153 0 R /Title (curveto) >>
-endobj
-1155 0 obj
-<< /Dest [ 229 0 R /Fit ] /Next 1156 0 R /Parent 1114 0 R /Prev 1154 0 R /Title (data) >>
-endobj
-1156 0 obj
-<< /Dest [ 229 0 R /Fit ] /Next 1157 0 R /Parent 1114 0 R /Prev 1155 0 R /Title (data) >>
-endobj
-1157 0 obj
-<< /Dest [ 229 0 R /Fit ] /Next 1158 0 R /Parent 1114 0 R /Prev 1156 0 R /Title (data) >>
-endobj
-1158 0 obj
-<< /Dest [ 254 0 R /Fit ] /Next 1159 0 R /Parent 1114 0 R /Prev 1157 0 R /Title (debug) >>
-endobj
-1159 0 obj
-<< /Dest [ 254 0 R /Fit ] /Next 1160 0 R /Parent 1114 0 R /Prev 1158 0 R /Title (docAssign) >>
-endobj
-1160 0 obj
-<< /Dest [ 254 0 R /Fit ] /Next 1161 0 R /Parent 1114 0 R /Prev 1159 0 R /Title (docElse) >>
-endobj
-1161 0 obj
-<< /Dest [ 254 0 R /Fit ] /Next 1162 0 R /Parent 1114 0 R /Prev 1160 0 R /Title (docExec) >>
-endobj
-1162 0 obj
-<< /Dest [ 254 0 R /Fit ] /Next 1163 0 R /Parent 1114 0 R /Prev 1161 0 R /Title (docIf) >>
-endobj
-1163 0 obj
-<< /Dest [ 267 0 R /Fit ] /Next 1164 0 R /Parent 1114 0 R /Prev 1162 0 R /Title (docPara) >>
-endobj
-1164 0 obj
-<< /Dest [ 267 0 R /Fit ] /Next 1165 0 R /Parent 1114 0 R /Prev 1163 0 R /Title (docWhile) >>
-endobj
-1165 0 obj
-<< /Dest [ 267 0 R /Fit ] /Next 1166 0 R /Parent 1114 0 R /Prev 1164 0 R /Title (docinit) >>
-endobj
-1166 0 obj
-<< /Dest [ 302 0 R /Fit ] /Next 1167 0 R /Parent 1114 0 R /Prev 1165 0 R /Title (document) >>
-endobj
-1167 0 obj
-<< /Dest [ 319 0 R /Fit ] /Next 1168 0 R /Parent 1114 0 R /Prev 1166 0 R /Title (drawAlignedString) >>
-endobj
-1168 0 obj
-<< /Dest [ 319 0 R /Fit ] /Next 1169 0 R /Parent 1114 0 R /Prev 1167 0 R /Title (drawCenteredString) >>
-endobj
-1169 0 obj
-<< /Dest [ 319 0 R /Fit ] /Next 1170 0 R /Parent 1114 0 R /Prev 1168 0 R /Title (drawRightString) >>
-endobj
-1170 0 obj
-<< /Dest [ 332 0 R /Fit ] /Next 1171 0 R /Parent 1114 0 R /Prev 1169 0 R /Title (drawString) >>
-endobj
-1171 0 obj
-<< /Dest [ 332 0 R /Fit ] /Next 1172 0 R /Parent 1114 0 R /Prev 1170 0 R /Title (ellipse) >>
-endobj
-1172 0 obj
-<< /Dest [ 332 0 R /Fit ] /Next 1173 0 R /Parent 1114 0 R /Prev 1171 0 R /Title (error) >>
-endobj
-1173 0 obj
-<< /Dest [ 345 0 R /Fit ] /Next 1174 0 R /Parent 1114 0 R /Prev 1172 0 R /Title (fill) >>
-endobj
-1174 0 obj
-<< /Dest [ 345 0 R /Fit ] /Next 1175 0 R /Parent 1114 0 R /Prev 1173 0 R /Title (fixedSize) >>
-endobj
-1175 0 obj
-<< /Dest [ 345 0 R /Fit ] /Next 1176 0 R /Parent 1114 0 R /Prev 1174 0 R /Title (frame) >>
-endobj
-1176 0 obj
-<< /Dest [ 358 0 R /Fit ] /Next 1177 0 R /Parent 1114 0 R /Prev 1175 0 R /Title (grid) >>
-endobj
-1177 0 obj
-<< /Dest [ 358 0 R /Fit ] /Next 1178 0 R /Parent 1114 0 R /Prev 1176 0 R /Title (h1) >>
-endobj
-1178 0 obj
-<< /Dest [ 364 0 R /Fit ] /Next 1179 0 R /Parent 1114 0 R /Prev 1177 0 R /Title (h2) >>
-endobj
-1179 0 obj
-<< /Dest [ 369 0 R /Fit ] /Next 1180 0 R /Parent 1114 0 R /Prev 1178 0 R /Title (h3) >>
-endobj
-1180 0 obj
-<< /Dest [ 374 0 R /Fit ] /Next 1181 0 R /Parent 1114 0 R /Prev 1179 0 R /Title (h4) >>
-endobj
-1181 0 obj
-<< /Dest [ 380 0 R /Fit ] /Next 1182 0 R /Parent 1114 0 R /Prev 1180 0 R /Title (h5) >>
-endobj
-1182 0 obj
-<< /Dest [ 385 0 R /Fit ] /Next 1183 0 R /Parent 1114 0 R /Prev 1181 0 R /Title (h6) >>
-endobj
-1183 0 obj
-<< /Dest [ 399 0 R /Fit ] /Next 1184 0 R /Parent 1114 0 R /Prev 1182 0 R /Title (hr) >>
-endobj
-1184 0 obj
-<< /Dest [ 399 0 R /Fit ] /Next 1185 0 R /Parent 1114 0 R /Prev 1183 0 R /Title (illustration) >>
-endobj
-1185 0 obj
-<< /Dest [ 399 0 R /Fit ] /Next 1186 0 R /Parent 1114 0 R /Prev 1184 0 R /Title (image) >>
-endobj
-1186 0 obj
-<< /Dest [ 404 0 R /Fit ] /Next 1187 0 R /Parent 1114 0 R /Prev 1185 0 R /Title (imageAndFlowables) >>
-endobj
-1187 0 obj
-<< /Dest [ 429 0 R /Fit ] /Next 1188 0 R /Parent 1114 0 R /Prev 1186 0 R /Title (img) >>
-endobj
-1188 0 obj
-<< /Dest [ 429 0 R /Fit ] /Next 1189 0 R /Parent 1114 0 R /Prev 1187 0 R /Title (includePdfPages) >>
-endobj
-1189 0 obj
-<< /Dest [ 429 0 R /Fit ] /Next 1190 0 R /Parent 1114 0 R /Prev 1188 0 R /Title (indent) >>
-endobj
-1190 0 obj
-<< /Dest [ 445 0 R /Fit ] /Next 1191 0 R /Parent 1114 0 R /Prev 1189 0 R /Title (info) >>
-endobj
-1191 0 obj
-<< /Dest [ 445 0 R /Fit ] /Next 1192 0 R /Parent 1114 0 R /Prev 1190 0 R /Title (initialize) >>
-endobj
-1192 0 obj
-<< /Dest [ 445 0 R /Fit ] /Next 1193 0 R /Parent 1114 0 R /Prev 1191 0 R /Title (keepInFrame) >>
-endobj
-1193 0 obj
-<< /Dest [ 450 0 R /Fit ] /Next 1194 0 R /Parent 1114 0 R /Prev 1192 0 R /Title (keepTogether) >>
-endobj
-1194 0 obj
-<< /Dest [ 455 0 R /Fit ] /Next 1195 0 R /Parent 1114 0 R /Prev 1193 0 R /Title (label) >>
-endobj
-1195 0 obj
-<< /Dest [ 460 0 R /Fit ] /Next 1196 0 R /Parent 1114 0 R /Prev 1194 0 R /Title (label) >>
-endobj
-1196 0 obj
-<< /Dest [ 465 0 R /Fit ] /Next 1197 0 R /Parent 1114 0 R /Prev 1195 0 R /Title (label) >>
-endobj
-1197 0 obj
-<< /Dest [ 474 0 R /Fit ] /Next 1198 0 R /Parent 1114 0 R /Prev 1196 0 R /Title (label) >>
-endobj
-1198 0 obj
-<< /Dest [ 474 0 R /Fit ] /Next 1199 0 R /Parent 1114 0 R /Prev 1197 0 R /Title (label) >>
-endobj
-1199 0 obj
-<< /Dest [ 476 0 R /Fit ] /Next 1200 0 R /Parent 1114 0 R /Prev 1198 0 R /Title (labels) >>
-endobj
-1200 0 obj
-<< /Dest [ 487 0 R /Fit ] /Next 1201 0 R /Parent 1114 0 R /Prev 1199 0 R /Title (labels) >>
-endobj
-1201 0 obj
-<< /Dest [ 487 0 R /Fit ] /Next 1202 0 R /Parent 1114 0 R /Prev 1200 0 R /Title (li) >>
-endobj
-1202 0 obj
-<< /Dest [ 496 0 R /Fit ] /Next 1203 0 R /Parent 1114 0 R /Prev 1201 0 R /Title (li) >>
-endobj
-1203 0 obj
-<< /Dest [ 496 0 R /Fit ] /Next 1204 0 R /Parent 1114 0 R /Prev 1202 0 R /Title (line) >>
-endobj
-1204 0 obj
-<< /Dest [ 501 0 R /Fit ] /Next 1205 0 R /Parent 1114 0 R /Prev 1203 0 R /Title (lineLabels) >>
-endobj
-1205 0 obj
-<< /Dest [ 511 0 R /Fit ] /Next 1206 0 R /Parent 1114 0 R /Prev 1204 0 R /Title (lineMode) >>
-endobj
-1206 0 obj
-<< /Dest [ 511 0 R /Fit ] /Next 1207 0 R /Parent 1114 0 R /Prev 1205 0 R /Title (linePlot) >>
-endobj
-1207 0 obj
-<< /Dest [ 523 0 R /Fit ] /Next 1208 0 R /Parent 1114 0 R /Prev 1206 0 R /Title (linePlot3D) >>
-endobj
-1208 0 obj
-<< /Dest [ 543 0 R /Fit ] /Next 1209 0 R /Parent 1114 0 R /Prev 1207 0 R /Title (lineStyle) >>
-endobj
-1209 0 obj
-<< /Dest [ 543 0 R /Fit ] /Next 1210 0 R /Parent 1114 0 R /Prev 1208 0 R /Title (lines) >>
-endobj
-1210 0 obj
-<< /Dest [ 543 0 R /Fit ] /Next 1211 0 R /Parent 1114 0 R /Prev 1209 0 R /Title (lines) >>
-endobj
-1211 0 obj
-<< /Dest [ 557 0 R /Fit ] /Next 1212 0 R /Parent 1114 0 R /Prev 1210 0 R /Title (link) >>
-endobj
-1212 0 obj
-<< /Dest [ 557 0 R /Fit ] /Next 1213 0 R /Parent 1114 0 R /Prev 1211 0 R /Title (listStyle) >>
-endobj
-1213 0 obj
-<< /Dest [ 570 0 R /Fit ] /Next 1214 0 R /Parent 1114 0 R /Prev 1212 0 R /Title (log) >>
-endobj
-1214 0 obj
-<< /Dest [ 570 0 R /Fit ] /Next 1215 0 R /Parent 1114 0 R /Prev 1213 0 R /Title (logConfig) >>
-endobj
-1215 0 obj
-<< /Dest [ 583 0 R /Fit ] /Next 1216 0 R /Parent 1114 0 R /Prev 1214 0 R /Title (mergePage) >>
-endobj
-1216 0 obj
-<< /Dest [ 583 0 R /Fit ] /Next 1217 0 R /Parent 1114 0 R /Prev 1215 0 R /Title (moveto) >>
-endobj
-1217 0 obj
-<< /Dest [ 583 0 R /Fit ] /Next 1218 0 R /Parent 1114 0 R /Prev 1216 0 R /Title (name) >>
-endobj
-1218 0 obj
-<< /Dest [ 583 0 R /Fit ] /Next 1219 0 R /Parent 1114 0 R /Prev 1217 0 R /Title (name) >>
-endobj
-1219 0 obj
-<< /Dest [ 596 0 R /Fit ] /Next 1220 0 R /Parent 1114 0 R /Prev 1218 0 R /Title (namedString) >>
-endobj
-1220 0 obj
-<< /Dest [ 596 0 R /Fit ] /Next 1221 0 R /Parent 1114 0 R /Prev 1219 0 R /Title (nextFrame) >>
-endobj
-1221 0 obj
-<< /Dest [ 596 0 R /Fit ] /Next 1222 0 R /Parent 1114 0 R /Prev 1220 0 R /Title (nextPage) >>
-endobj
-1222 0 obj
-<< /Dest [ 596 0 R /Fit ] /Next 1223 0 R /Parent 1114 0 R /Prev 1221 0 R /Title (ol) >>
-endobj
-1223 0 obj
-<< /Dest [ 614 0 R /Fit ] /Next 1224 0 R /Parent 1114 0 R /Prev 1222 0 R /Title (option) >>
-endobj
-1224 0 obj
-<< /Dest [ 614 0 R /Fit ] /Next 1225 0 R /Parent 1114 0 R /Prev 1223 0 R /Title (outlineAdd) >>
-endobj
-1225 0 obj
-<< /Dest [ 614 0 R /Fit ] /Next 1226 0 R /Parent 1114 0 R /Prev 1224 0 R /Title (pageDrawing) >>
-endobj
-1226 0 obj
-<< /Dest [ 659 0 R /Fit ] /Next 1227 0 R /Parent 1114 0 R /Prev 1225 0 R /Title (pageGraphics) >>
-endobj
-1227 0 obj
-<< /Dest [ 683 0 R /Fit ] /Next 1228 0 R /Parent 1114 0 R /Prev 1226 0 R /Title (pageInfo) >>
-endobj
-1228 0 obj
-<< /Dest [ 683 0 R /Fit ] /Next 1229 0 R /Parent 1114 0 R /Prev 1227 0 R /Title (pageTemplate) >>
-endobj
-1229 0 obj
-<< /Dest [ 683 0 R /Fit ] /Next 1230 0 R /Parent 1114 0 R /Prev 1228 0 R /Title (para) >>
-endobj
-1230 0 obj
-<< /Dest [ 689 0 R /Fit ] /Next 1231 0 R /Parent 1114 0 R /Prev 1229 0 R /Title (paraStyle) >>
-endobj
-1231 0 obj
-<< /Dest [ 698 0 R /Fit ] /Next 1232 0 R /Parent 1114 0 R /Prev 1230 0 R /Title (param) >>
-endobj
-1232 0 obj
-<< /Dest [ 698 0 R /Fit ] /Next 1233 0 R /Parent 1114 0 R /Prev 1231 0 R /Title (path) >>
-endobj
-1233 0 obj
-<< /Dest [ 710 0 R /Fit ] /Next 1234 0 R /Parent 1114 0 R /Prev 1232 0 R /Title (pieChart) >>
-endobj
-1234 0 obj
-<< /Dest [ 720 0 R /Fit ] /Next 1235 0 R /Parent 1114 0 R /Prev 1233 0 R /Title (pieChart3D) >>
-endobj
-1235 0 obj
-<< /Dest [ 731 0 R /Fit ] /Next 1236 0 R /Parent 1114 0 R /Prev 1234 0 R /Title (place) >>
-endobj
-1236 0 obj
-<< /Dest [ 740 0 R /Fit ] /Next 1237 0 R /Parent 1114 0 R /Prev 1235 0 R /Title (plugInFlowable) >>
-endobj
-1237 0 obj
-<< /Dest [ 740 0 R /Fit ] /Next 1238 0 R /Parent 1114 0 R /Prev 1236 0 R /Title (plugInGraphic) >>
-endobj
-1238 0 obj
-<< /Dest [ 740 0 R /Fit ] /Next 1239 0 R /Parent 1114 0 R /Prev 1237 0 R /Title (pointer) >>
-endobj
-1239 0 obj
-<< /Dest [ 753 0 R /Fit ] /Next 1240 0 R /Parent 1114 0 R /Prev 1238 0 R /Title (pre) >>
-endobj
-1240 0 obj
-<< /Dest [ 753 0 R /Fit ] /Next 1241 0 R /Parent 1114 0 R /Prev 1239 0 R /Title (pto) >>
-endobj
-1241 0 obj
-<< /Dest [ 753 0 R /Fit ] /Next 1242 0 R /Parent 1114 0 R /Prev 1240 0 R /Title (rect) >>
-endobj
-1242 0 obj
-<< /Dest [ 766 0 R /Fit ] /Next 1243 0 R /Parent 1114 0 R /Prev 1241 0 R /Title (registerCidFont) >>
-endobj
-1243 0 obj
-<< /Dest [ 766 0 R /Fit ] /Next 1244 0 R /Parent 1114 0 R /Prev 1242 0 R /Title (registerFont) >>
-endobj
-1244 0 obj
-<< /Dest [ 783 0 R /Fit ] /Next 1245 0 R /Parent 1114 0 R /Prev 1243 0 R /Title (registerFontFamily) >>
-endobj
-1245 0 obj
-<< /Dest [ 783 0 R /Fit ] /Next 1246 0 R /Parent 1114 0 R /Prev 1244 0 R /Title (registerTTFont) >>
-endobj
-1246 0 obj
-<< /Dest [ 783 0 R /Fit ] /Next 1247 0 R /Parent 1114 0 R /Prev 1245 0 R /Title (registerType1Face) >>
-endobj
-1247 0 obj
-<< /Dest [ 783 0 R /Fit ] /Next 1248 0 R /Parent 1114 0 R /Prev 1246 0 R /Title (restoreState) >>
-endobj
-1248 0 obj
-<< /Dest [ 800 0 R /Fit ] /Next 1249 0 R /Parent 1114 0 R /Prev 1247 0 R /Title (rotate) >>
-endobj
-1249 0 obj
-<< /Dest [ 800 0 R /Fit ] /Next 1250 0 R /Parent 1114 0 R /Prev 1248 0 R /Title (saveState) >>
-endobj
-1250 0 obj
-<< /Dest [ 800 0 R /Fit ] /Next 1251 0 R /Parent 1114 0 R /Prev 1249 0 R /Title (scale) >>
-endobj
-1251 0 obj
-<< /Dest [ 800 0 R /Fit ] /Next 1252 0 R /Parent 1114 0 R /Prev 1250 0 R /Title (selectField) >>
-endobj
-1252 0 obj
-<< /Dest [ 814 0 R /Fit ] /Next 1253 0 R /Parent 1114 0 R /Prev 1251 0 R /Title (series) >>
-endobj
-1253 0 obj
-<< /Dest [ 814 0 R /Fit ] /Next 1254 0 R /Parent 1114 0 R /Prev 1252 0 R /Title (series) >>
-endobj
-1254 0 obj
-<< /Dest [ 814 0 R /Fit ] /Next 1255 0 R /Parent 1114 0 R /Prev 1253 0 R /Title (setFont) >>
-endobj
-1255 0 obj
-<< /Dest [ 835 0 R /Fit ] /Next 1256 0 R /Parent 1114 0 R /Prev 1254 0 R /Title (setFontSize) >>
-endobj
-1256 0 obj
-<< /Dest [ 835 0 R /Fit ] /Next 1257 0 R /Parent 1114 0 R /Prev 1255 0 R /Title (setNextFrame) >>
-endobj
-1257 0 obj
-<< /Dest [ 835 0 R /Fit ] /Next 1258 0 R /Parent 1114 0 R /Prev 1256 0 R /Title (setNextTemplate) >>
-endobj
-1258 0 obj
-<< /Dest [ 835 0 R /Fit ] /Next 1259 0 R /Parent 1114 0 R /Prev 1257 0 R /Title (showIndex) >>
-endobj
-1259 0 obj
-<< /Dest [ 850 0 R /Fit ] /Next 1260 0 R /Parent 1114 0 R /Prev 1258 0 R /Title (skew) >>
-endobj
-1260 0 obj
-<< /Dest [ 850 0 R /Fit ] /Next 1261 0 R /Parent 1114 0 R /Prev 1259 0 R /Title (slice) >>
-endobj
-1261 0 obj
-<< /Dest [ 850 0 R /Fit ] /Next 1262 0 R /Parent 1114 0 R /Prev 1260 0 R /Title (slice) >>
-endobj
-1262 0 obj
-<< /Dest [ 856 0 R /Fit ] /Next 1263 0 R /Parent 1114 0 R /Prev 1261 0 R /Title (slices) >>
-endobj
-1263 0 obj
-<< /Dest [ 866 0 R /Fit ] /Next 1264 0 R /Parent 1114 0 R /Prev 1262 0 R /Title (slices) >>
-endobj
-1264 0 obj
-<< /Dest [ 866 0 R /Fit ] /Next 1265 0 R /Parent 1114 0 R /Prev 1263 0 R /Title (spacer) >>
-endobj
-1265 0 obj
-<< /Dest [ 878 0 R /Fit ] /Next 1266 0 R /Parent 1114 0 R /Prev 1264 0 R /Title (spiderChart) >>
-endobj
-1266 0 obj
-<< /Dest [ 883 0 R /Fit ] /Next 1267 0 R /Parent 1114 0 R /Prev 1265 0 R /Title (spoke) >>
-endobj
-1267 0 obj
-<< /Dest [ 883 0 R /Fit ] /Next 1268 0 R /Parent 1114 0 R /Prev 1266 0 R /Title (spokeLabels) >>
-endobj
-1268 0 obj
-<< /Dest [ 889 0 R /Fit ] /Next 1269 0 R /Parent 1114 0 R /Prev 1267 0 R /Title (spokes) >>
-endobj
-1269 0 obj
-<< /Dest [ 909 0 R /Fit ] /Next 1270 0 R /Parent 1114 0 R /Prev 1268 0 R /Title (startIndex) >>
-endobj
-1270 0 obj
-<< /Dest [ 909 0 R /Fit ] /Next 1271 0 R /Parent 1114 0 R /Prev 1269 0 R /Title (story) >>
-endobj
-1271 0 obj
-<< /Dest [ 956 0 R /Fit ] /Next 1272 0 R /Parent 1114 0 R /Prev 1270 0 R /Title (storyPlace) >>
-endobj
-1272 0 obj
-<< /Dest [ 965 0 R /Fit ] /Next 1273 0 R /Parent 1114 0 R /Prev 1271 0 R /Title (strand) >>
-endobj
-1273 0 obj
-<< /Dest [ 965 0 R /Fit ] /Next 1274 0 R /Parent 1114 0 R /Prev 1272 0 R /Title (strandLabels) >>
-endobj
-1274 0 obj
-<< /Dest [ 985 0 R /Fit ] /Next 1275 0 R /Parent 1114 0 R /Prev 1273 0 R /Title (strands) >>
-endobj
-1275 0 obj
-<< /Dest [ 985 0 R /Fit ] /Next 1276 0 R /Parent 1114 0 R /Prev 1274 0 R /Title (stroke) >>
-endobj
-1276 0 obj
-<< /Dest [ 985 0 R /Fit ] /Next 1277 0 R /Parent 1114 0 R /Prev 1275 0 R /Title (stylesheet) >>
-endobj
-1277 0 obj
-<< /Dest [ 990 0 R /Fit ] /Next 1278 0 R /Parent 1114 0 R /Prev 1276 0 R /Title (td) >>
-endobj
-1278 0 obj
-<< /Dest [ 995 0 R /Fit ] /Next 1279 0 R /Parent 1114 0 R /Prev 1277 0 R /Title (template) >>
-endobj
-1279 0 obj
-<< /Dest [ 1005 0 R /Fit ] /Next 1280 0 R /Parent 1114 0 R /Prev 1278 0 R /Title (text) >>
-endobj
-1280 0 obj
-<< /Dest [ 1023 0 R /Fit ] /Next 1281 0 R /Parent 1114 0 R /Prev 1279 0 R /Title (textAnnotation) >>
-endobj
-1281 0 obj
-<< /Dest [ 1023 0 R /Fit ] /Next 1282 0 R /Parent 1114 0 R /Prev 1280 0 R /Title (textField) >>
-endobj
-1282 0 obj
-<< /Dest [ 1023 0 R /Fit ] /Next 1283 0 R /Parent 1114 0 R /Prev 1281 0 R /Title (texts) >>
-endobj
-1283 0 obj
-<< /Dest [ 1029 0 R /Fit ] /Next 1284 0 R /Parent 1114 0 R /Prev 1282 0 R /Title (title) >>
-endobj
-1284 0 obj
-<< /Dest [ 1043 0 R /Fit ] /Next 1285 0 R /Parent 1114 0 R /Prev 1283 0 R /Title (tr) >>
-endobj
-1285 0 obj
-<< /Dest [ 1052 0 R /Fit ] /Next 1286 0 R /Parent 1114 0 R /Prev 1284 0 R /Title (transform) >>
-endobj
-1286 0 obj
-<< /Dest [ 1052 0 R /Fit ] /Next 1287 0 R /Parent 1114 0 R /Prev 1285 0 R /Title (translate) >>
-endobj
-1287 0 obj
-<< /Dest [ 1052 0 R /Fit ] /Next 1288 0 R /Parent 1114 0 R /Prev 1286 0 R /Title (ul) >>
-endobj
-1288 0 obj
-<< /Dest [ 1058 0 R /Fit ] /Next 1289 0 R /Parent 1114 0 R /Prev 1287 0 R /Title (valueAxis) >>
-endobj
-1289 0 obj
-<< /Dest [ 1067 0 R /Fit ] /Next 1290 0 R /Parent 1114 0 R /Prev 1288 0 R /Title (warning) >>
-endobj
-1290 0 obj
-<< /Dest [ 1067 0 R /Fit ] /Next 1291 0 R /Parent 1114 0 R /Prev 1289 0 R /Title (xValueAxis) >>
-endobj
-1291 0 obj
-<< /Dest [ 1077 0 R /Fit ] /Next 1292 0 R /Parent 1114 0 R /Prev 1290 0 R /Title (xpre) >>
-endobj
-1292 0 obj
-<< /Dest [ 1077 0 R /Fit ] /Parent 1114 0 R /Prev 1291 0 R /Title (yValueAxis) >>
-endobj
-1293 0 obj
-<< /Count 104 /Kids [ 3 0 R 6 0 R 8 0 R 9 0 R 25 0 R 32 0 R 37 0 R 48 0 R 49 0 R 58 0 R
- 67 0 R 69 0 R 79 0 R 92 0 R 109 0 R 124 0 R 148 0 R 153 0 R 166 0 R 173 0 R
- 183 0 R 200 0 R 213 0 R 229 0 R 254 0 R 267 0 R 287 0 R 302 0 R 319 0 R 332 0 R
- 345 0 R 358 0 R 359 0 R 364 0 R 369 0 R 374 0 R 375 0 R 380 0 R 385 0 R 386 0 R
- 399 0 R 404 0 R 429 0 R 445 0 R 450 0 R 455 0 R 460 0 R 465 0 R 474 0 R 475 0 R
- 476 0 R 487 0 R 496 0 R 501 0 R 511 0 R 518 0 R 523 0 R 534 0 R 543 0 R 557 0 R
- 570 0 R 583 0 R 596 0 R 614 0 R 659 0 R 683 0 R 684 0 R 689 0 R 698 0 R 710 0 R
- 715 0 R 720 0 R 731 0 R 740 0 R 753 0 R 766 0 R 783 0 R 800 0 R 814 0 R 835 0 R
- 850 0 R 856 0 R 866 0 R 878 0 R 883 0 R 889 0 R 909 0 R 956 0 R 965 0 R 967 0 R
- 985 0 R 990 0 R 995 0 R 1005 0 R 1023 0 R 1029 0 R 1043 0 R 1052 0 R 1058 0 R 1067 0 R
- 1068 0 R 1077 0 R 1078 0 R 1083 0 R ] /Type /Pages >>
-endobj
-1294 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 190 >>
-stream
-GarWrYmS?5%*%i9i83E3eKHj8?$fi\Sa'Sh^-K5\KiY:E:[b]ui#mS%J+=hC/.F8E*Is@5G[[gA40Tq7X`7BW?Il4&Kt7#BMQN_jWtRVk1(WkC6'YCX*O,G%/N),u:$gjRa#<@Z4nPs!c`4KXPsF;h.XBG^-W\Yg=lgFm*iJbm3C8OO_4*endstream
-endobj
-1295 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 722 >>
-stream
-Gasam?#SFN'R`L25Ffc2C9n+X.$'k+C.M%`W^tmFj4o/da3JK+`d[lhbu\+H$%Ynu+.mWB\L6IJiD6%oAIEl^;o(G=YUl?E_Ik@/>!Y5^6ns[$/h,e!Rp+"joT,;Xt2-c?F=CS?7,UPVqo,r^Q],$2mEPF)o6AHAUEjZI9a7VV(,rIU>?c#lN\;=p[nYTWnu"1?:i"Ar29rpLod6G=Jc'hni!Vfuo^Yu,c$mPnD?L&jKW9pqtP[0Yd5.W#[akbVij!<3TV(tAi4aPs,Cm/+AKL\aPd^Gnheb1iS($7tt&2=o6gQnAj'nE2+P8JNgT(P'Pj60/l0h:*Z>Om1&KAo_G=stsP9b=1Vn%6[4gK?@ul"7EjQ0gG)]';F.MSX+)4-6b/f+Ti-Wp/k3KAk`Q]n_),~>endstream
-endobj
-1296 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1620 >>
-stream
-Gau0D>u)\('R`L25@!;]fd_[!7g@DNYUunUTcXiFW_+AWjA+^:a.B\%,jDN$[3o=_#ik?O,![hlhs9c,Uc)JRDU#ME[@0>1(1FeWd(G.uB:+/2A,YOsY==H\+s))C(klKXCpH[AHYp'W0":q7\`HG8i5U@S+BXsRVukU0B`kcZ)&,^?#7eb?gb-,/U\AuAJ-&B.edTDRQsI[`@8&r"Z,%t1m[lMR_=P1i@7o^-Yet7Q">Uj^c=k_!:(i8V'?.-V5(TUY+a@Un`W=jS89Kn55sJtSk6?6\kcN7Z0.(>YMgE/q+YSLPiiJPL0O_3c@\t74os`[=lUg1RqJ(0r)T-Q=i.!,'r."sOKaj$1[[tq)L(D.ath=YkpGf_RnJ[NdcdP_"8g!Fa7@IM)@R^+2V2lE2/nsLg.#=flbA!Tt@8/31MV`R/V@eT8'R*F?)_M32-B6dQ3?8<(cB014"hN+B,o;03A8CSR?VloYSj&?F3RAf)et=G(F!]upp&NL#4W,OcU_U4o*MR21fo3O1TZ4M8Kj#nV,$g1q[Bsc38nD(khnu(8\lFAtD&:.JZ=)5'nB+3d%M^VHNb[7#DY&X9-Tb/%[0Ks.SdQJ/pUTdh@5cejki#pGJklGDj3-3hBcT!H3CEI-.+n-:crX)-h11AHh+sF/sph*!IKJW$>4Ug]l[!_+WFRb8rd/IE`Rhn*,FmQgU;GQJ:_CA\YhFIO[U_?/KN8na:Zq`IiNAX6Vc'IRiZm5g;a:="&Z]-gAM"?Q$B]3=cN5\+;G63q1Xkbhc5Y5I7WQro9NK8_0[)h,^B&XNm;n0>2T'IWL<5F$I1&Z))pmVW3F$n[Dsg`s;T>@.@T0*Q1#43C=^LcdC'Y$nj,G1$-+b#oTn8%^T`CfcWbt`_c@2pnc]tc*aSG+#c"iel4AAK"Hs.\F+9p]-[;a8+VGHZ;&b2SW'E=eTVL)i1,X*c2pa:rWQ*9*7+~>endstream
-endobj
-1297 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1134 >>
-stream
-Gatm;gMZ%0&:G(NIi.r,ftset/sbPhVEqu7Za_p9S*DQ#P^Ho]Qh*%#lD=,1e3AV$GeU?+)!iSsmTGmf3C#Mtc'#*"8?K5AN3"FI(qEClMg0t:%`jkA>8C_2kREAIe6_lHr`g`7qS@U*``0_hpMLG4,*msPQrSVP*b`60l;I(R[.(r!]JJH2P$;WC`#CXg)&pp'HB/-k-:12.R7!]%O\,"EK@OeBaLCZ5M5Mh[Q$$Uk;$[6d1eK,Vo5rn8JdP]f+LSl1)XB\1b(pA;XOJ(,jCDhH&Dml^%?eF.SEOk+Tq_nF\V3bBYjpQJ&-hdh3hq`Y---eVMX2"3+mW$goT[X=7)4'^"Jj;`Ao]5$s;CA9m#\)FNJB_X[cc"iqWT`G=i0PdaqbeLdmPPAL:$p^l`gAFZg;ilCo[/pk#p%p4;=COKcBlR`BiY%"/JjHV7q-!cC692cJE24/C$S3[(H0g@Fg1=P%tBFTouG6:q#N=IN'r1oMu`>#J;\B`%&'qZ-%U'dcs?3,ra4nSVnFP62a"@'YGW3,&hn*&0a1[IW?/XI(^/J`eqOCD3]$B6PDWk<*euNG8&;"o_JtVk,9`E3i>P,FUbiP`:,=)(uMbI_j#_@g)K2bTE:?^A`ju2P,71a-gO`$YtX^?,]>Ypendstream
-endobj
-1298 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1399 >>
-stream
-Gb!;e?#SIU'R^LRs)?@5B4tP4qQbim5asTDJTYX'UO/C&5[1V?7@%29Nn8cq/(,N&AQNsk":GhFL3,!gT)3Mf(]kcX&H-gY!-g;Q=*FcQL#E_:cjsOZ41lS??@9H!+Ih";l:2.T#fM;O-V9Q\2g'YK"6Ah>!ZsdQ:QAhm^o(*"U["fZXe+4X'p;@WGi7Zu%0(n;:O8F)qY02_Upep4Qma+9J?Gk;']9Jo4q/^%VB=H2.IrlIU1b*\,I3/_!uoa]!UXfh@mD8JG[OD`WtJ%t/`Yrk2_ME.,m_IF0c=7_0a.d1,$0l4"UA%XRWDjM[:1")97&Zj\n*YkauZ*>ODteDn1437dtj`T@:S!3Cbq:L@ErIfj^B&No2&E0)>bUnRdhm8&6j)V*g*q;ZthmrTikUd5PA[Z/F`%_shF7ZpI>7bk,'hct`fR'X\"WE61f?IOhVG;V\:Leg=C="R;60-P6PfbAX0[8c\lp`R6j-8Y,jgkD"S&`qe\-1\fjS8/$En>\a3H(sqc@.:j9TaOhV:[E=9bi*&Iho%dES)k!iNj(`3cI)!))KH[%2sG_GZ_pQ%]:L?%eUgdMW3J4J`%:p)kI70GecVEo)V@\A9#q6M@;qg4br]Q9.\$WeDdgS;HpLcN[GaCaD57?WBj01;_G*WSP!KGG)5j3f_\UCC4:iL&"Jn8aVQ?BQA>ajV\C'[25K7PXu4qX&Q"J#C*;1b(HERKi:tM;U$>24HouCMq4u<)>72^Y=`mhaeLmr:!:d2:]H>$!&COkendstream
-endobj
-1299 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1445 >>
-stream
-GauI79lK&M&;KWSnfJ'_M77.<;dZtj[Qq-([tcQD79lW?EhR>RAh/dBMK56dqN@(Zb:BTiQ:d@V:ui5ao&1!i7L2KS([98b#2jA'2cBk#K@pT.0FV@_!T)-T00WZJTZT0OL/IV4=M)s(3/L6>F6J.Ms^\T]`nSqUKeBC\X=U]\m2m(@:(/W3!8a52*aY$`#7Vl?&EbH0V_3TG]\Z8TJW&sQ?%rj/S.DV1UAs4a]e<[,q1Q6S#-VKipp7nhA4_F;IQH@30e/r4\5=pM0$HMPUiCE/4m\bYms]c>hSe52o<)Tokis,>@T;"+DWP#F3dgeBiYIS8MHZZXos)C(u_t^$G$i9Sh=7SL;#1ShD.M:[)PHlMRIdsZa0hs[2)iPT__:l+_p]IDPZW_6PichgfcqqZH<>`J!5(-A_[8Zhm_)jBm"B!<;0QhD:0(sV8e^4S27l)g_NrOgcgt,*r:c3+E[#r.V(,^ps9;`NlZV27U\a7Zk)WrS3)G(<78UlBI4"_bSo$Q]bM[]+u*K:@k8ocZd[mRmTk@kOmFUI'2H$@8oZ%(@@7JS,_MTm&.E0`+30NYC_&boaRl"gY.7kaZMZ[5F]eU:0i:E4)!sk!)P*Rd&ASE4$usd"T,]Htt/gEc2li;U$ZL\<=u^kEtH*ihK/4n3cBiTub@C4D/@O9FXBK#PFWlLu34S#(<[tWn=`@(--RFEje02L!HfPnhj'PVnQaPc$/RmjD5q-S>9*'2qZV?a?%N@S#=d0>`//63!oVK9iQm(Xqla%9E%sfV05ePq9f5mJ1Pp%*H#S[K/XjrhDEG_)J3KCRBG$XVNK!-I*L0F%1K[>NMD5&;de(oX=e>5W-2bQLS#?Y^-V"gg1g+m(tVF'L,fT6qr:G#D\W#8d;cck+#?'&F?6qEp_S1!6#H~>endstream
-endobj
-1300 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1475 >>
-stream
-Gau`Uhf%7-&:P.Os5B'+\4(7mqIOHp#,FhM5,:Q$)!H]c&%##'>\'h/keu^m5DkV6aV&G?dL\JM*:]'emc0l+UOp8mD^9i0COhIe(s`a9'BUf1p;i!a/UX"ZTDa+cL'h/**P%d+M(b/P6D!KL:MCrAG;d;Q9e=`pdhYlajb1*Pl3SRXS(`sB(;KpglQ+4L.9s2P5KgeH$d@[uP3n,rd<-'Jm$F%N,Y'I&d=tmGR\uZ%@m0Oeoqo)dW$=AoEWuMZ]L0*9XNUBjgqS\#>li'I?PWiX-MGEN@/WX14Un)N1iJp23(V,Y6SZeX!(LJm:^rJ*7YY]3U?aJj_JPX!HiBiAIU:p6e=0KMruE0P2q]oLI`V1jV`s*MXLRUDor!+r7>@SqH?&U[ErTZfdNnRWU_Z-H->Ict-EH?"IEB3NB`q>gsr3urJ.alcWRBPPW$$r'f4XfHc2$qhWEtLmClo_]2lX=bjfJS2'n22Z?1U*&Z1X$a:o`>:k1_b6\i'X@K9*.Ns"=RIVjf!;7[YbmWF='0=qM-9WS+EIi9%@EqYB-[t#01;YHCJ_HVu,#UfM#Nje4'r%g)V)Pd+=54Srj'Y*XY=s>gbKd;jtWa!YH"=EdoqKEpOQ,S19UNc5Bo(GYs[&(UGG9%lL;U2Ia-l2;OU'fOq<+)[t[5_,Hr^G&-LTc+30F%e_N)mg6p%F5)?R.[kAs*4@/'"s$X-+k'GW7p@b16*6Qq*,[!TRP5bW1M7l)6-+Brbu0io>LG].:sH'VJ@j0?U9:l^3/C*-BsT5(\o\h4K\*'d.RVV-;Bka9b]10aGL_O=^PX1qJB"f=fu"N[1,V5$.sJ]!%OA0!p0+Vc%-"mm.Ch_)JqB\?Z/m&a3RVQq8sZ)HD)g.4ib:l6c/UAAX9aA_5L4/VY>6Q<2T7&cf#\LKbcD'2MYf>QYu'3pm(4,Kf@BSEH+A#1([$!S%>9:"E0peZ9qh+MooS^.lOAVrhP<\)%QPbHA-KpVh4FNcA4o1<@;OL3(\)KWc/U.a$9$DXTL7FmX@->9(:A!04_a*K]l'."-*6(?g=G072/dhSr.*!hk7BS@Ud+XJ+Q!ctdn^c*f>ZZB(eaI8nR%^\ZnCNLq#W+o]5m"SaQ'C(ctMsgn;Thq1B&g9--b7ARf86GRZ2S*^N@Kkq-rrMHskFD~>endstream
-endobj
-1301 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1552 >>
-stream
-Gb!TX?$#!`'Sc'4PQ,T6YLlSNb9)6rD.iFEU_h^%4)nmlBmLr,!&qop[NK+1I3mPn#"_)jUc[$:(bk.:]R"ZF*>ntqHQ_i>ScbJfclF;q2?X[YDT@Ih)En;%-i]^.T[MEWFaCdh,O"lm%e=s1o+VDQ\[&KRNebu3]n'QDR_*/@pAe@/@7r_g.C:_&N/VJ8-LW,QRoq_I7I(0aAd$!9CIfg@+kW_ep1[5.i^36D@4bY*t"*hhrcD`1BkIQ"R!sebXk,1jWO"gK',)qTgtZ&O$YB8I.!GDlhO&lZt!#*[&Mq.f*n'akF++^f/`u?CHNg20[8aI._sleXO=jjO0).U-Hq,c#frH$+\T)YMrYODTIgAmEKE-"jY^Raala=W\TQ-&>%]rGf`67PS'MJ.PYl"/SJh)SCr?lb<$@+ntF7Q1jo)e`KL"-JM)U*Qc`*=VJL:rdr-pmhetY9s^b(FnF7rSc'kL\ScE@p^]dIg4R6-P!bHVD_2kJF7)n+0"nMta%*=?SNa.FHkDjN9?>f$A(^2bSUT6J[-@1C+r29G$\$R?\J1ZO9Z$HuRnEfrl^]%Bmj,4eaimbQM8Q*!g/FEb82Ql7ULn(sQ=M3JgpQ+^>>Y2qMtIbc1g3nTMIK['drEm7[mm5`Yp=,@f>XIrOSk3aDfaN%11$*%7UmDS0$h*$ZSM67;42s_ia%Jd:+ti6\Oba;P@BS^4FWC!(*9*5_hTN'#88^.%-lWO.u9\*ZJdY.UWk;)j?8A$,dkAJded9O$9'ilA*J%5Sc'+&_[HF>HK`W<&%]3Z7_Y@U;T%o<-VF'%65Jl6X+?AWSrTWZrB^ks`.ku00]5_;^jgcKNT5r,AFl@LYB8K*FJ@KKng]crKQeP>YA^$/hTal[SWZ+1224d6U)8dMqZ4ghuj=rj4U3lN?jj'+_U['FN3cKO-sUIAp?%g`erMendstream
-endobj
-1302 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1742 >>
-stream
-Gatn(?#SIU'Sc&Yj?K0H3(*#!qXDPng2:$tZie_n-nlJTBUQ<=8u+dO:"s%46V;Nler&]g8kkSUh_Z)%FjP<%(d[04jQdf2;RsEfffXZN)=t*)l>8sr]eVVF2QeEhh-P-acjR7L-V;?&k=[-.f5^]M!88CPm>](MZ29t?[TZqQc`LQl]3OocJR$*%E5AIqn\m#g\6&AWqeDL#YuNomYI(!47905bXto:r:bgdE42^6j"9o[MY4R2M5&$C$KS&HO]"Uh^mCu8.,FGa&CL4Gd(a8bYcC?.$a`Y11&5=enQ_(#5W/Gb^%T>]kGd.btd>a`LIeNuPHZS[[DMI>fnA&*P5;9ho(tH$',nn9sb:!k>ouUr/bc?lZ!^eJ?Dmdr?e3SFK^:ej".SPer6HRB3#%V6)rhc!:ul"sd*DlJ=XcecIP0[$!;(0SHW"7;]-^r8r#7ap3JId/FCa.tKq?3&G5:;^M;ZWRemYBa";i5g#o)'GhBZtd8P\AlO)"ZiR3M]#8ZTaWlelGJaS_sZ(e51J/4BK9ZG(_[Gi7tC7p`;"g:^s!W)UYQCIJFE1@]?'"N2Mt?Nq^/5naTtLFB^B+dMD.2(q;QF7krV7(Yb/7lAY4*N*gib<0ir4Zk7X#t_,fukV)PV2kf2%+^][qP(3!U*A6II&4sM%iA67:7^1tp\4rUNtL)XKk,hVW[7MSi_bk(AC@m(nU8IUT??[:Mp1.%bdVGQTn>Uo_Y$:Ba6%P=L/1tt8u3PnF'N%BIYiR+ar#@#Zg0\5%LcLP=LY;f"3SIl:%4(`;*I:l0h)Il4WrS`NiOSbKQ6`\%-.8cT(e<'kM+Lb+d^JZ'(fPb7j2Go'oY#12MrE-_'ZoH!DE&CO8OZRh/NCV%Ljk(LASuiGaa7+7B$oJ"Pc9pAf_EQSCOh@u6^\LiB;kn+$,W9K1D=Y^pL/I4K5%$>Y8I>[>ATu]`Gasm(NJ!%HaZZOKRK\%Aoen\Tq"XjVkjn*RedLV0D)5Jej?-1qSKnK.S0W@:\AffmO$0?:FaA!Gbf.S#8K>BW]LF2TV&ZY?XAF7UkjihLb)?GsKbh)b(,:\u]kg^(=]=tOk#$)dG0I%Z_p"X!gD/:j!lMbKeh:PLSH=/8%F(K^>YoqX8g)3>sl$[rfctM3i7U35#C\kJeJJ6g]Zf!^SG-(5%)floFh\2.*PX#j;Q>d9qPQLXW,9,E_i-LJ>kh.LFW+BFA7McjQI_O"pU>\r_`B)N`=P,L0_]\-ISc^ec0`B>1FOcd\ND+EMm_/K03bF#j8R&4<;<9BFo%+cO&g%S.=Zr<\P1n0I$p^//SL,DII?AGp@UP%9toT cHgq>^Mcr8~>endstream
-endobj
-1303 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1665 >>
-stream
-Gb!Sm>>HJ&'RiR35?PR[X[mX%\Q(S)B3G89c3u9!2@-#*.lXQ)&F?Dt[cS33=%EAa$!tPhod-5M!ms]`s=0d9/#\"EV'Sc#Ua$C-&=oae&),S;G93aFsk5'3:n6uo:XBt8W&&1Ip?I!(bgnAq*p]h)7PsDO6XsAc-qYot7%H36E2ZaQB&hTqD(n7`,O"29N9CQTV0$/INg\^4@Rqcg/a'/`df8JRo%c:*sP@0N=([:%.TNn-C%0e0.nKm-s/.,t=5C-1R@CUd:G`A=Su+,ph_*d2ZbE6GP&HEXDJ1bRuAu]<_6CT^a8%@`DQr$>G@7g$&IEN;_Q3>`)LC@A`Cj5HUM-o1HNVQ&gmu1H(PVab''Z!B>n0d*a.k.-Sh4Hl!b,iPrsCjm\Tg*7"R=%fNU^LT)]*&t1NWQ,dI(0j7[GnMZ,T/WCi?R57BK#uZS<\aXp^+Rq13Urf??$?;"aD,ORmLf/ekb*E>Qfs41MUT$_k1)Y4f=hHujlSV;\Vfu#Sdba/W=8KYcZJ1I(a\QZC'hL].\!nFOpTp*jO_rtJj3A8+'?t.5m/.CZ&`RWLR/hik#i3e6TjH^@IRr=5RFVj@ds`TZKZ*bni%dpdPdj(-XAGm[Rq]XHdr=EaN@+/L]3*n-4h'3DGa)NHpqeELKnC)f`1Q:.apNFggCWX'dnj..eVm0c5C5/.p2G`1@bad6"D5nN-#kl$iU/_qAsF;lu"hR@-k6B>SF5@*BabmZ'@#:[k:Csf1/4]EjXU50XV/>R%ZCFXOn):k;J%4n.Gn_AFJ*]@B%\[k,ciEFii<&f]jYbFNbKi!^s:2ZG6VAWR,kH1eoq=Y'A!TG1*)*Kk6GE04*\fFc6N@i<(E\_7]LO69h!DVMin)*?E[3=<-CHX10hf1SY=lL;7(J.M7cn(1[\G7aVg@;+KFEf-Te8YiG)Ul`Nl.WK+8(8pC`AUgR5E#WEe&L9B3b!9j-o/)`s9#9AaSl$Ds*leXsA7l3Oq]'dGVW@s'(C/Okt+=0lU-[1"X]VJH\;2$:P0R@&lh4j]Ee#m"E@-IQ`BOfC(e"3Q3eFZN:h8qpd0*&,s*;GrPRV#Z@R4")`GgkIjm+hCgt(U2K@Rk-Rll>u?CZ:$KWmeEL(:>FY?<\=9_\$NjR:3PT;[Lk$1$N;BJ/r1TJ3Ec#79?b]TcH15:cZch[7b[ke^E\O-l`QW<[q01K@j9T^cMD0Te[%1g"^<`si!A`=r=*LOp"'~>endstream
-endobj
-1304 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1951 >>
-stream
-Gb!Sm>Ar7S'Rh^^s)?>O3('Er\iCh?!DQdn"k')YN"tQh#?muVXd&%4FOKm7muXi&P81E(*k'%BK?/i/a7%eI1'DuP&c7t3!*:DT(_RqlN+P=!07qS/]G`q]o(hM`ZEfH'0,Xlp!r[dsA<74=Uc#s([7q3Z0d2lC'@'G,q6"`""Ggu.p?bMuU%b/D>b&[pDu;LuIG=W:7Mu;B^&g$Aqg?P:EE9;A/'n>i.]'X^5P!b";JDLPI-Z.!8dIO$BK:bXIueqCie(Y;+J451QsFe*'D*VNI`SEJK3Z5t19-b\mjV#k6]lGD'6ns+H'r:)e+'D=%lCBCf_7[LU8X%jUm:Si!-c%L9a$.9;Nk]DrM5__D!8,>]lSEsC,T_Q&PYgDkbaG=&14\jkLKJ`POAm&R(*eVAG4i0kD3'n<2&[P%t`diB$&7S544M*9.W)Sm/'d;LN%Q^^P:\'\gfXit^Ecl&>-99UTLl`p?MOV563T,p9[4W9&EPP\*iM,A6Y/)*l/eAPkL$:m/2?XfKK,06>oQe)+4n+L]]18*kFoT,W^KUF98l%Z)Z.YgQOMdGL1bj48L,J5/-"WoE=4;*:dFA_?HhK\*Li?IAgB9'-O#G#@.5+69HjKa.0[KYt%Hm@rLf@`/'[hpJY#Ns%-ElQWi1G$thdt/TZc`NLY3Hmk(3]*7[*A^)/@%\Lje[;GHQcHN2&\;9f4AZ,pm;2M7$?Cj"SPfkU[8!8*)HHE<+ANbD9tuiE[OepdRrjtMb35e,N5hE"p2,NmghJ>3`@W9[81^\C9Cph<__+h6X0QA.g:^H#&=&ukBi[3;l,m\l=_t,B9j)VAHA(@>K%B:.k10M6Ml7r8XhcL%9h0rB&_)(q"*;B-A^i)APh6W=jrfdI)Cm:]Y:@"BqMC90AXYeWk`lpfs42X]imCidf0eG/sBO^rf&O*+MRA5Wc`<2INc]A\k+%@Q8Uc$S2]h2hhn2BAE5%+1_tr1%h]h*6';D_kTh)9EYW.96bCYH(;MB*Ase]1GsT]S"a^,05[N>[Pf\\@ksNBX-Kbj6;]&g5d"b#O[]$?Yu.2anWiXA?t1uDK1K4D684q9*tc0?+qlG#>sGPh5FLK8cHm;I7)]B&Z/Hn`QacGa3:@)hCGD7.7qAl95WF1"U,ce`BNCE^mUnVo<,HKOi!WpS,[BSou5#C]C(SH[F#<@NfB1r>DK!a2Ur9*AaJ!k_qeYugg65j)M9kIh.,o2=XqHZC3?;+[#j%TDSf5`[O.~>endstream
-endobj
-1305 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1372 >>
-stream
-Gatn(?#uJp'Sc'4PQ.;f\2tY]ile3C8[k;Z9[_`T9KU_FN=<*i$cjjZf^5m",CqfI(1L]dS.G`'?9K8KSQEgE!["MQBo12RJmQbX_B)=8#RBAi-$SQYEd@3$jTTPVL=%u<]bmO/e0!^1MW%1`!&!-;JP5O_pO(Uf8q"<5\8d$Q<]?W6O'&)Q[R75pndWn?mCCV%\u2@\#[5YKlBB>.>/Ef.djZQZI6tSc*+D$_SO4P4_NSIQn$ugjGpQ%5hX)SjCNBkUJi0$VlQr,\uC`+i"m\WTt/iku*brJFrH?kRHX7Y\$F@F`WhPtFhpFCYWD=g-"OaOXqq4Z+lc*g]7Y71:bm2[LM`,GG]24a$P^?.;:&@+jRJk5U2?bp.DiR@o*#:]FlqN_rR00gO:PS<[!QQb!"4U2Ms"^\4:[K@Fo!5B_Q!Yqf2VWb[\1NZuG2Kk/r,MYAHc2aeS)9a2c!=\#@!Pg]G$3u\0c?]`4&9(7dl*t4FV5'^SH6_40c5?YZoDebqC1X=hYkANI:kFprDGj(Tg=.rX("jLi8^6UY'H:OeT!`K5.N[6g/mQ9r$sOYVbtRBdAl^FYD/a2c8AZW_8B['r*CN1b"sN%/Q9V^YrU1X^Vq`[$ClS5l;GInH(;dUJEf)PoG+,aD2l2:n5TN3#aiel?JV6Yf2218bSP!.<\8nh8,1=n_SQl^IjFlr^eI?V:?0gZ2%='C/i:%=8>q]\'gHJ$6i(3'N*Ann-H1]h/B=lQA&ae5ED_5]s203V9UJQ)QtobHc^uG)<4gani:TS/dc5!opc='nU%$gV=?K#t#jB%'pBN^E3%,pYiML2M`1riY3.59*%-5:PNs!F/7l.3c'B&O46TiTV+nmpQkk=mY1m_JYBPTZ!gm=S4A`Z[Z6A;fr@c?\S.e/]G10s\5$P-8.8%'u@eMsETpTW),#YK\-@(lDJkdQ9PMiudd,MGNgb)]1X1s,YM-ao)V'1EJ]>^/DfI'),X-j6o4FA&UTeY.]Q%BF>:e/Vl)+dsQSk50'l:]"IeSFgUkb~>endstream
-endobj
-1306 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1517 >>
-stream
-Gb!kugMZ%0&:G(NIi.Oq3ecsW\uTKPj9dHBgMUd-"^:XdP%e-[,^Lmh?N5FFb)UVL@leWH9o9()/gKrVbj]R`JjA?\8H+THJ865Zmh$Z_r$`b0BS-6rmel[_0BZt]D/7flgXA:gNaiK[B7'PLBqS$"3]fRd_k>/nI`b/<2P]PHbh`e#&fe0DA3d"'"r-VPbTe#Z`3Xi9!WM!7IjZWD@%eef=EOmNN6sU9(sWjD1X+Q`Ppn[ma>%eN7PRh%roLg"#`8@8W1]J58ffZn4/!cEQ+TY_h>lVX74c$a%uY<7/VIAX;8luHdcsq(&kce6M+&?U^'B.J+d+hF%$pKERKMT2KVLk#-^[-E@7#TXVWoYU3XpGN`tLAg_;6OZj9A>DY!>^?F:nB%EQuWXFo)4H\M)0VO'J`fg>QAfVH]BX`TB!;l-^C^lm]srC[pa/rEi5>.f@=Sr5uQXD?E8>s_,KTV$'+"%8Alg6B63l"ijsj.k)*VZ2jqrt@8V020@[<\s",nS'ippj4I6a'MK"_,.^!Jg03?r@Y(!Mn7QNa4072/F=3KKpTsCItN5V*3>&I+X6^n4p[.i$09'75q'qP*KPJcdUfcU"4_"8@-ai$u+Nm,-OA_n$m*53CgOTT!&nJ=k^]4@94&F]3N_["2/:B,\AY*)9"T$<\bf@H'9P,q^P2BA11I%c^"um0p6tq-N*M,.Jg]Geoe5`8d3Q4^"lNELIJb(HGQ8_*)ET@COM\%/:.!2r\q68mHe-RJ$0Wendstream
-endobj
-1307 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1417 >>
-stream
-Gb!kuD3*[7&H9DlreJmL3OSuINpXJYD5CHS=#t&">moO^5D3De]d2_[7sE]p?cNHa#V>+i[Ui5WPa@4_o?>G=R/ql85"P^.$,G@&DBBE4)b)VKUebCj#kt+[X3]C!W03uPhskP*Ja;;Znf;(#Wo7bgqj^0.9uf2s/)>iO]#iB^!M@2Y-^,qfAAlsVoKt+]S;Aj,(-F&m`gsTl161EH&t+.%L%6c)eB.JT00]4u>Pu,4m^:e8L[;H`T-E?qK=]m]&o67iqfJi[j^MCAbHd+)>-@HAN"uhh&sC'VAe8iJ@E&IAFZ5L[l;!RU;WM7pYbCW@ZuoQrd^`ViFka)NaE#*0Q:aNhZ/$2h`uWFjBP5^W3^=$gQbcY;4ms=>L9)uG1h*01cG%iNipKrP`)-7u#oMpp$4QX"*E%<0\)M=[SRlZb#LS+"EPW\bD>-"iFYYkK;#l4)g.ahDU=C(5e;j&dQJj%UP%EUAI)R;1k9$rWe\##P.(ujQ'%5(l[CHAd[JFASf"kXYbgk_l5Eh=%3.+o;HJgW71@TFsb98>:FA2*IdcppMs%u]fAM^7-g`btT[-]V(/2EAWG2R3*B+oYduXDRXXY51!dr;#m]_dD0DC:s-UoI2[iJ=^%YJ793jb5`!oJB)k"ph;@*Sk]`C:;"hUgW3dcK_37-Y[0`,n;-V:*oA)'[\1mVIW#A\,H<.39&pUE9biZ43=]\r:h&1nN$Ur:*&f8XLos(0":DGfPg(4bq$O48R:e+\5'/@BS1_p1/&]B.(Sm9$3&jiRde(E36Gd*<^iaG_h:=IW@^#e7$u#GLnD%-"TMrRX43js#\_-#Eo=?:;%fLtB(;Hf1ba)^4uirFI7,dC7_@6RF[/c]m.f'R\#UN,!_mfiMl[,fK7\Y!Bo(_2e84(MMI-0"XBdcM'=;_t8ON@i2ZrNMUCIguep-pXOfU\/'8R0iu3;:i,+f_:)"WP:k+:/)3H,a+c^4Xb/3iEI\i-[kl53mDC`bP5lOOIJ*c?6.5&L[u;&T-_P(`#Q#>/iG26ulcoR%F"lIq#HGUdFP)+\_4p`l_\=NkdWo*V<`D_?p`NRkL2fCWM&S&K?'pK6),iMOrDHY/D'+i5'<:nO"a.Og*pkK?Mc=Uc%X9TM-CW,X#]D=gp'brKe!m(<]=u(hgt10pf`">3"irK7Oe:qIl>1FhgSeH=[?5HfqO-MNK9DQnoaT"JO]09>/NWuD\"4UGAg`+*l[dN7gBf"g?n:iK4+VDZk0]+R"C-%Fq>^8_jOA)Wqf@7MT=(JIl`5L9G763M~>endstream
-endobj
-1308 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1266 >>
-stream
-Gb!ku?#SIU'R^LRs)?AP3eQhh9P&MQGs;e"Y;%0u^udM1!RdlbCUPl=WhWj[Gd'$hu"5`0^,fhX86J<=!:Z3a"8R$C-6OTqG]\A*oa[2D:)#fr5`eZ\_BfSmO1A+ZXT9K*F="HRO).DMQ)hS]qA4oHLL#\[iudV>NDFr!,V9)=+u.gT])6Pp,9)@koso[9m[)C^/!1#DX%V;QE;/,3)`U4V4G4W9YGN^T+N@!$DZU]Uli;jT65S%Cqtk2V6Zf)kHna7kpMn&DB4jqHUlG*gFFO>?Ksp2;PUWtYum7t5ZRL@#SnGe7PuN:"3'<%Zq.g,W6-Y.;jC:r0"c+4AMp"^Hk"g2/Y>D"dhWnP1MN/T]I-4DYtEOpA-;NfFq4c$R>:gWVP4ehb#[=H"O*P"1\=(+8S_4b:0COs^8`*-Rpnb:)m\PU=B2mtp%>0#qp[SOOo70m]=+7&7[jB'Sb#at)H:Mj>:7DO`_JD4F^,$Y'G1?b,hY>$p`r[k)(!C8ig&k-Fu49,?[a&R9-A%O\cRA\CjT`>BW(i*rM\GP4ZD>R[st$81Vh"tI-]o-dK6=M[GnK=/-9He-bKj.I?iihGL&2Rj#1K]8`)GD#3[H?83RT@YjCP?#YjU\=C](CY;0[(+uaYR"4E)9[C(2-l,>Q:rmZS$&cLfEZ56&aP^j\Hj4#RuG]jI`n=/iq#9q;i@91@?.YT1(4O`J/&BQ%2^(e'Rng_'Xedo[b=o2XP;mB>pd67-TUaa[!8_1C[.<5p->_r$LT30"l7CL5R)MD51W-endstream
-endobj
-1309 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1564 >>
-stream
-Gb!;dD/\/e&H3^ns5?d^W&$DnW#*2W>CeUa=Kusb(BX[rmfP/h()L.R.=,n2rCBP@Cs.hfb8h->EFejV^GhI:J`2RF?A<04$_0YGo\a*%[1-.3E+9#qIraL>c)W!op%!R>!J5BTYX;\5mERkT6f7kf_>XTJ_a\&muAEtT[`WQ]7+Rtg2#YSTnDunBLIo9'UP"@A=[F(9EpjR;1nauK7c?#I9mO!ea]8\54j#[]1CZ(PHf$)L5$NJ(^YY8M98aGLXSu&O(]6C7B@"2dln^K)U8'a3p?-s=9oE'ZT98\t'KD=&Jr/DAQr$7mi%*KEa-+BiF2Qm3LXNkrRZO2=Wtio@I'a30`<1U<^:sPmh,T^t?XQ+fCh!4qc%B/95Q48/Q_[a[g@(B/23IF?2)Kc/*51i>)g58!VV'#H>SLaYK9[22.M^a;od:@LPPE3&Z$%8DJ!Sa)*REF!24"";d%:qtbg+KYjq,c&2=GbOgZpesXm3;oDI@J"+ih=%.VmrW;P)4M9%+J65CiU2FBE,A;,KWQ_@k-PH`_MBb.e+a+]KR911l[`d^p+<8/m4d"&-L4iAUsN6&HeMIqrZJYrRIZ-m&Sob@l4Pei_<>M`%nX#endstream
-endobj
-1310 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1366 >>
-stream
-Gb!ku>Ap!%'Rl+-s)=3h3\/rn\5RNOC=5MMPjW^1CEI`U#6JC^[_U6u]]o.AmkA,gN*SujW6QlT-/b;]mp,&9J3X]r8H*oY_"ADEmLUKUVK5$!=GQ-(geQ2A5+eI@>h1ULVP?0X/5$p,a)m!3'G/E&)52p=:";K['[#P*`PNN9-!`Ko@1*Y@o_dS(+e[\if)]#B+cc=D9`H_Y8/3FN)*n2B>V")(IptlsA+(h`ZV1+9qND'\]DUOoh*bO9^W1EphXu:0/WL9HGIe"YJLm+8U"?BKd9fhtC"O)He`[qNPf>jp8"CI_[Hi6E0Y3/>@q/S$YLjBXYrDHTh0I9%d%EVu^3;;S2MU`l@ja<<$c6`&KIM'#ZX8;2oHHY)nKJ]ZdCW>r9E;&CK1Hc]-^lrf'KZS@e%u4BBP`V0t5YLbY,Jm)6:&;VB*CNJG*9&PX1pueE"jH3;-e+BF&[b#%"8ImOgsj-B;4Gm*sj!Qmp1p'_^),Q`;QG8(X]k.m<#\A/S\$@^bA4_i@Q?ZXN6_hpBiLUs84[R4$<'+l9b:35*0[YZK+()%\L`ra/N=+k"3FpYe/,FF:B3:\cM3S`!NJOD+<1eKFY7N='8)oBj_P"]=CG`foFiH)jKraH/dj`hsW__[NGWi,0dS5&==,FWWHbC`>4a8q%LFEneYuTqUc:_(O-bkAiL0j"@oIRO&p\O%\Ia\"3,Q"9H#PN8:B0;chJ_aJZY[^<$N:2mXT9((ubsPHK:m24<+Jq_tKcQAq0GGD(s^iQLmg54;BmdqPBYRF+i^I^Js#Q?2CC4oon=&TER;Yn7C@Y]u+`n@X.LTWZF/]fI33"rI+usWCY*3]Pa$\mqgW/O^n('[ZKpHcL12;``ef-_I,F#WoIk]p$F2\O@qW%JI0J90n3:O68S#gK)mhf+a"5dnhO2ncgr9QY]-NH@~>endstream
-endobj
-1311 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1545 >>
-stream
-Gb!;eD/\/e&H3^ns5D>2sXkhPf0>ApY>;L,>B;r&$`lP!UqFio.'kfKQIJFDT@jQK?No^ki;1FRE6eHG,HGU$$;1ENR6S2q.J@bu(!CN%_dhpeG`SDsbS\DE]TpHdQW/$/RbOH,bskBt_V;?VNPnQWUojjP6`t0PEXL'^TQkPLg:f]J``i;@rGK$T6[%-'-LHJJ*aYr%NKs_5G$gOql7,eOP\'O9-nEpG(=Fo>L-h=="G:M>$:CdX@rJKIfYbm9X%?n3G#UYcI@YOO`J"&5D9X:/cZ?p]2_Z:H1QYe`_VHG6kj+?A9PL(q!>g?Kb(>n)]2S.[Ec`pHCbQ@Hlp8NPf40/o0d5hjU\Z6<;h(t#RN^f0/NCL;k0)6-d^jh!73uP#[!/NFJ,bsC6`N4(T.H*#cHaoX#asLtYUJ-/9.2MOWRBZWSeCqm1^`X&0pZ"O@t2A`&n+HI'c3gQbu)625hJ]$OXN_*ko`;pn=$KMrZOgD:pdV6[*Ym\1XfR8q(kaUL9#t\D)MsO[TY'Bl$8o+aNW[HF>'1ak!+.;'?/Wp0Cg&-e:Mu,YE^`KqWoeWB97'T04[U5*PcCfC#m.[i%=n>'B]n+tV=Z,Mh`MV,Y`FaE-Cm(>Tm>B.1Ha&o%)4N%"Z/cus_;<,u,SP;!T?/0JD)HI]qGGS<`]6`DO#l-Nqm'?h9"`:AMe)c7qDsEl$N5g+ja:S\'gEM:i9R&uYjYB4HdS;YU(qh^6.XZ/Cp*Bs-Y"NlctWLmFoH0n`dK\T#"R5+OD,%hZ]-%UMG4SK/@CWB,^."+hSVdZjFD!8LZ\@;[5:;m9%nm"@^6UT">=Dfo&X"RbCi7.L3+WH)2J1"N)`op8^5aV]eIX\M)Ea#CW!`#--Sq0:c4]/po^<`;io-[V:6"1o9bDAR)KcA!P^WcV2_6,1Mk,?3giqgpZW7M[pdLrendstream
-endobj
-1312 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1505 >>
-stream
-Gb!Sl>>O9K'RiR35902i9U,aAY=WXFm)#b8?.#h*m=hPYlq*Sap&o^DA:K#ga0?<<5UMl#Zm@-*Arc9II-3Zr9`,Ip*@:ca!?@^F+;P)i+O7cRhu_2UrOpta4gL;p]n&,J7Ke+r*fuLC_E4"_hH\0)m_C,ZL_gUJl>[X8?k8&r4P3W*C]_T[)p9H3rkVI:NO&kYb[QlR^<5@$\d_j@V<4SNjZE,^UXJ[q:7,3f&I0aZf_>%_;2Y[qO28fgJQc>Bm'qGq&";_oIVD=9.@bKGgPJ!h=CLq0O>aWSK,9p2ILd`,9]E!IKps7DqBogGqno#%A#,f>[`Xn!BTgQ'%aGcWIQnX]J&q-gS-Wqm+L@X+MjK%jEj+Y)Q+,:Oe?>`A+!$pM1u_4hYU:*b!5sg.]eYR>C"!m,9U`NXDHL@?uahb%0A8]R')mO!_i/mF4eF%Aa2mtP&hPA"h$LRMCknVB-ZcKmJ4c#6^TL]gr9$_@NU#qA[?UTaT?.,]?81Du.cJhCDnrC2e!bf^.]>XTA.WGM9DDXQZLO1X.9[mI'<,1\aXI&+>'.G_t&9K^g20s:De/_X;QV1+])d&`7!uo87U3:2o*d0^[$(?\%Mh=p)-t\1TPRTLNK]R>?(jY=;im&o"QJ;3,*`d'EH8l*`Vpbl#2/m_rh5gYB&\Ct!f&j*BfEn`E=1ZIulG%MpZ\m(oA4Nt6A[9@TZ9"b(=RYti#2Z(e_/".K-#^WSGKinuO'g#D(DCSlO>D4d-$AD@Y.eO^)^&OXM.=\KXN+lZB5lm^>t4O#1I;*ekV:KYV()ODH,=%Bj?g)UC!?&L/C:Zj.b3QI_1KBo-:&Mokj+u-_,H&8?akoYgn?^]/A,$>.qcm:LbW,&Zfl[l)&XVF.?AOE99o,Gd-XS7&I)MI/5HU2U=kYoW2"A`Mi,6Ce(6`F2d_KKJ;;UE3.q1CIfW^S&=E~>endstream
-endobj
-1313 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1646 >>
-stream
-GauI8CN%rc'Sa@-aF?25QafEBLq;6iYRO-Efe=[g2]F9OAJf*;[b/Z19$t3Af8l_<>I(&XZJ<HHm&A-/-+O$i:I?WZ=,KjjRulH>f5[anDMLK!Qs/CKDrZqI0@H]dmsDQQT]Hnfm2,fpA,gs,P_Bf$iP5"nr!a'/G6uJIdfAirh:j4`WRVF\4b_rjKi[ajK3_m_P`28+S_*>6cedBLkl%[U+$Au*a#/oM.oi/bGN9Ef'Qj:_tk'^*:89VjnT,/_1&8+#8O1dg?cF*3\(B6bo.ad`sQ]!:5^5mR.$qJJ$1&Rh:?U'gcV+tQ2:Zts(?;sZ>&sQ[B=OPOY-)s7c:*f.LJe_(_noKaSqtZ:[F`@`;>jF?V"%dO=Ii).IE@e/Y>STdHpM@j6W\@iM6W]aKilVZU%[)V[bnVV;Pi_>U9hF0B<-Qj8"D.TFkmF/b_t`W5/ol(W7d.8c0fo\RBHnJQV*a?V+E-B%X!CQO_:PE-?EJ1b7g3kAZophQ/L(1e[(e$l'8`h-J-`5NL/+Xgjfq20)GEpc,J%U=\C06!_T7bAkS]".ig=P^_Yk3epk(Y^"_E$KX23e6UFJKAD=;+:$0=Q\uTT[`A`aF9=BSe0CIp8<[T$-AbG_aG3$>)`uc&d%.fm\opgN[6`ns^IFKZA.GS\;]`(UBmCeo[leK1Qn"K2h.QpVZHDBDbEc3i&*l(gO>\7CJ$cC4k,#g6s`qk\5%n(^^25c@m?c5&+/H+@2)WrgUCVO3uGR#=.8`7qoq1$!LZpZ(u*Q.0T]endstream
-endobj
-1314 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1646 >>
-stream
-Gb!;d>Ar7S'RgRSs)?>O3Q(3>]%JRA!GTti!KqVA$nT@[+LFPkC1U8=W&XeN,:WGc92/WXJKe1:7m,])cCG4LnV,J2Ih(sc#a`"+O9rf2+M2:(n/gEscd0=rT:nU&EI4j$H3j@qX+rgh'5o?$6OC!]q3a2HX\\AB_rfr\>9'T%2`.&]@N?#F8U*I^,"]:Y-TG(F1!3nASVeLcp+/%BAebtkp]/LlX4qD#-8ONFsKj/;FK2LM]/PmM2FXVSGWABlL;ojBbSopj.9(,4Z<[L':MN?PXpo*d=-6LnCARonVLY)3hisC&3MW[R,99"i6H`;"/\EOfaTs`"W.TJ@Rh"b7S=d()hF1o5*0^Kl?>;7V1AEMU_Ibc^W[=X1m97fhB$,+1,`e+nH)Qp,^jZDNSdH>]bA6\m]iG!eq[SckuP:M!c"m@,8!I=PiR:q205/N\dhBQ6"H0>F*Z[U^.4!h$AMdKW4fY40DH.R2GacM-_*Z/tacOKa34YN0-,W\L)!#1k@QUSqGAim=r)S8^"%"25Mi0@o6%EC%`t;8Sl;/peA(CJ2*0l-mF3pFdCLB\s,#IQ*_maCePgSnfAO-UZhS("e'G]HoFFtU>X)'4;r*A*Z5I)/3S:L>@(h1kS!opKR>lKF/r>ESbGlR:9D6UWYNNop8)/N,0#B/S%ONCT2!Y<0Fbb!"OpKc[_3\%^U+8Mo6,:j/HY`1&Ha]DRH"b9uh&(5/s"(qg9foX`alq)MR:A=R=%s0&;9O:1416mE5'2orTB-%/rj+_GiCLX2jP<4('=B,Sb/)mu2tDq3XW*a'XN`O$"CqEYoE&NgLLDMl;Yf3Dgo/FWF+]#[;n\F9Uh_K66oG)E/!$EH2rI9p:Y/\K2)7BZqh%=`U@@'"3W>EQW5UK,cA5@4jn`-V5!Z1'P(5>HA'jKW%DecgmbjqY;!sbCKt2i%osraGSn-*N_molF1*l,90K84K[dP^N:U-p%EiA+K=OQNDg:MgU1?I@)51T8M$T=QT4;m?;i?Df-4S/LMUKBQkrfB7A')/l/BA'qVA8='9^a(8S#0,pQK@'.PV]ZYoZQa/OaQ5,tl]G"4`&/c3]5TB<\G:eiC1qoNrN+[`7W5kZ.oSABAI@Xr58K"fM]fkpm(O;GDE^YJ8T],FkY##DjZ$2e>i?lHo&;iq(R:gF>4&IeFk5_k5-~>endstream
-endobj
-1315 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1484 >>
-stream
-Gb!Sl>Ar7S'RgRSs)=9Z<@J\feBM%+(dE-&_\6Sjn[VX5=2Z$2fp]2#-<8@C@qV@rc7!N":9SSE%N(%Mc#`^WK&9J!'p[A'o[!\9d_[Yg)qA7K,2"i;)f0JRVQ@#g&grX4hoS6PJga=PFtCY**CUNUqLgiX$t59[b8ABgddZ%e=!,_HT#<*/@%\mIenpY"X^uNF.p65pJk7)Qnp3gq;a94l:8W`Z:G9cquCOat2Gg?_>Xsrg#'OAAcEU:G?_!Xh!V`9t=>`IPpn9Sq1>d/oXA<4Urn,#PTr9W#B=HJ^uDkP'[h_#UkK$o'bn6Q\hkArOe!oIk)]KR.Kt+_%P59C78TojDSg6;Oq3Y0MWIgqNYiplI+SLZa!QU8KcjOn/Z9S%K:9'BDX?Vk$3DBju1:fUH+KVqA51MFr^ugAi**P6L=R2HD)rLK:rc_;rP-B@o)&H,L\b5(`9dc#p(c.+H2Th,+_$>0`dl]%=q`LgbDpl#>J!8MrL3i1j9VeZ02D>c%;-QF"uEfD3h,j6R$Vc1]=(VS\]?FSFu0`fLX,n7?isCHjEa<,IeMV=f;YZ)JfLl\NLb&+kfV9Y?%in6+,e1^h>&](\C_c`-2sH]84ltLj4b$MJjor/We'?b3ddk-OkHolIUsS&%g8T@p#p:@ne[(cQBtCjq)+`Z8PKM-4U=pBQE2C;-0nq5Q1D_,?`mS@aHDoK)"kP\Q2e?'SL@G3Eu)ZS$!jYPgqBS>+!Ip$3*0W$f)_fK=5C%/mHp/$04pO)1*?XA1F(99Ld.!-eVhB#5U/5+=(WlcKs>o,6t`=4Yt#f&c-U8't"n!]ZTV`X"/`g5.*(HN)1Xr#Wn"WdF3@L@)P+pjT)+,8VrE,^?)WVKSk^RA:EB8(+(XO_(;k3BcFioWB[)q`CcDbBkD40Mdok4npenT]L9ZK.QeV6ZS>&I&e,pVd8k-fiT8*iUpKp-aR(Pjb;%%4bpT##"2BtiaaAe=bJS5P*AHM9Hfnc$-@*CO6T'<9j$P--kOe1ZTt%C.%KgBj5*c]INgaUUa.R!4gcLVFB49!jQ18$7kBNd(mU)lU;i+MkB^"@`+#*fO>*(2GogWg(V*_Wo0!QaA8`3<4!+OSOtF(b`DE\G%juA+`f;VAAMj)n2m!N1GqYo0X4I\GpR*%.>QjU=W#'+(0!3[?7_N8E`SB8(YEBH+P%Ao+(R9IGol>/"H@,m\/.'jT+lr(nTMjLAV:Y,S/&D5A^Kdj$_>~>endstream
-endobj
-1316 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1541 >>
-stream
-Gb!;d;/`4!&:T\)s"MTZYIZ\E/7;4i--*Qs+uuQ:c;H/MI9;uHDd*XaAY#Xqoc4fa^qb49]-enbNA1P4mC+nCbq&l'?UTChQ2oMM\GAI@fJ&]qTm[930ta-KT7&je,DE8cotA-N#l)-_-\3)lS_='^hUpbg`-6#&^J:*kEFXAMSs&HVQ@?pZo^:D]ms!eh&h>"RGQX/Ed*+#aH4N0\^TN:OiPQU_D=W;`o;hk/L#e@K8@I8s#oVZf.O6"WW^FAXC!%4(^u?'[HgbA5Ku5[\#V(BSLF?:VGh=s.jodPTRh9EYZVNu5otfIcJ]?Ais3-e0Lo5tpg%O9VWNk@tZQr`jIafV8Al:$3@o7^KZTaUQ%:O@.41Q@@`uAKp6/sCqD3*@7$]C=WW3N1)e10_9EDR#_j-_ugom]64Q"2\i6^Z&-$$-^?oBKDEdu$?_tc0h2H[_gVcN6mG(2\Ea&"\R7pY*9`AnmUn7%AK,nI^\Hg'<;idsk@Km8[dM8C23I7Y;8Sg?ilF]6TLIt,m>q=Bsp2'3%CeG`#2J1-)?H[EV2j5l\>$o-Z6ldoh+VT0<2Z?g2>YW2jA0@:m_XAZYq6OKNFp%bH*iFi'\bo0Tl:VLPGFYLFad8r>L56'%Yr#a%7%b^2e+KNa(49\e$;5JfaJWK>SMrNo\no_j&gai;3;pH4'"9Y6N-.=RIQ:qkYaItk93>q$eW/@uOK-e*R,.$"#8-Y=&(=-PF#+NX22bd+*jJI+hO)?Ae$)>p:<,ST]c9lSI6$"+WM>*k!r*o'=K5P\]2"NF1IH;\?=sN`7N,`M;Kb-WPcM8R3PZnq:pQu9fN_i/e1k0L'do@(;5rU#)'6JA:TUB@[/f2H4Hg:OhpeWDOc8DC8H[P9snL`ab#Des0TJ*Qe3+7Fg5_r:"9\_]@Bs*:;[hf[+.4`)U1e@ilJ(a62@trjMmb8$'al3AR'8"F\in;puF;SEEc5kgWL2p=@W0G+,Wdu37r?,8e]/rr^ISrG:.J%`=XfhPe5UPQ"FG!/GH#"#8u$3:?nC"7IY\.R(*V@gC9(Kh3Ea9/)s1u6/R(ufosEtjkD!]IG&PF@L(#jC"RVqmmnel&!n6Mk'f1*I4,81[,g'?cmlJM25,1W&TiVm_Rl"5d0,,QOslCU7f_S.DZYf:ma*uC@PQ!?S1.aLFm`'33I!]8793H.bD5i2Md5X+Qendstream
-endobj
-1317 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1060 >>
-stream
-Gb!;d>Ar4L'RiR35Ffc9)A(YC0%2Xk/+$Zo[8V>iHO.HP9L,Od\n]!/[M*=,d$R_Y+`I_[n-puSmFH]tKlU>]G23-'#X"/i;;_ZLU_^2B!5E!4pHf1\7SB4)g+GQ2D=0bfP0Ct5eJn5X\R7t.$$<"mpOMDd=8+A_[Z`cJ4_k1%)_1a;*V3"C/MM:;PZagF%#1U8,Es:.Aip;+/F#G)2)1o9\0!L^d.71b].>!hnln[47S[@-&-X!0a>U5ZD5!Ya:&W]F5eHocE0eAMFek$>4QTX##c]TYK`^S*L_o0.#;9s&Sm)$`6N[#*@(D5u*degLF$M5UJbJNOf!7I$W8!kJ6qF,dW*[C8SAZWFZ`)5ZP2ij,2n11Ahce30J*Dc`]/?a=&biWmrhVN0EdgUeq=f0kq'X=.#ej4s3hA>/d6'gB"-([RSt-(LB$2oQ"q[/Gg,nPE_7Li5\/S)W8?H?uo@WY!MA3=FLQLU;f?>f>L%T_FD"(L*3S'>R\-!X(0`>X)$o;0.%33<]U/L&?<:Em_tfc=sMm6dS\4gqdkQ6Q=.?I0cUficoqg-\9[8HT`,lhTj0ps-1J/4kepHUTkt+atcBQd$cKQ_61GfTL$L\KgDJgaNZ8M*]+"l`1TE;kWbAc#7X"uEJU"'"G%2J%n0"c\_qc1=F>fgj4\'sD_Yq6eLn45rr=FND"I~>endstream
-endobj
-1318 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1319 >>
-stream
-Gb!Sl=`<=Y&:P.Os"MO;HAb8TV5reqaDU@=5dk>F[j]Vj""i!1=rgq,:9so6eDX%a6q*"J%MCa]4e*D72rDY!0d-FIMq9'UGX$fZ&-F75RK@(:K@(\J7[Fp`0/%9UCHIjB'-Dkm;@EA^Y?)JDW%a=>b7!\ADgER!HaW0InbJRH(`T6J*6r'7CXfrk^?fkl:neJjguUl5HCk/c_:Y@I(6X8'/HYPXfq'T5Qh*V^_#-(*-Bh%s+HFqpATYiWm,+tMm4b\%NGYPBN+pLVE4[>V;8:*XW20bn4BCS,S--,^f70c9Z'DcM3m>j&"RH4:\!-2+qu-]>UiCd;>'n1C%'es75"u]!S%#=p>hDNL+JrOs'Y\:2fDsI]/%R%i3-L*LO\b[Z4lhSg%DBP&["^I"JuR=`Is'b05"nl3hEqieA]G8>;2E31A#\tlt/C>POgYYp2p,-lHORS?3`m,m[uRca#sZme^ueg/3OAl[@*.`*>@'^\B2$qQ5IK>+1Xs.NGOFFI$#uo"qD/+=r(pTRbS5$^!%:D0P%PMSED^)7O]48QcbQAbk'SG/_^rn#;.t&=t8l1ab@>!2;IMn'>s4%\SbJ#re&CUO!=ZiCM42.EXj!=PDPCj3"LXeJRf(&QpITIBro\*6![,7Se`t`A*.p9nNa"R,s4kb_Z^hAmr`@;6kW&,Fk:N]q/J#"&G^\OKlO@h#P,7V%N0#YNo>/kUNN%El9`R9ld&0t^'^0(lD\ADFba;R(Z\TP>G9kWe(i^c-Wd\b[GP^4V*7(u9f.@XVG.c:B^#Dq$n4)WKhnV3DK7==h&rP%/D'[&p?]X5_J6HuU3;..H+sCU87Db"$<).E&8Hae+;Ql3q7Q.BG.p=D#`^mf'j%fC&]`Rt`anY=4#AEu#,L(Tl]McW8trVIn2@a/1=_#Fk9/hendstream
-endobj
-1319 0 obj
-<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 1609 >>
-stream
-Gb!Sm>>O9K'RiR359(iSQtcpKO.F4+\'cloq``mH>hB3HeAAYCM&BE(Sjb"\rX1f%h.]12csJV'/AXN:>d.m^!h5r\iAW312Uh'RD`$*RoXbiYTBq0rGWh+L+[2tp7M'_Vni9&!P3:L*M&p)R$fdU?\EF-b_^tu4$H]$6+[#$Ki%9+h!*,YInEe"rkXf9l7e]20:KV&6jE6oQ1W8q#:Be^mKD#P:POY87)1\WW,o!n\>hmlV+K:d&[>ZBQiQ"A-]XT)o7(5SAkj'-QHppAu@%Z:Sc+0S%bq?0].>nB)7!^s*4(s[Q5=R5/K:%:#a$h;[!AaZgM")5U*?I2R-W"c<:M=1564/&B\ZBPar0t8-T)C>Fp[Z*lB"b0q/*Y0*IK8a;1)7g=cF0YbJqSCD^kNhg9gVr?*i\gm6AFgj4T]f3G9Xr%E,ffC*q.Q(t0Ng6:VjB6CXnpFIl?o;1XH?!3`\+q8'aWp$*+<>QQD4&%TPZ9Wb,Scm4\SHg&9C;2Iac*=nO/^c,!Qp2<]b;`s%OR)A:'91hU#_RCA6Qbn^@6nK2A?aP"NLd9T11p84k4L08)&,c]`/<2(-khGWUWp)D&Q4HrlC>$OPRPp>mfVn6oPV=s(Xhhh>QNo=*AjTWUlQ30.8RGMO0.nNjl@O=t5RC9`tC;)qRE%qu&sMbDOo<>)[H^YUnZ7<60/#%YrO-5g20(]oH4Z___NXlh>"049a.lOTHQ0j8JB[a>5FXPtRX\g$PWU&ALR@HYNm3h=&\Q_2M[];;3hc4O/5N_ns>Q`hR%0BC,C6*)Fa'.71jQVLDs/N6Ck%W.3m)<+]5Pn$0`p&D_9SY>GR%;R@et,pT3X8=mY'ber]e#]6M6=XI.mbNDRT"_#0[+l_jK$,`i5]%6rii+;D.eEp1e]Z\2T.FUu[=Y(