def vector(self, e): scale = float(e.get('scale', '1.0')) width = toLength(e.get('width')) height = toLength(e.get('height')) path = e.get('src') search = e.get('search', None) replace = e.get('replace', None) fh = open(self.get_from_url(path), 'rb') data = fh.read() fh.close() if search is not None: data = data.replace(search, replace) svg = xml.dom.minidom.parseString(data).documentElement svgRenderer = SvgRenderer() svgRenderer.render(svg) svg_obj = svgRenderer.finish() svg_obj.scale(scale, scale) svg_obj.asDrawing(width, height) yield svg_obj
def doc(self, e): format = e.get('format', 'A4') raw_margins = e.get('margin', '2cm, 2cm, 2cm, 2cm') title = e.get('title') if ',' in format: w, h = (toLength(i.strip()) for i in format.split(',')) format = (w, h) else: format = eval('pagesizes.' + format) topMargin, rightMargin, bottomMargin, leftMargin = (toLength(i.strip()) for i in raw_margins.split(',')) def make_canvas(*args, **kwargs): canvas = Canvas(*args, **kwargs) canvas.setLineWidth(0.25) return canvas if self.document is None: self.document = SimpleDocTemplate(self.out_buffer, pagesize=format, title=title, topMargin=topMargin, leftMargin=leftMargin, rightMargin=rightMargin, bottomMargin=bottomMargin, canvasmaker=make_canvas) for i in self.parse_children(e): yield i
def vector(self, e): scale = float(e.get('scale', '1.0')) width = toLength(e.get('width')) height = toLength(e.get('height')) path = e.get('src') search = e.get('search', None) replace = e.get('replace', None) fh = open(self.media_root + path, 'rb') data = fh.read() fh.close() if search is not None: data = data.replace(search, replace) import xml.dom.minidom svg = xml.dom.minidom.parseString(data).documentElement from svglib.svglib import SvgRenderer svgRenderer = SvgRenderer() svgRenderer.render(svg) svg_obj = svgRenderer.finish() svg_obj.scale(scale, scale) svg_obj.asDrawing(width, height) yield svg_obj
def sign(self, e): text = e.get('text') scale = float(e.get('scale', '1.0')) width = toLength(e.get('width')) height = toLength(e.get('height')) template = """ <table cols="9.9cm, 1.9cm" align="right"> <tstyle padding="0" /> <tstyle area="0,0:-1,-1" padding-left="0.5cm"/> <tr> <td> <p>................................................................</p> <p><font size="8pt">{text}</font></p> </td> <td> <vector src="common/pdf_img/left-pointing-arrow.svg" scale="{scale}" width="{width}" height="{height}" /> </td> </tr> </table> """.format( text=text, scale=scale, width=width, height=height, ) element = self.parse_parts(template) for i in element: yield i
def __init__(self, labelsacross, labelsdown, labelwidth, labelheight, horizlabelgap, vertlabelgap, pagesize=A4): self.width = toLength(labelwidth) self.height = toLength(labelheight) self._pagesize = pagesize horizlabelgap = toLength(horizlabelgap) vertlabelgap = toLength(vertlabelgap) pagewidth = pagesize[0] pageheight = pagesize[1] sidemargin = (pagewidth - (self.width * labelsacross) - (horizlabelgap * (labelsacross - 1))) / 2 endmargin = (pageheight - (self.height * labelsdown) - (vertlabelgap * (labelsdown - 1))) / 2 self.label = 0 self.ll = [] for y in range(0, labelsdown): for x in range(0, labelsacross): # We assume that labels are centered top-to-bottom # and left-to-right, and that the gaps between them # are consistent. The page origin is in the bottom-left. # We record the bottom-left-hand corner of each label. xpos = sidemargin + ((self.width + horizlabelgap) * x) ypos = (pageheight - endmargin - ((self.height + vertlabelgap) * y) - self.height) self.ll.append((xpos, ypos))
def parseLength(length): """ Convert length to reportlab points. """ match = length_match(length) if match is None: raise SVGError("Not a valid length unit: '%s'" % length) value = match.group('value') unit = match.group('unit') or '' if not value: raise SVGError("Not a valid length unit: '%s'" % length) if not unit: if value[0] == 'e' or value[0] == 'E': return float('1' + value) else: return float(value) elif unit in ('em', 'ex', 'px', '%'): # ignoring relative units return float(value) elif unit == 'pc': return toLength(value + 'pica') elif unit in ('mm', 'cm', 'in', 'i', 'pt', 'pica'): return toLength(length) else: raise SVGError("Unknown unit '%s'" % unit)
def doc(self, e): format = e.get('format', 'A4') raw_margins = e.get('margin', '2cm, 2cm, 2cm, 2cm') title = e.get('title') if ',' in format: w, h = (toLength(i.strip()) for i in format.split(',')) format = (w, h) else: format = eval('pagesizes.' + format.upper()) topMargin, rightMargin, bottomMargin, leftMargin = (toLength( i.strip()) for i in raw_margins.split(',')) def make_canvas(*args, **kwargs): canvas = Canvas(*args, **kwargs) canvas.setLineWidth(0.25) return canvas if self.document is None: self.document = SimpleDocTemplate(self.out_buffer, pagesize=format, title=title, topMargin=topMargin, leftMargin=leftMargin, rightMargin=rightMargin, bottomMargin=bottomMargin, canvasmaker=make_canvas) for i in self.parse_children(e): yield i
def img(self, e): width = toLength(e.get('width')) height = toLength(e.get('height')) path = e.get('src') align = e.get('align', 'left').upper() img_obj = Image(self.get_from_url(path), width=width, height=height) img_obj.hAlign = align yield img_obj
def convertLength(self, svgAttr, percentOf=100): "Convert length to points." text = svgAttr if not text: return 0.0 if text[-1] == '%': if LOGMESSAGES: print "Fiddling length unit: %" return float(text[:-1]) / 100 * percentOf elif text[-2:] == "pc": return float(text[:-2]) * pica newSize = text[:] for u in "em ex px".split(): if newSize.find(u) >= 0: if LOGMESSAGES: print "Ignoring unit: %s" % u newSize = newSize.replace(u, '') newSize = newSize.strip() length = toLength(newSize) return length
def convert_length(value, percent_of=100, em_base=12): """ Convert length to points """ text = value if not text: return 0.0 if ' ' in text.replace(',', ' ').strip(): _logger.debug("Only getting first value of %s" % text) text = text.replace(',', ' ').split()[0] if text[-1] == '%': _logger.debug("Fiddling length unit: %") return float(text[:-1]) / 100 * percent_of elif text[-2:] == "pc": return float(text[:-2]) * units.pica elif text.endswith("pt"): return float(text[:-2]) * 1.25 elif text.endswith("em"): return float(text[:-2]) * em_base elif text.endswith("px"): return float(text[:-2]) if "ex" in text: _logger.warn("Ignoring unit ex in '%s'" % value) text = text.replace("ex", '') text = text.strip() length = units.toLength(text) return length
def convertLength(self, svgAttr, percentOf=100): "Convert length to points." text = svgAttr if not text: return 0.0 if ' ' in text.replace(',', ' ').strip(): logger.debug("Only getting first value of %s" % text) text = text.replace(',', ' ').split()[0] if text.endswith('%'): logger.debug("Fiddling length unit: %") return float(text[:-1]) / 100 * percentOf elif text.endswith("pc"): return float(text[:-2]) * pica elif text.endswith("pt"): return float(text[:-2]) * 1.25 for unit in ("em", "ex", "px"): if unit in text: logger.warn("Ignoring unit: %s" % unit) text = text.replace(unit, '') text = text.strip() length = toLength(text) return length
def convertLength(self, svgAttr, percentOf=100, em_base=12): "Convert length to points." text = svgAttr if not text: return 0.0 if ' ' in text.replace(',', ' ').strip(): logger.debug("Only getting first value of %s" % text) text = text.replace(',', ' ').split()[0] if text.endswith('%'): logger.debug("Fiddling length unit: %") return float(text[:-1]) / 100 * percentOf elif text.endswith("pc"): return float(text[:-2]) * pica elif text.endswith("pt"): return float(text[:-2]) * 1.25 elif text.endswith("em"): return float(text[:-2]) * em_base elif text.endswith("px"): return float(text[:-2]) if "ex" in text: logger.warn("Ignoring unit ex") text = text.replace("ex", '') text = text.strip() length = toLength(text) # this does the default measurements such as mm and cm return length
def barcode(self, e): scale = float(e.get('scale', '1.0')) width = toLength(e.get('width')) height = toLength(e.get('height')) value = e.get('value') align = e.get('align', 'left').upper() type = e.get('type', 'datamatrix') barcode_obj = Barcode(library=self.barcode_library, width=width, height=height, data=value, scale=scale, type=type, align=align.lower()) barcode_obj.hAlign = align yield barcode_obj
def vector(self, e): scale = float(e.get('scale', '1.0')) width = toLength(e.get('width')) height = toLength(e.get('height')) path = e.get('src') search = e.get('search', None) replace = e.get('replace', None) with open(self.get_from_url(path), 'rb') as fh: data = fh.read() if search is not None: data = data.replace(search, replace) svg = etree.fromstring(data) renderer = SvgRenderer() drawing = renderer.render(svg) drawing.scale(scale, scale) drawing.asDrawing(width, height) yield drawing
def img(self, e): width = toLength(e.get('width')) height = toLength(e.get('height')) path = e.get('src') align = e.get('align', 'left').upper() background = e.get('background', 'False') == 'True' vAlign = e.get('vertical-align', 'BOTTOM').upper() if background: img_obj = BackgroundImage( filename=self.get_from_url(path), width=width, height=height, hAlign=align, vAlign=vAlign) else: img_obj = Image(filename=self.get_from_url(path), width=width, height=height) img_obj.hAlign = align yield img_obj
def img(self, e): width = toLength(e.get('width')) height = toLength(e.get('height')) path = e.get('src') align = e.get('align', 'left').upper() background = e.get('background', 'False') == 'True' vAlign = e.get('vertical-align', 'BOTTOM').upper() if background: img_obj = BackgroundImage(filename=self.get_from_url(path), width=width, height=height, hAlign=align, vAlign=vAlign) else: img_obj = Image(filename=self.get_from_url(path), width=width, height=height) img_obj.hAlign = align yield img_obj
def print_card(user, barcode): PAGE_HEIGHT = toLength('2.125in') PAGE_WIDTH = toLength('3.37in') XCENTER = PAGE_WIDTH / 2.0 YCENTER = PAGE_HEIGHT / 2.0 pdffile = NamedTemporaryFile() if user.first_name: username = '******' % (user.first_name, user.last_name) else: username = user.username c = canvas.Canvas(pdffile.name, pagesize=(PAGE_WIDTH, PAGE_HEIGHT)) if hasattr(settings, 'PRINT_CARD_IMAGES'): for img in settings.PRINT_CARD_IMAGES: c.drawImage(barcode if img['img'] == '$barcode$' else img['img'], toLength(img['x']), toLength(img['y']), width=(toLength(img['width'])), height=(toLength(img['height'])), preserveAspectRatio=True) if hasattr(settings, 'PRINT_CARD_TEXT'): for msg in settings.PRINT_CARD_TEXT: c.setFont(msg['font'], msg['size']) c.drawCentredString( toLength(msg.get('x', XCENTER)), toLength(msg.get('y', YCENTER)), username if msg['text'] == '$username$' else msg['text']) c.showPage() if hasattr(settings, 'PRINT_BACK_IMAGE'): if os.path.isdir(settings.PRINT_BACK_IMAGE): back_image = '%s/%s' % (settings.PRINT_BACK_IMAGE, random.choice( os.listdir(settings.PRINT_BACK_IMAGE)) ) # This is so ugly. elif os.path.isfile(settings.PRINT_BACK_IMAGE): back_image = settings.PRINT_BACK_IMAGE c.drawImage(back_image, 0, 0, width=PAGE_WIDTH, height=PAGE_HEIGHT) c.showPage() c.save() try: printer = '-d %s' % settings.PRINTER except NameError: printer = '' printjob = Popen('lp -s %s %s' % (printer, pdffile.name), shell=True) printjob.wait()
def tstyle(self, e): area = e.get('area', '0:-1') topleft, bottomright = (list(int(q) for q in p.split(',')) for p in area.split(':')) top = topleft[0] left = topleft[-1] bottom = bottomright[0] right = bottomright[-1] cells = [(top, left), (bottom, right)] tstyle_dict = dict(e.attrib) if 'area' in tstyle_dict: del tstyle_dict['area'] if 'border' in tstyle_dict: border = tstyle_dict['border'] tstyle_dict.update({ 'border-left': border, 'border-right': border, 'border-top': border, 'border-bottom': border }) del tstyle_dict['border'] if 'padding' in tstyle_dict: padding = tstyle_dict['padding'] tstyle_dict.update({ 'padding-left': padding, 'padding-right': padding, 'padding-top': padding, 'padding-bottom': padding }) del tstyle_dict['padding'] for key in tstyle_dict.keys(): value = tstyle_dict[key] desc = CSS_DICT.get(key, key.upper()) params = value.split(',') for i in xrange(len(params)): param = params[i].strip() if param[0] == '#': params[i] = colors.HexColor(eval('0x' + param[1:])) else: try: floatval = toLength(param) params[i] = floatval except ValueError: params[i] = param.upper() yield [desc] + cells + params
def __init__(self, filename, tickets, fields, req, pagesize='A4', stickysize=(75, 75), fontname='(auto)'): self.req = req self.tz = req.tz locale = None if hasattr(req, 'locale'): locale = req.locale self.filename = filename self.tickets = tickets self.pagesize = self._get_pagesize(pagesize) self.stickysize = [units.toLength('%gmm' % val) for val in stickysize] self.fontname = self._setup_font(fontname, locale) self.fields = fields
def print_card(user, barcode): PAGE_HEIGHT = toLength('2.125in') PAGE_WIDTH = toLength('3.37in') XCENTER = PAGE_WIDTH / 2.0 YCENTER = PAGE_HEIGHT / 2.0 pdffile = NamedTemporaryFile() if user.first_name: username = '******' % (user.first_name, user.last_name) else: username = user.username c = canvas.Canvas(pdffile.name, pagesize=(PAGE_WIDTH, PAGE_HEIGHT)) if hasattr(settings, 'PRINT_CARD_IMAGES'): for img in settings.PRINT_CARD_IMAGES: c.drawImage(barcode if img['img'] == '$barcode$' else img['img'], toLength(img['x']), toLength(img['y']), width=(toLength(img['width'])), height=(toLength(img['height'])), preserveAspectRatio=True) if hasattr(settings, 'PRINT_CARD_TEXT'): for msg in settings.PRINT_CARD_TEXT: c.setFont(msg['font'], msg['size']) c.drawCentredString(toLength(msg.get('x', XCENTER)), toLength(msg.get('y', YCENTER)), username if msg['text'] == '$username$' else msg['text']) c.showPage() if hasattr(settings, 'PRINT_BACK_IMAGE'): if os.path.isdir(settings.PRINT_BACK_IMAGE): back_image = '%s/%s' % (settings.PRINT_BACK_IMAGE, random.choice(os.listdir(settings.PRINT_BACK_IMAGE))) # This is so ugly. elif os.path.isfile(settings.PRINT_BACK_IMAGE): back_image = settings.PRINT_BACK_IMAGE c.drawImage(back_image, 0, 0, width=PAGE_WIDTH, height=PAGE_HEIGHT) c.showPage() c.save() try: printer = '-d %s' % settings.PRINTER except NameError: printer = '' printjob = Popen('lp -s %s %s' % (printer, pdffile.name), shell=True) printjob.wait()
def table(self, e): cols = [toLength(i.strip()) for i in e.get('cols').split(',')] height = e.get('height') if height and len(height.split(',')) > 1: height = [toLength(i.strip()) for i in height.split(',')] elif height: height = toLength(height) align = e.get('align', 'left').upper() tstyles = [] rows = [] for c in e: if c.tag == 'tstyle': tstyles += list(self.tstyle(c)) else: rows.append(list(self.parse_element(c))) table_obj = Table(rows, cols, rowHeights=height, hAlign=align, style=tstyles) yield table_obj
def table(self, e): cols = [toLength(i.strip()) for i in e.get('cols').split(',')] align = e.get('align', 'left').upper() tstyles = [] rows = [] for c in e: if c.tag == 'tstyle': tstyles += list(self.tstyle(c)) else: rows.append(list(self.parse_element(c))) table_obj = Table(rows, cols, hAlign=align, style=tstyles) yield table_obj
def _lengthToFloat(self,value): v = value if not self.re_digits.search(v): return v try: if v[-4:] == "inch": # OO files use "inch" instead of "in" in Reportlab units v = v[:-2] except: pass try: c = round(toLength(v)) return c except: return v
def _lengthToFloat(self, value): v = value if not self.re_digits.search(v): return v try: if v[-4:] == "inch": # OO files use "inch" instead of "in" in Reportlab units v = v[:-2] except: pass try: c = round(toLength(v)) return c except: return v
def parse_paragraph_style(self, raw_style): if '=' in raw_style: # define name, definition = (i.strip() for i in raw_style.split('=', 1)) if '+' in definition: source_name, definition = (i.strip() for i in definition.split('+', 1)) else: source_name = None def_dict = eval(definition) new_dict = {} for k in def_dict.keys(): v = def_dict[k] nk = CSS_DICT.get(k, k) # translate v v = CSS_DICT.get(v, v) if nk == 'fontSize' or nk == 'leading': v = toLength(v) elif nk == 'color': v = colors.HexColor(eval('0x' + v[1:])) new_dict[nk] = v if 'leading' not in new_dict and 'fontSize' in new_dict: new_dict['leading'] = new_dict['fontSize'] * 1.5 # + 2.0 if source_name is not None: source_dict = self.styles[source_name].__dict__.copy() source_dict.update(new_dict) new_dict = source_dict new_dict.update({'name': name}) if name in self.styles: self.styles[name].__dict__.update(new_dict) else: self.styles.add(ParagraphStyle(**new_dict)) else: name = raw_style.strip() if name == 'end' or name == '': self.style_stack.pop() elif name in self.styles: style = self.styles[name] self.style_stack.append(style)
def getPt(val): """Get numeric pt value from string value. Strings can have the unit appended, like "3.5 in", "2 cm", "3 pica", "10 mm". > print self.getPt("1 in") 72 > print self.getPt("1") 1 > print self.getPt(1) 1 """ if isinstance(val, (int, long, float)): # return as-is as the pt value. return val else: # try to run it through reportlab's units.toLength() function: return units.toLength(val)
def parse_paragraph_style(self, raw_style): if '=' in raw_style: # define name, definition = (i.strip() for i in raw_style.split('=', 1)) if '+' in definition: source_name, definition = (i.strip() for i in definition.split('+', 1)) else: source_name = None def_dict = eval(definition) new_dict = {} for k in def_dict.keys(): v = def_dict[k] nk = CSS_DICT.get(k, k) # translate v v = CSS_DICT.get(v, v) if nk == 'fontSize' or nk == 'leading': v = toLength(v) elif nk == 'color': v = colors.HexColor(eval('0x' + v[1:])) new_dict[nk] = v if not new_dict.has_key('leading') and new_dict.has_key('fontSize'): new_dict['leading'] = new_dict['fontSize'] + 2.0 if source_name is not None: source_dict = self.styles[source_name].__dict__.copy() source_dict.update(new_dict) new_dict = source_dict new_dict.update({'name': name}) if self.styles.has_key(name): self.styles[name].__dict__.update(new_dict) else: self.styles.add(ParagraphStyle(**new_dict)) else: name = raw_style.strip() if name == 'end' or name == '': self.style_stack.pop() elif self.styles.has_key(name): style = self.styles[name] self.style_stack.append(style)
def style(self, e): name = e.get('name') source_name = e.get('base', None) def_dict = dict(e.attrib) del def_dict['name'] if 'base' in def_dict: del def_dict['base'] new_dict = {} for k in def_dict.keys(): v = def_dict[k] nk = CSS_DICT.get(k, k) # translate v v = CSS_DICT.get(v, v) if nk == 'fontSize' or nk == 'leading': v = toLength(v) elif nk == 'color': v = colors.HexColor(eval('0x' + v[1:])) new_dict[nk] = v if 'leading' not in new_dict and 'fontSize' in new_dict: new_dict['leading'] = new_dict['fontSize'] * 1.5 # + 2.0 if source_name is not None: source_dict = self.styles[source_name].__dict__.copy() source_dict.update(new_dict) new_dict = source_dict new_dict.update({'name': name}) if name in self.styles: self.styles[name].__dict__.update(new_dict) else: self.styles.add(ParagraphStyle(**new_dict)) # make this function an empty generator if False: yield
def style(self, e): name = e.get('name') source_name = e.get('base', None) def_dict = dict(e.attrib) del def_dict['name'] if 'base' in def_dict: del def_dict['base'] new_dict = {} for k in def_dict.keys(): v = def_dict[k] nk = CSS_DICT.get(k, k) # translate v v = CSS_DICT.get(v, v) if nk == 'fontSize' or nk == 'leading': v = toLength(v) elif nk == 'color': v = colors.HexColor(eval('0x' + v[1:])) new_dict[nk] = v if not new_dict.has_key('leading') and new_dict.has_key('fontSize'): new_dict['leading'] = new_dict['fontSize'] + 2.0 if source_name is not None: source_dict = self.styles[source_name].__dict__.copy() source_dict.update(new_dict) new_dict = source_dict new_dict.update({'name': name}) if self.styles.has_key(name): self.styles[name].__dict__.update(new_dict) else: self.styles.add(ParagraphStyle(**new_dict)) # make this function an empty generator if False: yield
def handle_document_properties(self, raw_properties, title): format, raw_unit, raw_margins = raw_properties.split(';') format = A4 unit = toLength('1%s' % raw_unit) self.unit = unit topMargin, rightMargin, bottomMargin, leftMargin = (float(i) for i in raw_margins.split(',')) if self.doc is not None: return def make_canvas(*args, **kwargs): canvas = Canvas(*args, **kwargs) canvas.setLineWidth(0.25) return canvas self.doc = SimpleDocTemplate(self.out_buffer, pagesize=format, title=title, topMargin=topMargin*unit, leftMargin=leftMargin*unit, rightMargin=rightMargin*unit, bottomMargin=bottomMargin*unit, canvasmaker=make_canvas)
def handle_document_properties(self, raw_properties, title): format, raw_unit, raw_margins = raw_properties.split(';') format = A4 unit = toLength('1%s' % raw_unit) self.unit = unit topMargin, rightMargin, bottomMargin, leftMargin = ( float(i) for i in raw_margins.split(',')) if self.doc is not None: return def make_canvas(*args, **kwargs): canvas = Canvas(*args, **kwargs) canvas.setLineWidth(0.25) return canvas self.doc = SimpleDocTemplate(self.out_buffer, pagesize=format, title=title, topMargin=topMargin * unit, leftMargin=leftMargin * unit, rightMargin=rightMargin * unit, bottomMargin=bottomMargin * unit, canvasmaker=make_canvas)
def spacer(self, e): width = toLength(e.get('width', '1pt')) height = toLength(e.get('height')) yield Spacer(width, height)
def parse_parts(self, buffer): # prepare ReportLab self.styles = getSampleStyleSheet() self.style_stack.append(self.styles['Normal']) if self.out_buffer is None: self.out_buffer = StringIO() self.parts = [] # prepare for parsing i = 0 buffer_len = len(buffer) # Possible modes: 0 = normal, 1 = table row, 2 = insert object mode = 0 new_line = True new_para = True cue = 0 content = '' raw_table_data = '' self.reset_table() obj = None style_stack = self.style_stack paragraphs = split_ignore(buffer, '\n\n', '[[[block', ']]]') for p in paragraphs: lines = p.split('\n') content = '' for line in lines: c = line[:1] if c == '#': debug_print('[comment]') elif c == '$': self.parse_paragraph_style(line[1:]) elif c == '~': debug_print('[document element %s]' % line[1]) elem = line[1] endpos = line.find(']', 2) if elem == 'D': self.handle_document_properties( line[3:endpos], line[endpos + 1:]) elif elem == 'T': if line[2] == '$': # table style raw_style = line[3:] style = self.parse_table_style(raw_style) self.table_styles.append(style) else: self.table_cols = list( float(n) * self.unit for n in line[3:endpos].split('|')) align = line[endpos + 1:endpos + 2] if align == '<': self.table_align = 'LEFT' elif align == '>': self.table_align = 'RIGHT' elif elem == 'B': self.append_to_parts(PageBreak()) elif elem == 'S': self.append_to_parts(Spacer(1, toLength(line[2:]))) elif elem == 'V': svg_info_raw = line[3:endpos] svg_info = svg_info_raw.split(';')[:7] if len(svg_info) == 1: mode = 2 obj = self.svg_dict[svg_info[0]] else: if len(svg_info) == 7: svg_name, svg_scale, svg_w, svg_h, svg_path, svg_find, svg_replace = svg_info else: svg_name, svg_scale, svg_w, svg_h, svg_path = svg_info svg_file = open(find(svg_path), 'rb') svg_data = svg_file.read() svg_file.close() if len(svg_info) == 7: svg_data = svg_data.replace( svg_find, svg_replace) svg = xml.dom.minidom.parseString( svg_data).documentElement svgRenderer = SvgRenderer() svgRenderer.render(svg) svg_obj = svgRenderer.finish() # svg_obj = svg2rlg(settings.MEDIA_ROOT + svg_path) svg_obj.scale(float(svg_scale), float(svg_scale)) svg_obj.asDrawing( float(svg_w) * self.unit, float(svg_h) * self.unit) self.svg_dict[svg_name] = svg_obj elif elem == 'I': img_info_raw = line[3:endpos] img_info = img_info_raw.split(';')[:4] if len(img_info) == 1: mode = 2 obj = self.img_dict[img_info[0]] else: img_name, img_w, img_h, img_path = img_info img_obj = Image(find(img_path), width=self.unit * float(img_w), height=self.unit * float(img_h)) align = line[endpos + 1:endpos + 2] if align == '<': img_obj.hAlign = 'LEFT' elif align == '>': img_obj.hAlign = 'RIGHT' self.img_dict[img_name] = img_obj elif elem == 'C': barcode_info_raw = line[3:endpos] barcode_info = barcode_info_raw.split(';')[:6] if len(barcode_info) == 1: mode = 2 obj = self.img_dict[barcode_info[0]] else: barcode_name, barcode_type, barcode_scale, barcode_w, barcode_h, barcode_data = barcode_info barcode_obj = Barcode( library=find('common/pdf_img/barcode.ps'), width=self.unit * float(barcode_w), height=self.unit * float(barcode_h), data=barcode_data, scale=float(barcode_scale), type=barcode_type) align = line[endpos + 1:endpos + 2] if align == '<': barcode_obj.hAlign = 'LEFT' elif align == '>': barcode_obj.hAlign = 'RIGHT' self.img_dict[barcode_name] = barcode_obj elif elem == 'F': font_info_raw = line[3:endpos] font_info = font_info_raw.split(';')[:2] self.import_pdf_font(font_info[1], font_info[0]) elif elem == 'P': if '[' in line: self.parts_buffer = line[3:endpos] self.parts_buffer_dict[self.parts_buffer] = [] else: self.parts_buffer = None elif elem == 'E': args = line[2:].split(';') name, width, height, value = args self.append_to_parts( TextField(name, int(width), int(height), value)) elif c == '[': mode = 1 raw_table_data += line + '\n' elif c == '\n': pass else: if mode == 0: content += line + '\n' elif mode == 1: raw_table_data += line + '\n' if mode == 0: if content != '': self.append_to_parts( Paragraph( content, self.style_stack[-1] if len(self.style_stack) > 0 else self.styles['Normal'])) content = '' if mode == 1: td = raw_table_data td_len = len(td) i = 0 while i < td_len: c = td[i] c_1 = td[i - 1:i] if c == '[' and c_1 != '\\': cue = i + 1 if (c == '|' or c == ']') and c_1 != '\\': cell_content = td[cue:i] pop_after_cell = False if cell_content[:1] == '$': if ' ' in cell_content: style, cell_content = cell_content.split( None, 1) style = style[1:] else: style = '' cell_content = cell_content[1:] self.parse_paragraph_style(style) if cell_content[-1:] == '$': cell_content = cell_content[:-1] pop_after_cell = True if cell_content[:2] == '~V': svg_name = cell_content[2:] self.table_row.append(self.svg_dict[svg_name]) elif cell_content[:2] == '~I': img_name = cell_content[2:] self.table_row.append(self.img_dict[img_name]) elif cell_content[:2] == '~P': self.table_row.append( self.parts_buffer_dict[cell_content[2:]]) else: self.table_row.append( Paragraph( cell_content, self.style_stack[-1] if len(self.style_stack) > 0 else self.styles['Normal'])) if pop_after_cell: self.parse_paragraph_style('') cue = i + 1 if c == ']': self.table_data.append(self.table_row) self.table_row = [] i += 1 if len(self.table_data) > 0: self.append_to_parts( Table(self.table_data, self.table_cols, hAlign=self.table_align, style=self.table_styles)) self.reset_table() raw_table_data = '' if mode == 2: if obj is not None: self.append_to_parts(obj) obj = None mode = 0 return self.parts
def get_unit_factor(name, default=1): from reportlab.lib.units import toLength if name: return toLength('1' + name) else: return default
def test_parseLength(self): self.assertTrue(parseLength('50%') == 50.) self.assertTrue(parseLength('50') == toLength('50')) self.assertTrue(parseLength('-646.595') == -646.595) self.assertTrue(parseLength('50em') == toLength('50')) self.assertTrue(parseLength('50ex') == toLength('50')) self.assertTrue(parseLength('50px') == toLength('50')) self.assertTrue(parseLength('50pc') == toLength('50pica')) self.assertTrue(parseLength('50pica') == toLength('50pica')) self.assertTrue(parseLength('50mm') == toLength('50mm')) self.assertTrue(parseLength('50cm') == toLength('50cm')) self.assertTrue(parseLength('50in') == toLength('50in')) self.assertTrue(parseLength('50i') == toLength('50i')) self.assertTrue(parseLength('50pt') == toLength('50pt')) self.assertTrue(parseLength('e-014') == 1e-14) self.assertRaises(SVGError, parseLength, 'mm') self.assertRaises(SVGError, parseLength, '50km') self.assertRaises(SVGError, parseLength, '50.5.mm')
def parse_parts(self, buffer): # prepare ReportLab self.styles = getSampleStyleSheet() self.style_stack.append(self.styles['Normal']) if self.out_buffer is None: self.out_buffer = StringIO() self.parts = [] # prepare for parsing i = 0 buffer_len = len(buffer) # Possible modes: 0 = normal, 1 = table row, 2 = insert object mode = 0 new_line = True new_para = True cue = 0 content = '' raw_table_data = '' self.reset_table() obj = None style_stack = self.style_stack paragraphs = split_ignore(buffer, '\n\n', '[[[block', ']]]') for p in paragraphs: lines = p.split('\n') content = '' for line in lines: c = line[:1] if c == '#': debug_print('[comment]') elif c == '$': self.parse_paragraph_style(line[1:]) elif c == '~': debug_print('[document element %s]' % line[1]) elem = line[1] endpos = line.find(']', 2) if elem == 'D': self.handle_document_properties(line[3:endpos], line[endpos+1:]) elif elem == 'T': if line[2] == '$': # table style raw_style = line[3:] style = self.parse_table_style(raw_style) self.table_styles.append(style) else: self.table_cols = list(float(n) * self.unit for n in line[3:endpos].split('|')) align = line[endpos+1:endpos+2] if align == '<': self.table_align = 'LEFT' elif align == '>': self.table_align = 'RIGHT' elif elem == 'B': self.append_to_parts(PageBreak()) elif elem == 'S': self.append_to_parts(Spacer(1, toLength(line[2:]))) elif elem == 'V': svg_info_raw = line[3:endpos] svg_info = svg_info_raw.split(';')[:7] if len(svg_info) == 1: mode = 2 obj = self.svg_dict[svg_info[0]] else: if len(svg_info) == 7: svg_name, svg_scale, svg_w, svg_h, svg_path, svg_find, svg_replace = svg_info else: svg_name, svg_scale, svg_w, svg_h, svg_path = svg_info svg_file = open(find(svg_path), 'rb') svg_data = svg_file.read() svg_file.close() if len(svg_info) == 7: svg_data = svg_data.replace(svg_find, svg_replace) svg = xml.dom.minidom.parseString(svg_data).documentElement svgRenderer = SvgRenderer() svgRenderer.render(svg) svg_obj = svgRenderer.finish() #svg_obj = svg2rlg(settings.MEDIA_ROOT + svg_path) svg_obj.scale(float(svg_scale), float(svg_scale)) svg_obj.asDrawing(float(svg_w) * self.unit, float(svg_h) * self.unit) self.svg_dict[svg_name] = svg_obj elif elem == 'I': img_info_raw = line[3:endpos] img_info = img_info_raw.split(';')[:4] if len(img_info) == 1: mode = 2 obj = self.img_dict[img_info[0]] else: img_name, img_w, img_h, img_path = img_info img_obj = Image(find(img_path), width=self.unit*float(img_w), height=self.unit*float(img_h)) align = line[endpos+1:endpos+2] if align == '<': img_obj.hAlign = 'LEFT' elif align == '>': img_obj.hAlign = 'RIGHT' self.img_dict[img_name] = img_obj elif elem == 'C': barcode_info_raw = line[3:endpos] barcode_info = barcode_info_raw.split(';')[:6] if len(barcode_info) == 1: mode = 2 obj = self.img_dict[barcode_info[0]] else: barcode_name, barcode_type, barcode_scale, barcode_w, barcode_h, barcode_data = barcode_info barcode_obj = Barcode(library=find('common/pdf_img/barcode.ps'), width=self.unit * float(barcode_w), height=self.unit * float(barcode_h), data=barcode_data, scale=float(barcode_scale), type=barcode_type) align = line[endpos+1:endpos+2] if align == '<': barcode_obj.hAlign = 'LEFT' elif align == '>': barcode_obj.hAlign = 'RIGHT' self.img_dict[barcode_name] = barcode_obj elif elem == 'F': font_info_raw = line[3:endpos] font_info = font_info_raw.split(';')[:2] self.import_pdf_font(font_info[1], font_info[0]) elif elem == 'P': if '[' in line: self.parts_buffer = line[3:endpos] self.parts_buffer_dict[self.parts_buffer] = [] else: self.parts_buffer = None elif c == '[': mode = 1 raw_table_data += line + '\n' elif c == '\n': pass else: if mode == 0: content += line + '\n' elif mode == 1: raw_table_data += line + '\n' if mode == 0: if content != '': self.append_to_parts(Paragraph(content, self.style_stack[-1] if len(self.style_stack) > 0 else self.styles['Normal'])) content = '' if mode == 1: td = raw_table_data td_len = len(td) i = 0 while i < td_len: c = td[i] c_1 = td[i-1:i] if c == '[' and c_1 != '\\': cue = i + 1 if (c == '|' or c == ']') and c_1 != '\\': cell_content = td[cue:i] pop_after_cell = False if cell_content[:1] == '$': if ' ' in cell_content: style, cell_content = cell_content.split(None, 1) style = style[1:] else: style = '' cell_content = cell_content[1:] self.parse_paragraph_style(style) if cell_content[-1:] == '$': cell_content = cell_content[:-1] pop_after_cell = True if cell_content[:2] == '~V': svg_name = cell_content[2:] self.table_row.append(self.svg_dict[svg_name]) elif cell_content[:2] == '~I': img_name = cell_content[2:] self.table_row.append(self.img_dict[img_name]) elif cell_content[:2] == '~P': self.table_row.append(self.parts_buffer_dict[cell_content[2:]]) else: self.table_row.append(Paragraph(cell_content, self.style_stack[-1] if len(self.style_stack) > 0 else self.styles['Normal'])) if pop_after_cell: self.parse_paragraph_style('') cue = i + 1 if c == ']': self.table_data.append(self.table_row) self.table_row = [] i += 1 if len(self.table_data) > 0: self.append_to_parts(Table(self.table_data, self.table_cols, hAlign=self.table_align, style=self.table_styles)) self.reset_table() raw_table_data = '' if mode == 2: if obj is not None: self.append_to_parts(obj) obj = None mode = 0 return self.parts