Example #1
0
 def _path(self, node):
     self.path = self.canvas.beginPath()
     self.path.moveTo(**utils.attr_get(node, ['x', 'y']))
     for n in utils._child_get(node, self):
         if not n.text:
             if n.tag == 'moveto':
                 vals = utils.text_get(n).split()
                 self.path.moveTo(utils.unit_get(vals[0]),
                                  utils.unit_get(vals[1]))
             elif n.tag == 'curvesto':
                 vals = utils.text_get(n).split()
                 while len(vals) > 5:
                     pos = []
                     while len(pos) < 6:
                         pos.append(utils.unit_get(vals.pop(0)))
                     self.path.curveTo(*pos)
         elif n.text:
             data = n.text.split(
             )  # Not sure if I must merge all TEXT_NODE ?
             while len(data) > 1:
                 x = utils.unit_get(data.pop(0))
                 y = utils.unit_get(data.pop(0))
                 self.path.lineTo(x, y)
     if (not node.get('close')) or utils.bool_get(node.get('close')):
         self.path.close()
     self.canvas.drawPath(
         self.path,
         **utils.attr_get(node, [], {
             'fill': 'bool',
             'stroke': 'bool'
         }))
Example #2
0
 def __init__(self, node, localcontext, styles, self2):
     self.localcontext = (localcontext or {}).copy()
     self.node = node
     self.styles = styles
     self.width = utils.unit_get(node.get('width'))
     self.height = utils.unit_get(node.get('height'))
     self.self2 = self2
Example #3
0
 def _circle(self, node):
     self.canvas.circle(x_cen=utils.unit_get(node.get('x')),
                        y_cen=utils.unit_get(node.get('y')),
                        r=utils.unit_get(node.get('radius')),
                        **utils.attr_get(node, [], {
                            'fill': 'bool',
                            'stroke': 'bool'
                        }))
Example #4
0
    def _ellipse(self, node):
        x1 = utils.unit_get(node.get('x'))
        x2 = utils.unit_get(node.get('width'))
        y1 = utils.unit_get(node.get('y'))
        y2 = utils.unit_get(node.get('height'))

        self.canvas.ellipse(
            x1, y1, x2, y2,
            **utils.attr_get(node, [], {
                'fill': 'bool',
                'stroke': 'bool'
            }))
Example #5
0
    def __init__(self, node, style,localcontext = {}):
        self.localcontext = localcontext
        self.posx = utils.unit_get(node.get('x'))
        self.posy =  utils.unit_get(node.get('y'))

        aligns = {
            'drawString': 'left',
            'drawRightString': 'right',
            'drawCentredString': 'center'
        }
        align = aligns[node.tag]
        self.pos = [(self.posx, self.posy, align, utils._process_text(self, node.text), style.get('td'), style.font_size_get('td'))]
Example #6
0
    def _tag_table(self, node):
        new_node = copy.deepcopy(node)
        for child in new_node:
            new_node.remove(child)
        new_node.tag = 'table'
        def process(node,new_node):
            for child in utils._child_get(node,self):
                new_child = copy.deepcopy(child)
                new_node.append(new_child)
                if len(child):
                    for n in new_child:
                        new_child.remove(n)
                    process(child, new_child)
                else:
                    new_child.text  = utils._process_text(self, child.text)
                    new_child.tag = 'p'
                    try:
                        if new_child.get('style').find('terp_tblheader')!= -1:
                            new_node.tag = 'th'
                    except Exception:
                        pass
        process(node,new_node)
        if new_node.get('colWidths',False):
            sizes = map(lambda x: utils.unit_get(x), new_node.get('colWidths').split(','))
            tr = etree.SubElement(new_node, 'tr')
            for s in sizes:
                etree.SubElement(tr, 'td', width=str(s))

        return etree.tostring(new_node)
Example #7
0
 def _lines(self, node):
     line_str = node.text.split()
     lines = []
     while len(line_str) > 3:
         lines.append([utils.unit_get(l) for l in line_str[0:4]])
         line_str = line_str[4:]
     self.canvas.lines(lines)
Example #8
0
 def _para_style_update(self, node):
     data = {}
     for attr in ['textColor', 'backColor', 'bulletColor', 'borderColor']:
         if node.get(attr):
             data[attr] = color.get(node.get(attr))
     for attr in ['fontName', 'bulletFontName', 'bulletText']:
         if node.get(attr):
             data[attr] = node.get(attr)
     for attr in [
             'fontSize', 'leftIndent', 'rightIndent', 'spaceBefore',
             'spaceAfter', 'firstLineIndent', 'bulletIndent',
             'bulletFontSize', 'leading', 'borderWidth', 'borderPadding',
             'borderRadius'
     ]:
         if node.get(attr):
             data[attr] = utils.unit_get(node.get(attr))
     if node.get('alignment'):
         align = {
             'right': reportlab.lib.enums.TA_RIGHT,
             'center': reportlab.lib.enums.TA_CENTER,
             'justify': reportlab.lib.enums.TA_JUSTIFY
         }
         data['alignment'] = align.get(
             node.get('alignment').lower(), reportlab.lib.enums.TA_LEFT)
     return data
Example #9
0
    def _line_mode(self, node):
        ljoin = {'round': 1, 'mitered': 0, 'bevelled': 2}
        lcap = {'default': 0, 'round': 1, 'square': 2}

        if node.get('width'):
            self.canvas.setLineWidth(utils.unit_get(node.get('width')))
        if node.get('join'):
            self.canvas.setLineJoin(ljoin[node.get('join')])
        if node.get('cap'):
            self.canvas.setLineCap(lcap[node.get('cap')])
        if node.get('miterLimit'):
            self.canvas.setDash(utils.unit_get(node.get('miterLimit')))
        if node.get('dash'):
            dashes = node.get('dash').split(',')
            for x in range(len(dashes)):
                dashes[x] = utils.unit_get(dashes[x])
            self.canvas.setDash(node.get('dash').split(','))
Example #10
0
 def __init__(self, template, localcontext=None):
     self.frame_pos = -1
     self.localcontext = localcontext
     self.frames = []
     self.template_order = []
     self.page_template = {}
     self.loop = 0
     self._tags = {
         'drawString': _rml_tmpl_draw_string,
         'drawRightString': _rml_tmpl_draw_string,
         'drawCentredString': _rml_tmpl_draw_string,
         'lines': _rml_tmpl_draw_lines
     }
     self.style = _rml_draw_style()
     rc = 'data:image/png;base64,'
     self.data = ''
     for pt in template.findall('pageTemplate'):
         frames = {}
         id = pt.get('id')
         self.template_order.append(id)
         for tmpl in pt.findall('frame'):
             posy = int(utils.unit_get(tmpl.get('y1')))
             posx = int(utils.unit_get(tmpl.get('x1')))
             frames[(posy,posx,tmpl.get('id'))] = _rml_tmpl_frame(posx, utils.unit_get(tmpl.get('width')))
         for tmpl in pt.findall('pageGraphics'):
             for n in tmpl:
                 if n.tag == 'image':
                     self.data = rc + utils._process_text(self, n.text)
                 if n.tag in self._tags:
                     t = self._tags[n.tag](n, self.style,self.localcontext)
                     frames[(t.posy,t.posx,n.tag)] = t
                 else:
                     self.style.update(n)
         keys = frames.keys()
         keys.sort()
         keys.reverse()
         self.page_template[id] = []
         for key in range(len(keys)):
             if key>0 and keys[key-1][0] == keys[key][0]:
                 if type(self.page_template[id][-1]) == type(frames[keys[key]]):
                     if self.page_template[id][-1].tag_mergeable():
                         self.page_template[id][-1].merge(frames[keys[key]])
                     continue
             self.page_template[id].append(frames[keys[key]])
     self.template = self.template_order[0]
Example #11
0
 def __init__(self, node, style, localcontext = {}):
     self.localcontext = localcontext
     coord = [utils.unit_get(x) for x in utils._process_text(self, node.text).split(' ')]
     self.ok = False
     self.posx = coord[0]
     self.posy = coord[1]
     self.width = coord[2]-coord[0]
     self.ok = coord[1]==coord[3]
     self.style = style
     self.style = style.get('hr')
Example #12
0
 def setFont(self, node):
     fontname = node.get('name')
     if fontname not in pdfmetrics.getRegisteredFontNames()\
          or fontname not in pdfmetrics.standardFonts:
         # let reportlab attempt to find it
         try:
             pdfmetrics.getFont(fontname)
         except Exception:
             _logger.debug(
                 'Could not locate font %s, substituting default: %s',
                 fontname, self.canvas._fontname)
             fontname = self.canvas._fontname
     return self.canvas.setFont(fontname, utils.unit_get(node.get('size')))
Example #13
0
 def _rect(self, node):
     if node.get('round'):
         self.canvas.roundRect(radius=utils.unit_get(node.get('round')),
                               **utils.attr_get(
                                   node, ['x', 'y', 'width', 'height'], {
                                       'fill': 'bool',
                                       'stroke': 'bool'
                                   }))
     else:
         self.canvas.rect(
             **utils.attr_get(node, ['x', 'y', 'width', 'height'], {
                 'fill': 'bool',
                 'stroke': 'bool'
             }))
Example #14
0
 def _table_style_get(self, style_node):
     styles = []
     for node in style_node:
         start = utils.tuple_int_get(node, 'start', (0, 0))
         stop = utils.tuple_int_get(node, 'stop', (-1, -1))
         if node.tag == 'blockValign':
             styles.append(('VALIGN', start, stop, str(node.get('value'))))
         elif node.tag == 'blockFont':
             styles.append(('FONT', start, stop, str(node.get('name'))))
         elif node.tag == 'blockTextColor':
             styles.append(('TEXTCOLOR', start, stop,
                            color.get(str(node.get('colorName')))))
         elif node.tag == 'blockLeading':
             styles.append(('LEADING', start, stop,
                            utils.unit_get(node.get('length'))))
         elif node.tag == 'blockAlignment':
             styles.append(
                 ('ALIGNMENT', start, stop, str(node.get('value'))))
         elif node.tag == 'blockSpan':
             styles.append(('SPAN', start, stop))
         elif node.tag == 'blockLeftPadding':
             styles.append(('LEFTPADDING', start, stop,
                            utils.unit_get(node.get('length'))))
         elif node.tag == 'blockRightPadding':
             styles.append(('RIGHTPADDING', start, stop,
                            utils.unit_get(node.get('length'))))
         elif node.tag == 'blockTopPadding':
             styles.append(('TOPPADDING', start, stop,
                            utils.unit_get(node.get('length'))))
         elif node.tag == 'blockBottomPadding':
             styles.append(('BOTTOMPADDING', start, stop,
                            utils.unit_get(node.get('length'))))
         elif node.tag == 'blockBackground':
             styles.append(('BACKGROUND', start, stop,
                            color.get(node.get('colorName'))))
         if node.get('size'):
             styles.append(('FONTSIZE', start, stop,
                            utils.unit_get(node.get('size'))))
         elif node.tag == 'lineStyle':
             kind = node.get('kind')
             kind_list = [
                 'GRID', 'BOX', 'OUTLINE', 'INNERGRID', 'LINEBELOW',
                 'LINEABOVE', 'LINEBEFORE', 'LINEAFTER'
             ]
             assert kind in kind_list
             thick = 1
             if node.get('thickness'):
                 thick = float(node.get('thickness'))
             styles.append((kind, start, stop, thick,
                            color.get(node.get('colorName'))))
     return platypus.tables.TableStyle(styles)
Example #15
0
 def __init__(self, localcontext, stylesheet, doc):
     self.doc = doc
     self.localcontext = localcontext
     self.attrs = {}
     self._tags = {
         'fontSize': lambda x: ('font-size',str(utils.unit_get(x)+5.0)+'px'),
         'alignment': lambda x: ('text-align',str(x))
     }
     result = ''
     for ps in stylesheet.findall('paraStyle'):
         attr = {}
         attrs = ps.attrib
         for key, val in attrs.items():
             attr[key] = val
         attrs = []
         for a in attr:
             if a in self._tags:
                 attrs.append('%s:%s' % self._tags[a](attr[a]))
         if len(attrs):
             result += 'p.'+attr['name']+' {'+'; '.join(attrs)+'}\n'
     self.result = result
Example #16
0
 def _image(self, node):
     import urllib
     import urlparse
     from reportlab.lib.utils import ImageReader
     nfile = node.get('file')
     if not nfile:
         if node.get('name'):
             image_data = self.images[node.get('name')]
             _logger.debug("Image %s used", node.get('name'))
             s = StringIO(image_data)
         else:
             newtext = node.text
             if self.localcontext:
                 res = utils._regex.findall(newtext)
                 for key in res:
                     newtext = eval(key, {}, self.localcontext) or ''
             image_data = None
             if newtext:
                 image_data = base64.decodestring(newtext)
             if image_data:
                 s = StringIO(image_data)
             else:
                 _logger.debug("No image data!")
                 return False
     else:
         if nfile in self.images:
             s = StringIO(self.images[nfile])
         else:
             try:
                 up = urlparse.urlparse(str(nfile))
             except ValueError:
                 up = False
             if up and up.scheme:
                 # RFC: do we really want to open external URLs?
                 # Are we safe from cross-site scripting or attacks?
                 _logger.debug("Retrieve image from %s", nfile)
                 u = urllib.urlopen(str(nfile))
                 s = StringIO(u.read())
             else:
                 _logger.debug("Open image file %s ", nfile)
                 s = _open_image(nfile, path=self.path)
     try:
         img = ImageReader(s)
         (sx, sy) = img.getSize()
         _logger.debug("Image is %dx%d", sx, sy)
         args = {'x': 0.0, 'y': 0.0, 'mask': 'auto'}
         for tag in ('width', 'height', 'x', 'y'):
             if node.get(tag):
                 args[tag] = utils.unit_get(node.get(tag))
         if ('width' in args) and (not 'height' in args):
             args['height'] = sy * args['width'] / sx
         elif ('height' in args) and (not 'width' in args):
             args['width'] = sx * args['height'] / sy
         elif ('width' in args) and ('height' in args):
             if (float(args['width']) / args['height']) > (float(sx) > sy):
                 args['width'] = sx * args['height'] / sy
             else:
                 args['height'] = sy * args['width'] / sx
         self.canvas.drawImage(img, **args)
     finally:
         s.close()
Example #17
0
 def font_size_get(self,tag):
     size  = utils.unit_get(self.style.get('td', {}).get('font-size','16'))
     return size
Example #18
0
 def _translate(self, node):
     dx = utils.unit_get(node.get('dx')) or 0
     dy = utils.unit_get(node.get('dy')) or 0
     self.canvas.translate(dx, dy)
Example #19
0
    def _grid(self, node):
        xlist = [utils.unit_get(s) for s in node.get('xs').split(',')]
        ylist = [utils.unit_get(s) for s in node.get('ys').split(',')]

        self.canvas.grid(xlist, ylist)
Example #20
0
 def _tag_spacer(self, node):
     length = 1+int(utils.unit_get(node.get('length')))/35
     return "<br/>"*length
Example #21
0
    def _table(self, node):
        children = utils._child_get(node, self, 'tr')
        if not children:
            return None
        length = 0
        colwidths = None
        rowheights = None
        data = []
        styles = []
        posy = 0
        for tr in children:
            paraStyle = None
            if tr.get('style'):
                st = copy.deepcopy(self.styles.table_styles[tr.get('style')])
                for si in range(len(st._cmds)):
                    s = list(st._cmds[si])
                    s[1] = (s[1][0], posy)
                    s[2] = (s[2][0], posy)
                    st._cmds[si] = tuple(s)
                styles.append(st)
            if tr.get('paraStyle'):
                paraStyle = self.styles.styles[tr.get('paraStyle')]
            data2 = []
            posx = 0
            for td in utils._child_get(tr, self, 'td'):
                if td.get('style'):
                    st = copy.deepcopy(
                        self.styles.table_styles[td.get('style')])
                    for s in st._cmds:
                        s[1][1] = posy
                        s[2][1] = posy
                        s[1][0] = posx
                        s[2][0] = posx
                    styles.append(st)
                if td.get('paraStyle'):
                    # TODO: merge styles
                    paraStyle = self.styles.styles[td.get('paraStyle')]
                posx += 1

                flow = []
                for n in utils._child_get(td, self):
                    if n.tag == etree.Comment:
                        n.text = ''
                        continue
                    fl = self._flowable(n, extra_style=paraStyle)
                    if isinstance(fl, list):
                        flow += fl
                    else:
                        flow.append(fl)

                if not len(flow):
                    flow = self._textual(td)
                data2.append(flow)
            if len(data2) > length:
                length = len(data2)
                for ab in data:
                    while len(ab) < length:
                        ab.append('')
            while len(data2) < length:
                data2.append('')
            data.append(data2)
            posy += 1

        if node.get('colWidths'):
            assert length == len(node.get('colWidths').split(','))
            colwidths = [
                utils.unit_get(f.strip())
                for f in node.get('colWidths').split(',')
            ]
        if node.get('rowHeights'):
            rowheights = [
                utils.unit_get(f.strip())
                for f in node.get('rowHeights').split(',')
            ]
            if len(rowheights) == 1:
                rowheights = rowheights[0]
        table = platypus.LongTable(data=data,
                                   colWidths=colwidths,
                                   rowHeights=rowheights,
                                   **(utils.attr_get(node, ['splitByRow'], {
                                       'repeatRows': 'int',
                                       'repeatCols': 'int'
                                   })))
        if node.get('style'):
            table.setStyle(self.styles.table_styles[node.get('style')])
        for s in styles:
            table.setStyle(s)
        return table
Example #22
0
 def draw(self):
     self.canv.beginForm("pageCount%d" % self.story_count)
     self.canv.setFont("Helvetica", utils.unit_get(str(8)))
     self.canv.drawString(0, 0, str(self.canv.getPageNumber()))
     self.canv.endForm()
Example #23
0
    def _flowable(self, node, extra_style=None):
        if node.tag == 'pto':
            return self._pto(node)
        if node.tag == 'para':
            style = self.styles.para_style_get(node)
            if extra_style:
                style.__dict__.update(extra_style)
            result = []
            for i in self._textual(node).split('\n'):
                result.append(
                    platypus.Paragraph(
                        i, style,
                        **(utils.attr_get(node, [], {'bulletText': 'str'}))))
            return result
        elif node.tag == 'barCode':
            try:
                from reportlab.graphics.barcode import code128
                from reportlab.graphics.barcode import code39
                from reportlab.graphics.barcode import code93
                from reportlab.graphics.barcode import common
                from reportlab.graphics.barcode import fourstate
                from reportlab.graphics.barcode import usps
                from reportlab.graphics.barcode import createBarcodeDrawing

            except ImportError:
                _logger.warning("Cannot use barcode renderers:", exc_info=True)
                return None
            args = utils.attr_get(
                node, [], {
                    'ratio': 'float',
                    'xdim': 'unit',
                    'height': 'unit',
                    'checksum': 'int',
                    'quiet': 'int',
                    'width': 'unit',
                    'stop': 'bool',
                    'bearers': 'int',
                    'barWidth': 'float',
                    'barHeight': 'float'
                })
            codes = {
                'codabar':
                lambda x: common.Codabar(x, **args),
                'code11':
                lambda x: common.Code11(x, **args),
                'code128':
                lambda x: code128.Code128(str(x), **args),
                'standard39':
                lambda x: code39.Standard39(str(x), **args),
                'standard93':
                lambda x: code93.Standard93(str(x), **args),
                'i2of5':
                lambda x: common.I2of5(x, **args),
                'extended39':
                lambda x: code39.Extended39(str(x), **args),
                'extended93':
                lambda x: code93.Extended93(str(x), **args),
                'msi':
                lambda x: common.MSI(x, **args),
                'fim':
                lambda x: usps.FIM(x, **args),
                'postnet':
                lambda x: usps.POSTNET(x, **args),
                'ean13':
                lambda x: createBarcodeDrawing('EAN13', value=str(x), **args),
                'qrcode':
                lambda x: createBarcodeDrawing('QR', value=x, **args),
            }
            code = 'code128'
            if node.get('code'):
                code = node.get('code').lower()
            return codes[code](self._textual(node))
        elif node.tag == 'name':
            self.styles.names[node.get('id')] = node.get('value')
            return None
        elif node.tag == 'xpre':
            style = self.styles.para_style_get(node)
            return platypus.XPreformatted(
                self._textual(node), style,
                **(utils.attr_get(node, [], {
                    'bulletText': 'str',
                    'dedent': 'int',
                    'frags': 'int'
                })))
        elif node.tag == 'pre':
            style = self.styles.para_style_get(node)
            return platypus.Preformatted(
                self._textual(node), style,
                **(utils.attr_get(node, [], {
                    'bulletText': 'str',
                    'dedent': 'int'
                })))
        elif node.tag == 'illustration':
            return self._illustration(node)
        elif node.tag == 'blockTable':
            return self._table(node)
        elif node.tag == 'title':
            styles = reportlab.lib.styles.getSampleStyleSheet()
            style = styles['Title']
            return platypus.Paragraph(
                self._textual(node), style,
                **(utils.attr_get(node, [], {'bulletText': 'str'})))
        elif re.match('^h([1-9]+[0-9]*)$', (node.tag or '')):
            styles = reportlab.lib.styles.getSampleStyleSheet()
            style = styles['Heading' + str(node.tag[1:])]
            return platypus.Paragraph(
                self._textual(node), style,
                **(utils.attr_get(node, [], {'bulletText': 'str'})))
        elif node.tag == 'image':
            image_data = False
            if not node.get('file'):
                if node.get('name'):
                    if node.get('name') in self.doc.images:
                        _logger.debug("Image %s read ", node.get('name'))
                        image_data = self.doc.images[node.get('name')].read()
                    else:
                        _logger.warning("Image %s not defined",
                                        node.get('name'))
                        return False
                else:
                    import base64
                    newtext = node.text
                    if self.localcontext:
                        newtext = utils._process_text(self, node.text or '')
                    image_data = base64.decodestring(newtext)
                if not image_data:
                    _logger.debug("No inline image data")
                    return False
                image = StringIO(image_data)
            else:
                _logger.debug("Image get from file %s", node.get('file'))
                image = _open_image(node.get('file'), path=self.doc.path)
            return platypus.Image(image,
                                  mask=(250, 255, 250, 255, 250, 255),
                                  **(utils.attr_get(node,
                                                    ['width', 'height'])))
        elif node.tag == 'spacer':
            if node.get('width'):
                width = utils.unit_get(node.get('width'))
            else:
                width = utils.unit_get('1cm')
            length = utils.unit_get(node.get('length'))
            return platypus.Spacer(width=width, height=length)
        elif node.tag == 'section':
            return self.render(node)
        elif node.tag == 'pageNumberReset':
            return PageReset()
        elif node.tag in ('pageBreak', 'nextPage'):
            return platypus.PageBreak()
        elif node.tag == 'condPageBreak':
            return platypus.CondPageBreak(**(utils.attr_get(node, ['height'])))
        elif node.tag == 'setNextTemplate':
            return platypus.NextPageTemplate(str(node.get('name')))
        elif node.tag == 'nextFrame':
            return platypus.CondPageBreak(1000)  # TODO: change the 1000 !
        elif node.tag == 'setNextFrame':
            from reportlab.platypus.doctemplate import NextFrameFlowable
            return NextFrameFlowable(str(node.get('name')))
        elif node.tag == 'currentFrame':
            from reportlab.platypus.doctemplate import CurrentFrameFlowable
            return CurrentFrameFlowable(str(node.get('name')))
        elif node.tag == 'frameEnd':
            return EndFrameFlowable()
        elif node.tag == 'hr':
            width_hr = node.get('width') or '100%'
            color_hr = node.get('color') or 'black'
            thickness_hr = node.get('thickness') or 1
            lineCap_hr = node.get('lineCap') or 'round'
            return platypus.flowables.HRFlowable(width=width_hr,
                                                 color=color.get(color_hr),
                                                 thickness=float(thickness_hr),
                                                 lineCap=str(lineCap_hr))
        else:
            sys.stderr.write('Warning: flowable not yet implemented: %s !\n' %
                             (node.tag, ))
            return None
Example #24
0
 def _curves(self, node):
     line_str = node.text.split()
     lines = []
     while len(line_str) > 7:
         self.canvas.bezier(*[utils.unit_get(l) for l in line_str[0:8]])
         line_str = line_str[8:]