def beforeDrawPage(self,canvas,doc): canvas.setFont(serif_font,8) canvas.saveState() if pdfstyles.show_title_page_footer: canvas.line(footer_margin_hor, footer_margin_vert, page_width - footer_margin_hor, footer_margin_vert ) footertext = [_(titlepagefooter)] if pdfstyles.show_creation_date: footertext.append('PDF generated at: %s' % strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime())) p = Paragraph('<br/>'.join([formatter.cleanText(line, escape=False) for line in footertext]), text_style(mode='footer')) w,h = p.wrap(print_width, print_height) canvas.translate( (page_width-w)/2.0, footer_margin_vert - h - 0.25*cm) p.canv = canvas p.draw() canvas.restoreState() if self.cover: width, height = self._scale_img(pdfstyles.title_page_image_size, self.cover) if pdfstyles.title_page_image_pos[0] == None: x = (page_width - width) / 2.0 else: x = max(0, min(page_width-width, pdfstyles.title_page_image_pos[0])) if pdfstyles.title_page_image_pos[1] == None: y = (page_height - height) / 2.0 else: y = max(0, min(page_height-height, pdfstyles.title_page_image_pos[1])) canvas.drawImage(self.cover, x, y, width , height)
def prepare_first_page(canvas, document): p1 = Paragraph(presentation.title, styles['Heading']) p2 = Paragraph( presentation.owner.get_full_name(), styles['SubHeading']) avail_width = width - inch avail_height = height - inch w1, h1 = p1.wrap(avail_width, avail_height) w2, h2 = p2.wrap(avail_width, avail_height) f = Frame( inch / 2, inch / 2, width - inch, height - inch, leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0 ) f.addFromList([p1, p2], canvas) document.pageTemplate.frames[0].height -= h1 + h2 + inch / 2 document.pageTemplate.frames[1].height -= h1 + h2 + inch / 2 canvas.saveState() canvas.setStrokeColorRGB(0, 0, 0) canvas.line( width / 2, inch / 2, width / 2, height - inch - h1 - h2) canvas.restoreState()
class Figure(Flowable): def __init__(self, imgFile, captionTxt, captionStyle, imgWidth=None, imgHeight=None, margin=(0, 0, 0, 0), padding=(0, 0, 0, 0), align=None, borderColor=(0.75, 0.75, 0.75), no_mask=False, url=None): imgFile = imgFile self.imgPath = imgFile # workaround for http://code.pediapress.com/wiki/ticket/324 # see http://two.pairlist.net/pipermail/reportlab-users/2008-October/007526.html if no_mask: self.i = Image(imgFile, width=imgWidth, height=imgHeight, mask=None) else: self.i = Image(imgFile, width=imgWidth, height=imgHeight) self.imgWidth = imgWidth self.imgHeight = imgHeight self.c = Paragraph(captionTxt, style=captionStyle) self.margin = margin # 4-tuple. margins in order: top, right, bottom, left self.padding = padding # same as above self.borderColor = borderColor self.align = align self.cs = captionStyle self.captionTxt = captionTxt self.availWidth = None self.availHeight = None self.url = url def draw(self): canv = self.canv if self.align == "center": canv.translate((self.availWidth - self.width) / 2, 0) canv.saveState() canv.setStrokeColor(Color(self.borderColor[0], self.borderColor[1], self.borderColor[2])) canv.rect(self.margin[3], self.margin[2], self.boxWidth, self.boxHeight) canv.restoreState() canv.translate(self.margin[3] + self.padding[3], self.margin[2] + self.padding[2] - 2) self.c.canv = canv self.c.draw() canv.translate((self.boxWidth - self.padding[1] - self.padding[3] - self.i.drawWidth) / 2, self.captionHeight + 2) self.i.canv = canv self.i.draw() if self.url: frags = urlparse.urlsplit(self.url.encode('utf-8')) clean_url = urlparse.urlunsplit((frags.scheme, frags.netloc, urllib.quote(frags.path, safe='/'), urllib.quote(frags.query, safe='=&'), frags.fragment,)).decode('utf-8') canv.linkURL(clean_url, (0, 0, self.imgWidth, self.imgHeight), relative=1, thickness=0) def wrap(self, availWidth, availHeight): self.availWidth = availWidth self.availHeight = availHeight contentWidth = max(self.i.drawWidth, self.c.wrap(self.i.drawWidth, availHeight)[0]) self.boxWidth = contentWidth + self.padding[1] + self.padding[3] (self.captionWidth, self.captionHeight) = self.c.wrap(contentWidth, availHeight) self.captionHeight += self.cs.spaceBefore + self.cs.spaceAfter self.boxHeight = self.i.drawHeight + self.captionHeight + self.padding[0] + self.padding[2] self.width = self.boxWidth + self.margin[1] + self.margin[3] self.height = self.boxHeight + self.margin[0] + self.margin[2] return (self.width, self.height)
def beforeDrawPage(self, canvas, doc): canvas.setFont(serif_font, 8) canvas.saveState() if pdfstyles.show_title_page_footer: canvas.line(footer_margin_hor, footer_margin_vert, page_width - footer_margin_hor, footer_margin_vert) footertext = [_(titlepagefooter)] if pdfstyles.show_creation_date: locale.setlocale(locale.LC_ALL, "") footertext.append( pdfstyles.creation_date_txt % time.strftime(pdfstyles.creation_date_format, time.localtime()) ) lines = [formatter.cleanText(line, escape=False) for line in footertext] txt = "<br/>".join(line if isinstance(line, unicode) else unicode(line, "utf-8") for line in lines) p = Paragraph(txt, text_style(mode="footer")) w, h = p.wrap(print_width, print_height) canvas.translate((page_width - w) / 2.0, footer_margin_vert - h - 0.25 * cm) p.canv = canvas p.draw() canvas.restoreState() if self.cover: width, height = self._scale_img(pdfstyles.title_page_image_size, self.cover) if pdfstyles.title_page_image_pos[0] is None: x = (page_width - width) / 2.0 else: x = max(0, min(page_width - width, pdfstyles.title_page_image_pos[0])) if pdfstyles.title_page_image_pos[1] is None: y = (page_height - height) / 2.0 else: y = max(0, min(page_height - height, pdfstyles.title_page_image_pos[1])) canvas.drawImage(self.cover, x, y, width, height)
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)
def test3(self): from reportlab.pdfgen.canvas import Canvas aW=307 styleSheet = getSampleStyleSheet() bt = styleSheet['BodyText'] btj = ParagraphStyle('bodyText1j',parent=bt,alignment=TA_JUSTIFY) p=Paragraph("""<a name='top'/>Subsequent pages test pageBreakBefore, frameBreakBefore and keepTogether attributes. Generated at 1111. The number in brackets at the end of each paragraph is its position in the story. llllllllllllllllllllllllll bbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccc ddddddddddddddddddddd eeeeyyy""",btj) w,h=p.wrap(aW,1000) canv=Canvas('test_platypus_paragraph_just.pdf',pagesize=(aW,h)) i=len(canv._code) p.drawOn(canv,0,0) ParaCode=canv._code[i:] canv.saveState() canv.setLineWidth(0) canv.setStrokeColorRGB(1,0,0) canv.rect(0,0,aW,h) canv.restoreState() canv.showPage() canv.save() from reportlab import rl_config x = rl_config.paraFontSizeHeightOffset and '50' or '53.17' good = ['q', '1 0 0 1 0 0 cm', 'q', 'BT 1 0 0 1 0 '+x+' Tm 3.59 Tw 12 TL /F1 10 Tf 0 0 0 rg (Subsequent pages test pageBreakBefore, frameBreakBefore and) Tj T* 0 Tw .23 Tw (keepTogether attributes. Generated at 1111. The number in brackets) Tj T* 0 Tw .299167 Tw (at the end of each paragraph is its position in the story. llllllllllllllllllllllllll) Tj T* 0 Tw 66.9 Tw (bbbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccccc) Tj T* 0 Tw (ddddddddddddddddddddd eeeeyyy) Tj T* ET', 'Q', 'Q'] ok= ParaCode==good assert ok, "\nParaCode=%r\nexpected=%r" % (ParaCode,good)
def do_heading(self, text, sty): # create bookmarkname bn = sha1(text.encode('utf-8') + sty.name.encode('utf-8')).hexdigest() # modify paragraph text to include an anchor point with name bn h = Paragraph(text + '<a name="%s"/>' % bn, sty) # store the bookmark name on the flowable so afterFlowable can see this h._bookmarkName = bn self.story.append(h)
def doHeading(text,sty): from hashlib import sha1 #create bookmarkname bn=sha1(text+sty.name).hexdigest() #modify paragraph text to include an anchor point with name bn h=Paragraph(text+'<a name="%s"/>' % bn,sty) #store the bookmark name on the flowable so afterFlowable can see this h._bookmarkName=bn story.append(h)
def go(): styles = getSampleStyleSheet() style=styles['Normal'] p1 = Paragraph('This is a paragraph', style ) print(p1.wrap(500,701)) print(p1._cache['avail']) print(len(p1.split(500,701))) print(p1.wrap(500,700)) print(len(p1.split(500,700)))
def _do_heading(self, text, sty): if isinstance(text, list): text = "_".join(text) # create bookmarkname bn = sha1(text + sty.name).hexdigest() # modify paragraph text to include an anchor point with name bn h = Paragraph(text + '<a name="%s"/>' % bn, sty) # store the bookmark name on the flowable so afterFlowable can see this h._bookmarkName = bn self.story.append(h)
def __list_format(canvas, doc): canvas.saveState() building_style = ParagraphStyle(name='building_title', fontSize=__FONT_SIZE__) t = u'%s<br/>Data afișării: %s<br/>Luna: %s' % (doc.habitam_building.name, doc.habitam_display, doc.habitam_month) p = Paragraph(t, building_style) p.wrapOn(canvas, 5 * cm, 2 * cm) p.drawOn(canvas, .5 * cm, __HEIGHT__ - 1.7 * cm) habitam_brand(canvas, __WIDTH__, __HEIGHT__) canvas.restoreState()
def _draw_tyvek(p, inventory): p.line(15, 245, 345, 245) p.line(15, 188, 345, 188) p.line(15, 115, 345, 115) p.setFontSize(12) p.drawString(26, 290, 'DC-%0.3d' % inventory.dropship.id) p.drawString(295, 290, str(inventory.item.id)) if len(inventory.item.name) > 55: p.setFont('Helvetica-Bold', 8) else: p.setFont('Helvetica-Bold', 10) p.drawString(26, 260, ellipsize(inventory.item.name, 75)) p.setFont('Helvetica-Bold', 10) p.drawString( 26, 224, 'Console:') p.drawString(120, 224, inventory.item.category.name) p.drawString( 26, 200, 'Rating:') p.drawString(120, 200, inventory.item.rating.title) p.drawImage(inventory.item.rating.image.path, 211, 197, width=20, height=30) p.setFont('Helvetica', 10) styles = getSampleStyleSheet() para = Paragraph(ellipsize(inventory.item.description, 305), styles['Normal']) para.wrap(290, 10000) i = 0 ll = para.breakLines(290) for l in ll.lines: if ll.kind == 0: p.drawString(25, 170 - i, ' '.join(l[1])) else: p.drawString(25, 170 - i, ' '.join([x.text for x in l.words])) i += 10 from code128 import Code128 bar = Code128() image = bar.getImage(inventory.barcode, 50, "png") _fd, n = tempfile.mkstemp() image.save(n, "PNG") p.drawImage(n, 196, 60, width=140, height=50) p.setFont('Helvetica-Bold', 10) p.drawString(236, 50, inventory.barcode) p.drawImage( os.path.join(settings.STATIC_ROOT, "img/bw-logo.png"), 26, 80, width=87, height=22) p.setFont('Helvetica-Bold', 10) p.drawString(25, 70, 'PO Box 6487') p.drawString(25, 58, 'Delray Beach, FL 33482-9901') p.showPage()
def test2(self): '''CJK splitting in multi-frag case''' style = ParagraphStyle('test', wordWrap = 'CJK') p = Paragraph('bla <i>blub</i> '*130 , style) aW,aH=439.275590551,121.88976378 w,h=p.wrap(aW,aH) S=p.split(aW,aH) assert len(S)==2, 'Multi frag CJK splitting failed' w0,h0=S[0].wrap(aW,aH) assert h0<=aH,'Multi-frag CJK split[0] has wrong height %s >= available %s' % (H0,aH) w1,h1=S[1].wrap(aW,aH) assert h0+h1==h, 'Multi-frag-CJK split[0].height(%s)+split[1].height(%s) don\'t add to original %s' % (h0,h1,h)
def wrap(self, availWidth, availHeight): # reduce the available width & height by the padding so the wrapping # will use the correct size style = self.style availWidth -= style.paddingLeft + style.paddingRight availHeight -= style.paddingTop + style.paddingBottom # call the base class to do wrapping and calculate the size Paragraph.wrap(self, availWidth, availHeight) # increase the calculated size by the padding self.width += style.paddingLeft + style.paddingRight self.height += style.paddingTop + style.paddingBottom return (self.width, self.height)
def test2(self): """CJK splitting in multi-frag case""" style = ParagraphStyle("test", wordWrap="CJK") p = Paragraph("bla <i>blub</i> " * 130, style) aW, aH = 439.275590551, 121.88976378 w, h = p.wrap(aW, aH) S = p.split(aW, aH) assert len(S) == 2, "Multi frag CJK splitting failed" w0, h0 = S[0].wrap(aW, aH) assert h0 <= aH, "Multi-frag CJK split[0] has wrong height %s >= available %s" % (H0, aH) w1, h1 = S[1].wrap(aW, aH) assert h0 + h1 == h, "Multi-frag-CJK split[0].height(%s)+split[1].height(%s) don't add to original %s" % ( h0, h1, h, )
def doPara(x,text,wc,ns,n,hrep=' ',crep=' ',hdw=0,cdw=0): if '{H}' in text: text = text.replace('{H}',hrep) wc += hdw if '{C}' in text: text = text.replace('{C}',crep) wc += cdw p = Paragraph(text,bt) w,h = p.wrap(aW,1000) annotations[:] = [] if measuring: ends[:] = [] p.drawOn(canv,x,y-h) canv.saveState() canv.setLineWidth(0.1) canv.setStrokeColorRGB(1,0,0) canv.rect(x,y-h,wc,h) if n is not None: canv.setFillColorRGB(0,1,0) canv.drawRightString(x,y-h,'%3d: ' % n) if annotations: canv.setLineWidth(0.1) canv.setStrokeColorRGB(0,1,0) canv.setFillColorRGB(0,0,1) canv.setFont('Helvetica',0.2) for info in annotations: cur_x = info['cur_x']+x cur_y = info['cur_y']+y-h canv.drawCentredString(cur_x, cur_y+0.3,'%.2f' % (cur_x-x)) canv.line(cur_x,cur_y,cur_x,cur_y+0.299) if measuring: if not ends: errors.append('Paragraph measurement failure no ends found for %s\n%r' % (ns,text)) elif len(ends)>1: errors.append('Paragraph measurement failure no len(ends)==%d for %s\n%r' % (len(ends),ns,text)) else: cur_x = ends[0]['cur_x'] adiff = abs(wc-cur_x) length_errors.append(adiff) if adiff>1e-8: errors.append('Paragraph measurement error wc=%.4f measured=%.4f for %s\n%r' % (wc,cur_x,ns,text)) canv.restoreState() return h
def prepare_first_page(canvas, document): p1 = Paragraph(presentation.title, styles['Heading']) p2 = Paragraph(presentation.owner.get_full_name(), styles['SubHeading']) avail_width = width - inch # TODO: determine if the complaint about height being undeclared is just pycharm or if its a problem # if it is possibly a problem "it's better to be explicit" so refactor avail_height = height - inch w1, h1 = p1.wrap(avail_width, avail_height) w2, h2 = p2.wrap(avail_width, avail_height) f = Frame(inch / 2, inch / 2, width - inch, height - inch, leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0) f.addFromList([p1, p2], canvas) document.pageTemplate.frames[0].height -= h1 + h2 + inch / 2 document.pageTemplate.frames[1].height -= h1 + h2 + inch / 2 canvas.saveState() canvas.setStrokeColorRGB(0, 0, 0) canvas.line(width / 2, inch / 2, width / 2, height - inch - h1 - h2) canvas.restoreState()
def test2(self): sty = ParagraphStyle(name = 'normal') sty.fontName = 'Times-Roman' sty.fontSize = 10 sty.leading = 12 p = Paragraph('one two three',sty) p.wrap(20,36) self.assertEqual(len(p.split(20,24)),2) #widows allowed self.assertEqual(len(p.split(20,16)),0) #orphans disallowed p.allowWidows = 0 self.assertEqual(len(p.split(20,24)),0) #widows disallowed p.allowOrphans = 1 self.assertEqual(len(p.split(20,16)),2) #orphans allowed
def beforeDrawPage(self,canvas,doc): canvas.setFont(serif_font,8) canvas.saveState() if pdfstyles.show_title_page_footer: canvas.line(footer_margin_hor, footer_margin_vert, page_width - footer_margin_hor, footer_margin_vert ) footertext = [_(titlepagefooter)] if pdfstyles.show_creation_date: footertext.append('PDF generated at: %s' % strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime())) p = Paragraph('<br/>'.join([formatter.cleanText(line, escape=False) for line in footertext]), text_style(mode='footer')) w,h = p.wrap(print_width, print_height) canvas.translate( (page_width-w)/2.0, 0.2*cm) p.canv = canvas p.draw() canvas.restoreState() if self.cover: width = 12 * cm img = Image.open(self.cover) w,h = img.size height = width/w*h x = (page_width - width) / 2.0 y = (page_height - height) / 2.0 canvas.drawImage(self.cover, x, y, width , height)
def __init__(self,imgFile, captionTxt, captionStyle, imgWidth=None, imgHeight=None, margin=(0,0,0,0), padding=(0,0,0,0), align=None, borderColor=(0.75,0.75,0.75), no_mask=False, url=None): imgFile = imgFile self.imgPath = imgFile # workaround for http://code.pediapress.com/wiki/ticket/324 # see http://two.pairlist.net/pipermail/reportlab-users/2008-October/007526.html if no_mask: self.i = Image(imgFile, width=imgWidth, height=imgHeight, mask=None) else: self.i = Image(imgFile, width=imgWidth, height=imgHeight) self.imgWidth = imgWidth self.imgHeight = imgHeight self.c = Paragraph(captionTxt, style=captionStyle) self.margin = margin # 4-tuple. margins in order: top, right, bottom, left self.padding = padding # same as above self.borderColor = borderColor self.align = align self.cs = captionStyle self.captionTxt = captionTxt self.availWidth = None self.availHeight = None self.url = url
def testUl(self): from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame, PageBegin from reportlab.lib.units import inch class MyDocTemplate(BaseDocTemplate): _invalidInitArgs = ('pageTemplates', ) def __init__(self, filename, **kw): self.allowSplitting = 0 BaseDocTemplate.__init__(self, filename, **kw) self.addPageTemplates([ PageTemplate( 'normal', [ Frame(inch, inch, 6.27 * inch, 9.69 * inch, id='first', topPadding=0, rightPadding=0, leftPadding=0, bottomPadding=0, showBoundary=ShowBoundaryValue(color="red")) ], ), ]) styleSheet = getSampleStyleSheet() normal = ParagraphStyle(name='normal', fontName='Times-Roman', fontSize=12, leading=1.2 * 12, parent=styleSheet['Normal']) normal_sp = ParagraphStyle(name='normal_sp', parent=normal, alignment=TA_JUSTIFY, spaceBefore=12) normal_just = ParagraphStyle(name='normal_just', parent=normal, alignment=TA_JUSTIFY, spaceAfter=12) normal_right = ParagraphStyle(name='normal_right', parent=normal, alignment=TA_RIGHT) normal_center = ParagraphStyle(name='normal_center', parent=normal, alignment=TA_CENTER) normal_indent = ParagraphStyle(name='normal_indent', firstLineIndent=0.5 * inch, parent=normal) normal_indent_lv_2 = ParagraphStyle(name='normal_indent_lv_2', firstLineIndent=1.0 * inch, parent=normal) text0 = '''Furthermore, a subset of English sentences interesting on quite independent grounds is not quite equivalent to a stipulation to place the constructions into these various categories. We will bring evidence in favor of The following thesis: most of the methodological work in modern linguistics can be defined in such a way as to impose problems of phonemic and morphological analysis.''' story = [] a = story.append for mode in (0, 1, 2, 3): text = text0 if mode == 1: text = text.replace('English sentences', '<b>English sentences</b>').replace( 'quite equivalent', '<i>quite equivalent</i>') text = text.replace('the methodological work', '<b>the methodological work</b>').replace( 'to impose problems', '<i>to impose problems</i>') a( Paragraph('Justified paragraph in normal/bold/italic font', style=normal)) elif mode == 2: text = '<b>%s</b>' % text a(Paragraph('Justified paragraph in bold font', style=normal)) elif mode == 3: text = '<i>%s</i>' % text a(Paragraph('Justified paragraph in italic font', style=normal)) else: a(Paragraph('Justified paragraph in normal font', style=normal)) a(Paragraph(text, style=normal_just)) doc = MyDocTemplate(outputfile('test_platypus_paragraphs_just.pdf')) doc.build(story)
def test3(self): '''compare CJK splitting in some edge cases''' from reportlab.pdfgen.canvas import Canvas from reportlab.platypus.paragraph import Paragraph from reportlab.lib.styles import ParagraphStyle from reportlab.pdfbase import pdfmetrics from reportlab.lib.enums import TA_LEFT sty = ParagraphStyle('A') sty.fontSize = 15 sty.leading = sty.fontSize*1.2 sty.fontName = 'Courier' sty.alignment = TA_LEFT sty.wordWrap = 'CJK' p0=Paragraph('ABCDEFGHIJKL]N',sty) p1=Paragraph('AB<font color="red">C</font>DEFGHIJKL]N',sty) canv = Canvas('test_platypus_paragraph_cjk3.pdf') ix = len(canv._code) aW = pdfmetrics.stringWidth('ABCD','Courier',15) w,h=p0.wrap(aW,1000000) y = canv._pagesize[1]-72-h p0.drawOn(canv,72,y) w,h=p1.wrap(aW,1000000) y -= h+10 p1.drawOn(canv,72,y) w,h=p0.wrap(aW*0.25-2,1000000) y -= h+10 p0.drawOn(canv,72,y) w,h=p1.wrap(aW/4.-2,1000000) y -= h+10 p1.drawOn(canv,72,y) assert canv._code[ix:]==['q', '1 0 0 1 72 697.8898 cm', 'q', '0 0 0 rg', 'BT 1 0 0 1 0 57 Tm /F2 15 Tf 18 TL (ABCD) Tj T* (EFGH) Tj T* (IJKL]) Tj T* (N) Tj T* ET', 'Q', 'Q', 'q', '1 0 0 1 72 615.8898 cm', 'q', 'BT 1 0 0 1 0 57 Tm 18 TL /F2 15 Tf 0 0 0 rg (AB) Tj 1 0 0 rg (C) Tj 0 0 0 rg (D) Tj T* (EFGH) Tj T* (IJKL]) Tj T* (N) Tj T* ET', 'Q', 'Q', 'q', '1 0 0 1 72 353.8898 cm', 'q', '0 0 0 rg', 'BT 1 0 0 1 0 237 Tm /F2 15 Tf 18 TL (A) Tj T* (B) Tj T* (C) Tj T* (D) Tj T* (E) Tj T* (F) Tj T* (G) Tj T* (H) Tj T* (I) Tj T* (J) Tj T* (K) Tj T* (L) Tj T* (]) Tj T* (N) Tj T* ET', 'Q', 'Q', 'q', '1 0 0 1 72 91.88976 cm', 'q', 'BT 1 0 0 1 0 237 Tm 18 TL /F2 15 Tf 0 0 0 rg (A) Tj T* (B) Tj T* 1 0 0 rg (C) Tj T* 0 0 0 rg (D) Tj T* (E) Tj T* (F) Tj T* (G) Tj T* (H) Tj T* (I) Tj T* (J) Tj T* (K) Tj T* (L) Tj T* (]) Tj T* (N) Tj T* ET', 'Q', 'Q'] canv.showPage() canv.save()
def draw(self): Paragraph.draw(self) TOC.append((self._label,self.canv.getPageNumber(),self._key)) self.canv.bookmarkHorizontal('TOC_%s' % self._key,0,+20)
def testUl(self): from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame, PageBegin from reportlab.lib.units import inch from reportlab.platypus.flowables import AnchorFlowable class MyDocTemplate(BaseDocTemplate): _invalidInitArgs = ('pageTemplates', ) def __init__(self, filename, **kw): self.allowSplitting = 0 kw['showBoundary'] = 1 BaseDocTemplate.__init__(self, filename, **kw) self.addPageTemplates([ PageTemplate( 'normal', [ Frame(inch, inch, 6.27 * inch, 9.69 * inch, id='first', topPadding=0, rightPadding=0, leftPadding=0, bottomPadding=0, showBoundary=ShowBoundaryValue(color="red")) ], ), ]) styleSheet = getSampleStyleSheet() normal = ParagraphStyle(name='normal', fontName='Times-Roman', fontSize=12, leading=1.2 * 12, parent=styleSheet['Normal']) normal_sp = ParagraphStyle(name='normal_sp', parent=normal, alignment=TA_JUSTIFY, spaceBefore=12) normal_just = ParagraphStyle(name='normal_just', parent=normal, alignment=TA_JUSTIFY) normal_right = ParagraphStyle(name='normal_right', parent=normal, alignment=TA_RIGHT) normal_center = ParagraphStyle(name='normal_center', parent=normal, alignment=TA_CENTER) normal_indent = ParagraphStyle(name='normal_indent', firstLineIndent=0.5 * inch, parent=normal) normal_indent_lv_2 = ParagraphStyle(name='normal_indent_lv_2', firstLineIndent=1.0 * inch, parent=normal) texts = [ '''Furthermore, a subset of <font size="14">English sentences</font> interesting on quite independent grounds is not quite equivalent to a stipulation to place the constructions into these various categories.''', '''We will bring evidence in favor of The following thesis: most of the methodological work in modern linguistics can be defined in such a way as to impose problems of phonemic and morphological analysis.''' ] story = [] a = story.append a( Paragraph( "This should <a href=\"#theEnd\" color=\"blue\"><a href=\"#theEnd\" color=\"blue\">jump</a></a> jump to the end!", style=normal)) a( XPreformatted( "This should <a href=\"#theEnd\" color=\"blue\"><a href=\"#theEnd\" color=\"blue\">jump</a></a> jump to the end!", style=normal)) a( Paragraph( "<a href=\"#theEnd\"><u><font color=\"blue\">ditto</font></u></a>", style=normal)) a( XPreformatted( "<a href=\"#theEnd\"><u><font color=\"blue\">ditto</font></u></a>", style=normal)) a( Paragraph( "This <font color='CMYKColor(0,0.6,0.94,0)'>should</font> <a href=\"#thePenultimate\" color=\"blue\"><a href=\"#thePenultimate\" color=\"blue\">jump</a></a> jump to the penultimate page!", style=normal)) a( Paragraph( "This should <a href=\"#theThird\" color=\"blue\"><a href=\"#theThird\" color=\"blue\">jump</a></a> jump to a justified para!", style=normal)) a( Paragraph( "This should <a href=\"#theFourth\" color=\"blue\"><a href=\"#theFourth\" color=\"blue\">jump</a></a> jump to an indented para!", style=normal)) for mode in (0, 1): text0 = texts[0] text1 = texts[1] if mode: text0 = text0.replace('English sentences', '<b>English sentences</b>').replace( 'quite equivalent', '<i>quite equivalent</i>') text1 = text1.replace( 'the methodological work', '<b>the methodological work</b>').replace( 'to impose problems', '<i>to impose problems</i>') for t in ('u', 'strike'): for n in xrange(6): for s in (normal, normal_center, normal_right, normal_just, normal_indent, normal_indent_lv_2): for autoLeading in ('', 'min', 'max'): if n == 4 and s == normal_center and t == 'strike' and mode == 1: a( Paragraph( "<font color=green>The second jump at the beginning should come here <a name=\"thePenultimate\"/><a name=\"thePenultimate\"/>!</font>", style=normal)) elif n == 4 and s == normal_just and t == 'strike' and mode == 1: a( Paragraph( "<font color=green>The third jump at the beginning should come just below here to a paragraph with just an a tag in it!</font>", style=normal)) a( Paragraph("<a name=\"theThird\"/>", style=normal)) elif n == 4 and s == normal_indent and t == 'strike' and mode == 1: a( Paragraph( "<font color=green>The fourth jump at the beginning should come just below here!</font>", style=normal)) a(AnchorFlowable('theFourth')) a( Paragraph( 'n=%d style=%s(autoLeading=%s) tag=%s' % (n, s.name, autoLeading, t), style=normal_sp)) a( Paragraph( '<para autoleading="%s">%s<%s>%s</%s>. %s <%s>%s</%s>. %s</para>' % (autoLeading, (s == normal_indent_lv_2 and '<seq id="document" inc="no"/>.<seq id="document_lv_2"/>' or ''), t, ' '.join((n + 1) * ['A']), t, text0, t, ' '.join( (n + 1) * ['A']), t, text1), style=s)) a( Paragraph( "The jump at the beginning should come here <a name=\"theEnd\"/><a name=\"theEnd\"/>!", style=normal)) doc = MyDocTemplate(outputfile('test_platypus_paragraphs_ul.pdf')) doc.build(story)
def __init__(self,key,text,*args,**kwds): self._label = text self._key = key Paragraph.__init__(self,text,*args,**kwds)
def wrap(self, availWidth, availHeight): text = self.textPattern % self._lastPageNum self._para = Paragraph(text, self.paraStyle) return self._para.wrap(availWidth, availHeight)
def fullTest(fileName="test_full.pdf"): """Creates large-ish test document with a variety of parameters""" story = [] styles = getSampleStyleSheet() styleN = styles['Normal'] styleH = styles['Heading1'] styleH2 = styles['Heading2'] story = [] story.append( Paragraph('ReportLab Barcode Test Suite - full output', styleH)) story.append(Paragraph('Generated on %s' % time.ctime(time.time()), styleN)) story.append(Paragraph('', styleN)) story.append(Paragraph('Repository information for this build:', styleN)) #see if we can figure out where it was built, if we're running in source if os.path.split(os.getcwd())[-1] == 'barcode' and os.path.isdir('.svn'): #runnning in a filesystem svn copy infoLines = os.popen('svn info').read() story.append(Preformatted(infoLines, styles["Code"])) story.append(Paragraph('About this document', styleH2)) story.append(Paragraph('History and Status', styleH2)) story.append( Paragraph( """ This is the test suite and docoumentation for the ReportLab open source barcode API, being re-released as part of the forthcoming ReportLab 2.0 release. """, styleN)) story.append( Paragraph( """ Several years ago Ty Sarna contributed a barcode module to the ReportLab community. Several of the codes were used by him in hiw work and to the best of our knowledge this was correct. These were written as flowable objects and were available in PDFs, but not in our graphics framework. However, we had no knowledge of barcodes ourselves and did not advertise or extend the package. """, styleN)) story.append( Paragraph( """ We "wrapped" the barcodes to be usable within our graphics framework; they are now available as Drawing objects which can be rendered to EPS files or bitmaps. For the last 2 years this has been available in our Diagra and Report Markup Language products. However, we did not charge separately and use was on an "as is" basis. """, styleN)) story.append( Paragraph( """ A major licensee of our technology has kindly agreed to part-fund proper productisation of this code on an open source basis in Q1 2006. This has involved addition of EAN codes as well as a proper testing program. Henceforth we intend to publicise the code more widely, gather feedback, accept contributions of code and treat it as "supported". """, styleN)) story.append( Paragraph( """ This involved making available both downloads and testing resources. This PDF document is the output of the current test suite. It contains codes you can scan (if you use a nice sharp laser printer!), and will be extended over coming weeks to include usage examples and notes on each barcode and how widely tested they are. This is being done through documentation strings in the barcode objects themselves so should always be up to date. """, styleN)) story.append(Paragraph('Usage examples', styleH2)) story.append(Paragraph(""" To be completed """, styleN)) story.append(Paragraph('The codes', styleH2)) story.append( Paragraph( """ Below we show a scannable code from each barcode, with and without human-readable text. These are magnified about 2x from the natural size done by the original author to aid inspection. This will be expanded to include several test cases per code, and to add explanations of checksums. Be aware that (a) if you enter numeric codes which are too short they may be prefixed for you (e.g. "123" for an 8-digit code becomes "00000123"), and that the scanned results and readable text will generally include extra checksums at the end. """, styleN)) codeNames = getCodeNames() from reportlab.lib.utils import flatten width = [float(x[8:]) for x in sys.argv if x.startswith('--width=')] height = [float(x[9:]) for x in sys.argv if x.startswith('--height=')] isoScale = [int(x[11:]) for x in sys.argv if x.startswith('--isoscale=')] options = {} if width: options['width'] = width[0] if height: options['height'] = height[0] if isoScale: options['isoScale'] = isoScale[0] scales = [x[8:].split(',') for x in sys.argv if x.startswith('--scale=')] scales = list(map(float, scales and flatten(scales) or [1])) scales = list(map(float, scales and flatten(scales) or [1])) for scale in scales: story.append(PageBreak()) story.append(Paragraph('Scale = %.1f' % scale, styleH2)) story.append(Spacer(36, 12)) for codeName in codeNames: s = [Paragraph('Code: ' + codeName, styleH2)] for hr in (0, 1): s.append(Spacer(36, 12)) dr = createBarcodeDrawing(codeName, humanReadable=hr, **options) dr.renderScale = scale s.append(dr) s.append(Spacer(36, 12)) s.append(Paragraph('Barcode should say: ' + dr._bc.value, styleN)) story.append(KeepTogether(s)) SimpleDocTemplate(fileName).build(story) print('created', fileName)
def __init__ (self, text, style, angle): Paragraph.__init__(self, text, style) self.angle = angle
def check(self, text, bt=getSampleStyleSheet()['BodyText']): try: P = Paragraph(text, style=bt) except: raise AssertionError("'%s' should parse" % text)
def testIt(self): "This makes one long multi-page paragraph." # Build story. story = [] styleSheet = getSampleStyleSheet() h1 = styleSheet['Heading1'] h1.pageBreakBefore = 1 h1.keepWithNext = 1 h2 = styleSheet['Heading2'] h2.frameBreakBefore = 1 h2.keepWithNext = 1 h3 = styleSheet['Heading3'] h3.backColor = colors.cyan h3.keepWithNext = 1 bt = styleSheet['BodyText'] story.append( Paragraph(""" This tests ability to alternate left and right templates. We start on a plain one. The next page should display a left-side template, with a big inner margin and staple-like holes on the right.""", style=bt)) story.append(NextPageTemplate(['left', 'right'])) story.append( Paragraph(""" One can specify a list of templates instead of a single one in order to sequence through them.""", style=bt)) def doSome(): for i in range(10): story.append( Paragraph( 'Heading 1 always starts a new page (%d)' % len(story), h1)) for j in range(3): story.append( Paragraph( 'Heading1 paragraphs should always' 'have a page break before. Heading 2 on the other hand' 'should always have a FRAME break before (%d)' % len(story), bt)) story.append( Paragraph( 'Heading 2 always starts a new frame (%d)' % len(story), h2)) story.append( Paragraph( 'Heading1 paragraphs should always' 'have a page break before. Heading 2 on the other hand' 'should always have a FRAME break before (%d)' % len(story), bt)) for j in range(3): story.append( Paragraph( randomText(theme=PYTHON, sentences=2) + ' (%d)' % len(story), bt)) story.append( Paragraph( 'I should never be at the bottom of a frame (%d)' % len(story), h3)) story.append( Paragraph( randomText(theme=PYTHON, sentences=1) + ' (%d)' % len(story), bt)) doSome() story.append(NextPageTemplate('plain')) story.append(Paragraph('Back to plain old page template', h1)) story.append(Paragraph('Back to plain old formatting', bt)) story.append( Paragraph( """use a template name of * to indicate where the iteration should restart""", style=bt)) story.append(NextPageTemplate(['left', '*', 'right'])) doSome() #doc = MyDocTemplate(outputfile('test_platypus_leftright.pdf')) doc = MyDocTemplate(outputfile('test_platypus_leftright.pdf')) doc.multiBuild(story)
def test0(self): ''' Test case for Indexes. This will draw an index at the end of the document with dots seperating the indexing terms from the page numbers. Index terms are grouped by their first 2, and first 3 characters. The page numbers should be clickable and link to the indexed word. ''' if rl_invariant: random.seed(1753799561) # Build story. for headers in False, True: path = outputfile('test_platypus_index%s.pdf' % (headers and '_headers' or '')) doc = MyDocTemplate(path) story = [] styleSheet = getSampleStyleSheet() bt = styleSheet['BodyText'] description = self.test0.__doc__ if headers: description = description.replace( 'index at', 'index with alphabetic headers at') description = '<font color=red>%s</font>' % description story.append(Paragraph(description, bt)) index = SimpleIndex(dot=' . ', headers=headers) def addParas(words): txt = u' '.join([(len(w) > 5 and u'<index item=%s/>%s' % (quoteattr(commajoin([w[:2], w[:3], w])), w) or w) for w in words]) para = Paragraph(txt, makeBodyStyle()) story.append(para) for i in range(20): addParas( randomtext.randomText(randomtext.PYTHON, 5).split(' ')) addParas([ u + w for u in u'E\xc8\xc9\xca\xcb' for w in (u'erily', u'asily') ]) addParas([ u + w for u in u'A\xc0\xc4\xc1\xc3\xc2' for w in (u'dvance', u'ttend') ]) addParas([ u + w for u in u'O\xd2\xd6\xd3\xd2' for w in (u'rdinary', u'verflow') ]) addParas([ u + w for u in u'U\xd9\xdc\xdb' for w in (u'ndertow', u'nbeliever') ]) addParas([ u + w for u in u'e\xe8\xea\xeb\xe9' for w in (u'ventide', u'lision') ]) addParas([ u + w for u in u'o\xf2\xf5\xf3\xf4' for w in (u'verture', u'ntology') ]) #test ampersand in index term txt = '\nMarks & Spencer - purveyors of fine groceries, underwear and ampersands - should have their initials displayed however they were input.\n<index item="M&S,groceries"/><index item="M&S,underwear"/><index item="M&S,ampersands"/>' para = Paragraph(txt, makeBodyStyle()) story.append(para) story.append(index) doc.build(story, canvasmaker=index.getCanvasMaker())
def test1(self): "This makes one long multi-page paragraph." # Build story. story = [] styleSheet = getSampleStyleSheet() h3 = styleSheet['Heading3'] bt = styleSheet['BodyText'] text = '''If you imagine that the box of X's tothe left is an image, what I want to be able to do is flow a series of paragraphs around the image so that once the bottom of the image is reached, then text will flow back to the left margin. I know that it would be possible to something like this using tables, but I can't see how to have a generic solution. There are two examples of this in the demonstration section of the reportlab site. If you look at the "minimal" euro python conference brochure, at the end of the timetable section (page 8), there are adverts for "AdSu" and "O'Reilly". I can see how the AdSu one might be done generically, but the O'Reilly, unsure... I guess I'm hoping that I've missed something, and that it's actually easy to do using platypus.We can do greek letters <greek>mDngG</greek>. This should be a u with a dieresis on top <unichar code=0xfc/>="<unichar code="0xfc"/>" and this &#xfc;="ü" and this \\xc3\\xbc="\xc3\xbc". On the other hand this should be a pound sign &pound;="£" and this an alpha &alpha;="α". You can have links in the page <link href="http://www.reportlab.com" color="blue">ReportLab</link> & <a href="http://www.reportlab.org" color="green">ReportLab.org</a>. Use scheme "pdf:" to indicate an external PDF link, "http:", "https:" to indicate an external link eg something to open in your browser. If an internal link begins with something that looks like a scheme, precede with "document:". <strike>This text should have a strike through it.</strike> ''' from reportlab.platypus.flowables import ImageAndFlowables, Image from reportlab.lib.testutils import testsFolder gif = os.path.join(testsFolder, 'pythonpowered.gif') heading = Paragraph('This is a heading', h3) story.append( ImageAndFlowables(Image(gif), [heading, Paragraph(text, bt)])) phrase = 'This should be a paragraph spanning at least three pages. ' description = ''.join([('%d: ' % i) + phrase for i in xrange(250)]) story.append( ImageAndFlowables(Image(gif), [heading, Paragraph(description, bt)], imageSide='left')) story.append(NextPageTemplate('special')) story.append(PageBreak()) VERA = ('Vera', 'VeraBd', 'VeraIt', 'VeraBI') for v in VERA: registerFont(TTFont(v, v + '.ttf')) registerFontFamily(*(VERA[:1] + VERA)) story.append( ImageAndFlowables( Image(gif, width=280, height=120), Paragraph( '''<font name="Vera">The <b>concept</b> of an <i>integrated</i> one <b><i>box</i></b> solution for <i><b>advanced</b></i> voice and data applications began with the introduction of the IMACS. The IMACS 200 carries on that tradition with an integrated solution optimized for smaller port size applications that the IMACS could not economically address. An array of the most popular interfaces and features from the IMACS has been bundled into a small 2U chassis providing the ultimate in ease of installation.</font>''', style=ParagraphStyle( name="base", fontName="Helvetica", leading=12, leftIndent=0, firstLineIndent=0, spaceBefore=9.5, fontSize=9.5, )), imageSide='left', )) story.append( ImageAndFlowables( Image(gif, width=240, height=120), Paragraph( '''The concept of an integrated one box solution for advanced voice and data applications began with the introduction of the IMACS. The IMACS 200 carries on that tradition with an integrated solution optimized for smaller port size applications that the IMACS could not economically address. An array of the most popular interfaces and features from the IMACS has been bundled into a small 2U chassis providing the ultimate in ease of installation.''', style=ParagraphStyle( name="base", fontName="Helvetica", leading=12, leftIndent=0, firstLineIndent=0, spaceBefore=9.5, fontSize=9.5, )), imageSide='left', )) doc = MyDocTemplate(outputfile('test_platypus_imageandflowables.pdf'), showBoundary=1) doc.multiBuild(story)
def getTable(self): styleSheet = getSampleStyleSheet() styNormal = styleSheet['Normal'] styNormal.spaceBefore = 20 styNormal.spaceAfter = 20 styNormal.alignment = 0 # LEFT styNormal.fontSize = 9 # self.unzip_rapporti_stratigrafici() individuo = Paragraph( "<b>Nr Individuo</b><br/>" + str(self.nr_individuo), styNormal) if self.area == None: area = Paragraph("<b>Area</b><br/>", styNormal) else: area = Paragraph("<b>Area</b><br/>" + str(self.area), styNormal) if str(self.us) == "None": us = Paragraph("<b>US</b><br/>", styNormal) else: us = Paragraph("<b>US</b><br/>" + str(self.us), styNormal) if self.eta_min == "None": eta_min = Paragraph("<b>Età min.</b><br/>", styNormal) else: eta_min = Paragraph("<b>Età min.</b><br/>" + str(self.eta_min), styNormal) if self.eta_max == "None": eta_max = Paragraph("<b>Età max.</b><br/>", styNormal) else: eta_max = Paragraph("<b>Età max.</b><br/>" + str(self.eta_max), styNormal) if self.classi_eta == None: classi_eta = Paragraph("<b>Classi età</b><br/>", styNormal) else: classi_eta = Paragraph( "<b>Classi età</b><br/>" + str(self.classi_eta), styNormal) data = [individuo, area, us, eta_min, eta_max, classi_eta] return data
def testUtf8Canvas(self): """Verify canvas declared as utf8 autoconverts. This assumes utf8 input. It converts to the encoding of the underlying font, so both text lines APPEAR the same.""" c = Canvas(outputfile('test_pdfbase_encodings_utf8.pdf')) c.drawString(100,700, testUTF8) # Set a font with UTF8 encoding c.setFont('Vera', 12) # This should pass the UTF8 through unchanged c.drawString(100,600, testUTF8) # and this should convert from Unicode to UTF8 c.drawString(100,500, testUni) # now add a paragraph in Latin-1 in the latin-1 style p = Paragraph(testUTF8, style=self.styNormal, encoding="utf-8") w, h = p.wrap(150, 100) p.drawOn(c, 100, 400) #3 c.rect(100,300,w,h) # now add a paragraph in UTF-8 in the UTF-8 style p2 = Paragraph(testUTF8, style=self.styTrueType, encoding="utf-8") w, h = p2.wrap(150, 100) p2.drawOn(c, 300, 400) #4 c.rect(100,300,w,h) # now add a paragraph in Unicode in the latin-1 style p3 = Paragraph(testUni, style=self.styNormal) w, h = p3.wrap(150, 100) p3.drawOn(c, 100, 300) c.rect(100,300,w,h) # now add a paragraph in Unicode in the UTF-8 style p4 = Paragraph(testUni, style=self.styTrueType) p4.wrap(150, 100) p4.drawOn(c, 300, 300) c.rect(300,300,w,h) # now a graphic d1 = Drawing(400,50) d1.add(Ellipse(200,25,200,12.5, fillColor=None)) d1.add(String(200,25,testUTF8, textAnchor='middle', encoding='utf-8')) d1.drawOn(c, 100, 150) # now a graphic in utf8 d2 = Drawing(400,50) d2.add(Ellipse(200,25,200,12.5, fillColor=None)) d2.add(String(200,25,testUTF8, fontName='Vera', textAnchor='middle', encoding='utf-8')) d2.drawOn(c, 100, 100) # now a graphic in Unicode with T1 font d3 = Drawing(400,50) d3.add(Ellipse(200,25,200,12.5, fillColor=None)) d3.add(String(200,25,testUni, textAnchor='middle')) d3.drawOn(c, 100, 50) # now a graphic in Unicode with TT font d4 = Drawing(400,50) d4.add(Ellipse(200,25,200,12.5, fillColor=None)) d4.add(String(200,25,testUni, fontName='Vera', textAnchor='middle')) d4.drawOn(c, 100, 0) extracted = extractText(c.getCurrentPageContent()) self.assertEquals(extracted[0], expectedCp1252) self.assertEquals(extracted[1], extracted[2]) #self.assertEquals(subsetToUnicode(self.vera, extracted[1]), testUni) c.save()
def draw(self): # Insert page number ''' if 0: #for line in self.blPara.lines: try: for frag in line.words: #print 111,frag.pageNumber, frag.text if frag.pageNumber: frag.text = str(self.canv.getPageNumber()) except Exception, e: log.debug("PmlParagraph", exc_info=1) ''' # Create outline if getattr(self, "outline", False): # Check level and add all levels last = getattr(self.canv, "outlineLast", -1) + 1 while last < self.outlineLevel: # print "(OUTLINE", last, self.text key = getUID() self.canv.bookmarkPage(key) self.canv.addOutlineEntry( self.text, key, last, not self.outlineOpen) last += 1 self.canv.outlineLast = self.outlineLevel key = getUID() # print " OUTLINE", self.outlineLevel, self.text self.canv.bookmarkPage(key) self.canv.addOutlineEntry( self.text, key, self.outlineLevel, not self.outlineOpen) last += 1 #else: # print repr(self.text)[:80] # Draw the background and borders here before passing control on to # ReportLab. This is because ReportLab can't handle the individual # components of the border independently. This will also let us # support more border styles eventually. canvas = self.canv style = self.style bg = style.backColor leftIndent = style.leftIndent bp = style.borderPadding x = leftIndent - bp y = -bp w = self.width - (leftIndent + style.rightIndent) + 2 * bp h = self.height + 2 * bp canvas.saveState() if bg: # draw a filled rectangle (with no stroke) using bg color canvas.setFillColor(bg) canvas.rect(x, y, w, h, fill=1, stroke=0) def _drawBorderLine(bstyle, width, color, x1, y1, x2, y2): # We need width and border style to be able to draw a border if width and getBorderStyle(bstyle): # If no color for border is given, the text color is used (like defined by W3C) if color is None: color = style.textColor canvas.setStrokeColor(color) canvas.setLineWidth(width) canvas.line(x1, y1, x2, y2) _drawBorderLine(style.borderTopStyle, style.borderTopWidth, style.borderTopColor, x, y+h, x+w, y+h) _drawBorderLine(style.borderBottomStyle, style.borderBottomWidth, style.borderBottomColor, x, y, x+w, y) _drawBorderLine(style.borderLeftStyle, style.borderLeftWidth, style.borderLeftColor, x, y, x, y+h) _drawBorderLine(style.borderRightStyle, style.borderRightWidth, style.borderRightColor, x+w, y, x+w, y+h) canvas.restoreState() # we need to hide the bg color (if any) so Paragraph won't try to draw it again style.backColor = None # offset the origin to compensate for the padding canvas.saveState() canvas.translate(style.paddingLeft, -style.paddingTop) # Call the base class draw method to finish up Paragraph.draw(self) canvas.restoreState() # Reset color because we need it again if we run 2-PASS like we # do when using TOC style.backColor = bg
def test0(self): "A basic document drawing some strings" c = Canvas(outputfile('test_multibyte_jpn.pdf')) c.setFont('Helvetica', 30) c.drawString(100,700, 'Japanese Font Support') c.setStrokeColor(colors.red) #unicode font automatically supplies the encoding pdfmetrics.registerFont(UnicodeCIDFont('HeiseiMin-W3')) msg = u'\u6771\u4EAC : Unicode font, unicode input' self.hDraw(c, msg, 'HeiseiMin-W3', 100, 600) msg = u'\u6771\u4EAC : Unicode font, utf8 input'.encode('utf8') self.hDraw(c, msg, 'HeiseiMin-W3', 100, 575) # now try verticals - this is broken, not sure how to make it # work in post Unicode world. pdfmetrics.registerFont(CIDFont('HeiseiMin-W3','90ms-RKSJ-V')) c.setFont('HeiseiMin-W3-90ms-RKSJ-V', 16) c.drawString(450, 650, '\223\214\213\236 vertical Shift-JIS') height = c.stringWidth('\223\214\213\236 vertical Shift-JIS', 'HeiseiMin-W3-90ms-RKSJ-V', 16) c.rect(450-8,650,16,-height) pdfmetrics.registerFont(CIDFont('HeiseiMin-W3','EUC-V')) c.setFont('HeiseiMin-W3-EUC-V', 16) c.drawString(475, 650, '\xC5\xEC\xB5\xFE vertical EUC') height = c.stringWidth('\xC5\xEC\xB5\xFE vertical EUC', 'HeiseiMin-W3-EUC-V', 16) c.rect(475-8,650,16,-height) from reportlab.platypus.paragraph import Paragraph from reportlab.lib.styles import ParagraphStyle jStyle = ParagraphStyle('jtext', fontName='HeiseiMin-W3', fontSize=12, wordWrap="CJK" ) gatwickText = '\xe3\x82\xac\xe3\x83\x88\xe3\x82\xa6\xe3\x82\xa3\xe3\x83\x83\xe3\x82\xaf\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xa8\xe9\x80\xa3\xe7\xb5\xa1\xe9\x80\x9a\xe8\xb7\xaf\xe3\x81\xa7\xe7\x9b\xb4\xe7\xb5\x90\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x82\x8b\xe5\x94\xaf\xe4\xb8\x80\xe3\x81\xae\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe5\xbd\x93\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xaf\xe3\x80\x81\xe8\xa1\x97\xe3\x81\xae\xe4\xb8\xad\xe5\xbf\x83\xe9\x83\xa8\xe3\x81\x8b\xe3\x82\x8930\xe5\x88\x86\xe3\x81\xae\xe5\xa0\xb4\xe6\x89\x80\xe3\x81\xab\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\x85\xa8\xe5\xae\xa2\xe5\xae\xa4\xe3\x81\xab\xe9\xab\x98\xe9\x80\x9f\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88\xe7\x92\xb0\xe5\xa2\x83\xe3\x82\x92\xe5\xae\x8c\xe5\x82\x99\xe3\x81\x97\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xaf5\xe5\x90\x8d\xe6\xa7\x98\xe3\x81\xbe\xe3\x81\xa7\xe3\x81\x8a\xe6\xb3\x8a\xe3\x82\x8a\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x81\xbe\xe3\x81\x9f\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xae\xe3\x81\x8a\xe5\xae\xa2\xe6\xa7\x98\xe3\x81\xaf\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xb8\xe3\x82\x92\xe3\x81\x94\xe5\x88\xa9\xe7\x94\xa8\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe4\xba\x8b\xe5\x89\x8d\xe3\x81\xab\xe3\x81\x94\xe4\xba\x88\xe7\xb4\x84\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x82\x8b\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xa0\xe3\x83\x88\xe3\x82\xa5\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xbb\xe3\x83\x91\xe3\x83\x83\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x81\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xae\xe9\xa7\x90\xe8\xbb\x8a\xe6\x96\x99\xe9\x87\x91\xe3\x81\x8c\xe5\x90\xab\xe3\x81\xbe\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82' gatwickText2= '\xe3\x82\xac\xe3\x83\x88\xe3\x82\xa6\xe3\x82\xa3\xe3\x83\x83\xe3\x82\xaf<font color=red>\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xa8\xe9\x80\xa3\xe7\xb5\xa1\xe9\x80\x9a\xe8\xb7\xaf\xe3\x81\xa7\xe7\x9b\xb4\xe7\xb5\x90</font>\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3\x82\x8b\xe5\x94\xaf\xe4\xb8\x80\xe3\x81\xae\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe5\xbd\x93\xe3\x83\x9b\xe3\x83\x86\xe3\x83\xab\xe3\x81\xaf\xe3\x80\x81\xe8\xa1\x97\xe3\x81\xae\xe4\xb8\xad\xe5\xbf\x83\xe9\x83\xa8\xe3\x81\x8b\xe3\x82\x8930\xe5\x88\x86\xe3\x81\xae\xe5\xa0\xb4\xe6\x89\x80\xe3\x81\xab\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\x85\xa8\xe5\xae\xa2\xe5\xae\xa4\xe3\x81\xab\xe9\xab\x98\xe9\x80\x9f\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88<link fg="blue" href="http://www.reportlab.com">\xe7\x92\xb0\xe5\xa2\x83\xe3\x82\x92\xe5\xae\x8c\xe5\x82\x99</link>\xe3\x81\x97\xe3\x81\xa6<u>\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99</u>\xe3\x80\x82\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xaf5\xe5\x90\x8d\xe6\xa7\x98\xe3\x81\xbe\xe3\x81\xa7\xe3\x81\x8a\xe6\xb3\x8a\xe3\x82\x8a\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe3\x81\xbe\xe3\x81\x9f\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xab\xe3\x83\xbc\xe3\x83\xa0\xe3\x81\xae\xe3\x81\x8a\xe5\xae\xa2\xe6\xa7\x98\xe3\x81\xaf\xe3\x80\x81\xe3\x82\xa8\xe3\x82\xb0\xe3\x82\xbc\xe3\x82\xaf\xe3\x83\x86\xe3\x82\xa3\xe3\x83\x96\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\xb3\xe3\x82\xb8\xe3\x82\x92\xe3\x81\x94\xe5\x88\xa9\xe7\x94\xa8\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe4\xba\x8b\xe5\x89\x8d\xe3\x81\xab\xe3\x81\x94\xe4\xba\x88\xe7\xb4\x84\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x91\xe3\x82\x8b\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xa0\xe3\x83\x88\xe3\x82\xa5\xe3\x83\x95\xe3\x83\xa9\xe3\x82\xa4\xe3\x83\xbb\xe3\x83\x91\xe3\x83\x83\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x81\xe7\xa9\xba\xe6\xb8\xaf\xe3\x81\xae\xe9\xa7\x90\xe8\xbb\x8a\xe6\x96\x99\xe9\x87\x91\xe3\x81\x8c\xe5\x90\xab\xe3\x81\xbe\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82' c.setFont('HeiseiMin-W3', 12) jPara = Paragraph(gatwickText, jStyle) jPara.wrap(300, 200) jPara.drawOn(c, 100, 220) jPara = Paragraph(gatwickText2, jStyle) jPara.wrap(300, 200) jPara.drawOn(c, 100, 320) c.setFillColor(colors.purple) tx = c.beginText(100, 200) tx.setFont('Helvetica', 12) tx.textLines("""This document shows sample output in Japanese from the Reportlab PDF library. This page shows the two fonts available and tests our ability to measure the width of glyphs in both horizontal and vertical writing, with proportional and fixed-width characters. The red boxes should be the same width (or height) as the character strings they surround. The next pages show more samples and information. """) c.drawText(tx) c.setFont('Helvetica',10) c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) c.showPage() c.setFont('Helvetica', 30) c.drawString(100,700, 'Japanese TrueType Font Support') msg = u'\u6771\u4EAC : Unicode font'.encode('utf8') msg2 = u'utf8 input 0123456789 ABCDEF'.encode('utf8') from reportlab.pdfbase.ttfonts import TTFont try: msmincho = TTFont('MS Mincho','msmincho.ttc',subfontIndex=0,asciiReadable=0) fn = ' file=msmincho.ttc subfont 0' except: try: msmincho = TTFont('MS Mincho','msmincho.ttf',asciiReadable=0) fn = 'file=msmincho.ttf' except: #Ubuntu - works on Lucid Lynx if xpdf-japanese installed try: msmincho = TTFont('MS Mincho','ttf-japanese-mincho.ttf') fn = 'file=msmincho.ttf' except: msmincho = None if msmincho is None: c.setFont('Helvetica', 12) c.drawString(100,600, 'Cannot find msmincho.ttf or msmincho.ttc') else: pdfmetrics.registerFont(msmincho) c.setFont('MS Mincho', 30) c.drawString(100,600, msg) c.drawString(100,570, msg2) c.drawString(100,540, fn) if fn.endswith('0'): try: msmincho1 = TTFont('MS Mincho 1','msmincho.ttc',subfontIndex=1,asciiPreload=0) pdfmetrics.registerFont(msmincho1) fn = ' file=msmincho.ttc subfont 1' c.setFont('MS Mincho 1',30) c.drawString(100,500,msg+fn) except: c.setFont('Helvetica',30) c.drawString(100,500,msg) c.drawString(100,470, msg2) c.drawString(100,440, fn) #test a paragraph with CJK and <br/> tags u = u'''<font color=red>\u30ac\u30c8\u30a6\u30a3\u30c3</font><br/><font color=blue>\u30af\u7a7a\u6e2f\u3068\u9023\u7d61\u901a</font><br/>\u8def\u3067\u76f4\u7d50\u3055\u308c\u3066\u3044\u308b\u552f<br/>\u4e00\u306e\u30db\u30c6\u30eb\u3067\u3042\u308b\u5f53\u30db\u30c6\u30eb\u306f\u3001\u8857\u306e\u4e2d\u5fc3\u90e8\u304b\u308930\u5206\u306e\u5834\u6240\u306b\u3054\u3056\u3044\u307e\u3059\u3002\u5168\u5ba2\u5ba4\u306b\u9ad8\u901f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8<br/>\u74b0\u5883\u3092\u5b8c\u5099\u3057\u3066\u304a\u308a\u307e\u3059\u3002\u30d5\u30a1\u30df\u30ea\u30fc\u30eb\u30fc\u30e0\u306f5\u540d\u69d8\u307e\u3067\u304a\u6cca\u308a\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u307e\u305f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30eb\u30fc\u30e0\u306e\u304a\u5ba2\u69d8\u306f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30e9\u30a6\u30f3\u30b8\u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u4e8b\u524d\u306b\u3054\u4e88\u7d04\u3044\u305f\u3060\u3051\u308b\u30bf\u30a4\u30e0\u30c8\u30a5\u30d5\u30e9\u30a4\u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u306f\u3001\u7a7a\u6e2f\u306e\u99d0\u8eca\u6599\u91d1\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u307e\u3059\u3002''' jPara = Paragraph(u, jStyle) jPara.wrap(300, 500) jPara.drawOn(c, 100, 300) c.showPage() # realistic text sample ## sample = """Adobe Acrobat ##\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xaa\x8aJ\x82\xa9\x82\xc8\x82\xad\x82\xc4\x8d\xa2\x82\xc1\x82\xbd\x82\xb1\x82\xc6\x82\xcd ##\x82\xa0\x82\xe8\x82\xdc\x82\xb9\x82\xf1\x82\xa9\x81B\x8e\x96\x8b\xc6\x8cv\x89\xe6\x8f\x91\x81A\x89c\x8b\xc6\x83\x8c\x83|\x81[\x83g ##\x81A\x83J\x83^\x83\x8d\x83O\x82\xe2\x83p\x83\x93\x83t\x83\x8c\x83b\x83g\x82\xc8\x82\xc7\x90\xa7\x8d\xec\x95\xa8\x82\xcc\x8e\xed ##\x97\xde\x82\xc9\x82\xa9\x82\xa9\x82\xed\x82\xe7\x82\xb8\x81A ##\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xcdAdobe® Acrobat® 5.0\x82\xf0\x8eg\x82\xc1\x82\xc4Adobe PDF\x81iPortable Document ##Format\x81j\x83t\x83@\x83C\x83\x8b\x82\xc9\x95\xcf\x8a\xb7\x82\xb5\x82\xdc\x82\xb5\x82\xe5\x82\xa4\x81B\x96\xb3\x8f\x9e\x94z\x95z\x82\xcc ##Adobe Acrobat Reader\x82\xf0\x8eg\x82\xa6\x82\xce\x81A\x83n\x81[\x83h\x83E\x83F\x83A\x81A\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc9\x82\xa9 ##\x82\xa9\x82\xed\x82\xe7\x82\xb8\x81A\x92N\x82\xc5\x82\xe0\x82\xa0\x82\xc8\x82\xbd\x82\xcc\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x82\xf0 ##\x83I\x83\x8a\x83W\x83i\x83\x8b\x82\xcc\x91\xcc\x8d\xd9\x82\xc5\x8aJ\x82\xad\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ##\x82\xa0\x82\xc8\x82\xbd\x82\xcc\x88\xd3\x90}\x82\xb5\x82\xbd\x82\xc6\x82\xa8\x82\xe8\x82\xc9\x8f\xee\x95\xf1\x82\xf0\x93`\x82\xa6\x82\xe9 ##\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ##\x82\xb3\x82\xe7\x82\xc9\x81AAdobe Acrobat 5.0\x82\xc5\x82\xcd\x81AWeb\x83u\x83\x89\x83E\x83U\x82\xa9\x82\xe7\x83R\x83\x81\x83\x93\x83g\x82\xe2 ##\x83}\x81[\x83N\x83A\x83b\x83v\x82\xf0\x8f\x91\x82\xab\x8d\x9e\x82\xf1\x82\xbe\x82\xe8\x81A\x93d\x8eq\x8f\x90\x96\xbc\x82\xf0\x8f\x91\x82\xab ##\x8d\x9e\x82\xdd\x81A\x8c\xb4\x96{\x82\xc6\x82\xb5\x82\xc4\x83\x8d\x81[\x83J\x83\x8b\x82\xc9\x95\xdb\x91\xb6\x82\xb7\x82\xe9\x82\xb1\x82\xc6\x82\xe0\x89\xc2\x94\\\x82\xc5\x82\xb7\x81B ##\x8a\xe9\x8b\xc6\x93\xe0\x82\xa0\x82\xe9\x82\xa2\x82\xcd\x8a\xe9\x8b\xc6\x82\xcc\x98g\x82\xf0\x92\xb4\x82\xa6\x82\xc4\x83`\x81[\x83\x80\x82\xc5 ##\x82\xcc\x83h\x83L\x83\x85\x83\x81\x83\x93\x83g\x83\x8f\x81[\x83N\x82\xcc\x90\xb6\x8eY\x90\xab\x82\xf0\x8c\xfc\x8f\xe3\x82\xb3\x82\xb9\x82\xe9\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B ## ##Adobe Acrobat 5.0\x82\xc5\x8d\xec\x90\xac\x82\xb5\x82\xbdAdobe PDF\x82\xcd\x81A(Acrobat 5.0\x82\xc5\x82\xcc\x82\xdd\x83T\x83|\x81[\x83g ##\x82\xb5\x82\xc4\x82\xa2\x82\xe9\x88\xc3\x8d\x86\x89\xbb\x90\xdd\x92\xe8\x82\xf0\x8f\x9c\x82\xa2\x82\xc4\x82\xcd)\x8f]\x97\x88\x82\xdc ##\x82\xc5\x82\xcc\x83o\x81[\x83W\x83\x87\x83\x93(3\x82\xa8\x82\xe6\x82\xd1\x82S)\x82\xccAcrobat Reader\x82\xc5\x82\xe0\x8aJ\x82\xad ##\x82\xb1\x82\xc6\x82\xaa\x82\xc5\x82\xab\x82\xdc\x82\xb7\x81B\x8f\xee\x95\xf1\x8b\xa4\x97L\x82\xcc\x83c\x81[\x83\x8b\x82\xc6\x82\xb5 ##\x82\xc4\x81A\x82\xb3\x82\xe7\x82\xc9\x90i\x95\xe0\x82\xb5\x82\xbdAdobe Acrobat 5.0\x82\xf0\x81A\x8f]\x97\x88\x82\xcc\x8a\xc2\x8b\xab ##\x82\xc5\x82\xe0\x88\xc0\x90S\x82\xb5\x82\xc4\x82\xb2\x97\x98\x97p\x82\xa2\x82\xbd\x82\xbe\x82\xaf\x82\xdc\x82\xb7\x81B ## ##\x96{\x90\xbb\x95i\x82\xf0\x83l\x83b\x83g\x83\x8f\x81[\x83N\x82\xc8\x82\xc7\x82\xf0\x89\xee\x82\xb5\x82\xc4\x92\xbc\x90\xda\x82\xa0\x82\xe9 ##\x82\xa2\x82\xcd\x8a\xd4\x90\xda\x82\xc9\x95\xa1\x90\x94\x82\xcc\x92[\x96\x96\x82\xa9\x82\xe7\x8eg\x97p\x82\xb7\x82\xe9\x8f\xea\x8d\x87\x81A ##\x82\xbb\x82\xcc\x92[\x96\x96\x82\xc6\x93\xaf\x90\x94\x82\xcc\x83\x89\x83C\x83Z\x83\x93\x83X\x82\xf0\x82\xb2\x8dw\x93\xfc\x82\xad\x82\xbe ##\x82\xb3\x82\xa2\x81B\x96{\x90\xbb\x95i\x82\xcd\x83N\x83\x89\x83C\x83A\x83\x93\x83g\x97p\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc5\x82\xa0\x82\xe8 ##\x81A\x83T\x81[\x83o\x97p\x83\\\x83t\x83g\x83E\x83F\x83A\x82\xc6\x82\xb5\x82\xc4\x82\xa8\x8eg\x82\xa2\x82\xa2\x82\xbd\x82\xbe\x82\xad\x82\xb1\x82\xc6 ##\x82\xcd\x81A\x8f\xe3\x8bL\x95\xfb\x96@\x82\xc9\x82\xe6\x82\xe9\x88\xc8\x8aO\x81A\x8b\x96\x91\xf8\x82\xb3\x82\xea\x82\xc4\x82\xa2\x82\xdc\x82\xb9 ##\x82\xf1\x81B\x95\xa1\x90\x94\x82\xcc\x83\x89\x83C\x83Z\x83\x93\x83X\x82\xf0\x82\xb2\x8dw\x93\xfc\x82\xb3\x82\xea\x82\xe9\x8f\xea\x8d\x87\x82\xc9 ##\x82\xcd\x83\x89\x83C\x83Z\x83\x93\x83X\x83v\x83\x8d\x83O\x83\x89\x83\x80\x82\xf0\x82\xb2\x97\x98\x97p\x82\xc9\x82\xc8\x82\xe9\x82\xc6\x82\xa8\x93\xbe\x82\xc5\x82\xb7\x81B ## ## ##\x81y\x82\xa8\x92m\x82\xe7\x82\xb9\x81zMicrosoft Office XP\x82\xa9\x82\xe7PDF\x82\xf0\x8d\xec\x90\xac\x82\xb7\x82\xe9\x82\xc9\x82\xcd ##""" ## c.setFont('Helvetica', 24) ## c.drawString(100,750, "Sample text from Adobe's web site") ## tx = c.beginText(100,700) ## tx.setFont('Helvetica', 10) ## tx.textLine('Note: line wrapping has not been preserved and some lines may be wrapped in mid-word.') ## tx.textLine('We are just testing that we see Japanese and not random characters!') ## tx.setFont('HeiseiMin-W3-90ms-RKSJ-H',6) ## tx.textLines(sample) ## tx.setFont('Helvetica', 8) ## tx.textLine() ## tx.textLine() ## tx.textLines(""" ## This test document shows Japanese output from the Reportlab PDF Library. ## You may use two fonts, HeiseiMin-W3 and HeiseiKakuGo-W5, and a number of ## different encodings. ## ## The available encoding names (with comments from the PDF specification) are: ## encodings_jpn = [ ## # official encoding names, comments taken verbatim from PDF Spec ## '83pv-RKSJ-H', #Macintosh, JIS X 0208 character set with KanjiTalk6 ## #extensions, Shift-JIS encoding, Script Manager code 1 ## '90ms-RKSJ-H', #Microsoft Code Page 932 (lfCharSet 0x80), JIS X 0208 ## #character set with NEC and IBM extensions ## '90ms-RKSJ-V', #Vertical version of 90ms-RKSJ-H ## '90msp-RKSJ-H', #Same as 90ms-RKSJ-H, but replaces half-width Latin ## #characters with proportional forms ## '90msp-RKSJ-V', #Vertical version of 90msp-RKSJ-H ## '90pv-RKSJ-H', #Macintosh, JIS X 0208 character set with KanjiTalk7 ## #extensions, Shift-JIS encoding, Script Manager code 1 ## 'Add-RKSJ-H', #JIS X 0208 character set with Fujitsu FMR extensions, ## #Shift-JIS encoding ## 'Add-RKSJ-V', #Vertical version of Add-RKSJ-H ## 'EUC-H', #JIS X 0208 character set, EUC-JP encoding ## 'EUC-V', #Vertical version of EUC-H ## 'Ext-RKSJ-H', #JIS C 6226 (JIS78) character set with NEC extensions, ## #Shift-JIS encoding ## 'Ext-RKSJ-V', #Vertical version of Ext-RKSJ-H ## 'H', #JIS X 0208 character set, ISO-2022-JP encoding, ## 'V', #Vertical version of H ## 'UniJIS-UCS2-H', #Unicode (UCS-2) encoding for the Adobe-Japan1 character ## #collection ## 'UniJIS-UCS2-V', #Vertical version of UniJIS-UCS2-H ## 'UniJIS-UCS2-HW-H', #Same as UniJIS-UCS2-H, but replaces proportional Latin ## #characters with half-width forms ## 'UniJIS-UCS2-HW-V' #Vertical version of UniJIS-UCS2-HW-H ## ] ## ## The next few pages show the complete character set available in the encoding ## "90ms-RKSJ-H" - Shift-JIS with the standard Microsoft extensions. ## """) ## c.drawText(tx) ## ## c.setFont('Helvetica',10) ## c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) ## ## ## ## c.showPage() from reportlab.lib import textsplit c.setFont('HeiseiMin-W3', 14) y = 700 c.drawString(70, y, 'cannot end line') y -= 20 for group in textsplit.CANNOT_START_LINE: c.drawString(70, y, group) y -= 20 c.setFont('Helvetica',10) c.drawString(70, y, ' '.join([ascii(x)[4:-1] for x in group])) c.setFont('HeiseiMin-W3', 14) y -= 20 y -= 20 c.drawString(70, y, 'cannot end line') y -= 20 for group in textsplit.CANNOT_END_LINE: c.drawString(70, y, group) y -= 20 c.setFont('Helvetica',10) c.drawString(70, y, ' '.join([ascii(x)[2:] for x in group])) c.setFont('HeiseiMin-W3', 14) y -= 20 c.showPage() #utf8 encoded paragraph sample2_uni = u'''\u30ac\u30c8\u30a6\u30a3\u30c3\u30af\u7a7a\u6e2f\u3068\u9023\u7d61\u901a \u8def\u3067\u76f4\u7d50\u3055\u308c\u3066\u3044\u308b\u552f\u4e00\u306e\u30db\u30c6\u30eb \u3067\u3042\u308b\u5f53\u30db\u30c6\u30eb\u306f\u3001\u8857\u306e\u4e2d\u5fc3\u90e8\u304b \u308930\u5206\u306e\u5834\u6240\u306b\u3054\u3056\u3044\u307e\u3059\u3002\u5168\u5ba2\u5ba4 \u306b\u9ad8\u901f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u74b0\u5883\u3092\u5b8c\u5099 \u3057\u3066\u304a\u308a\u307e\u3059\u3002\u30d5\u30a1\u30df\u30ea\u30fc\u30eb\u30fc\u30e0 \u306f5\u540d\u69d8\u307e\u3067\u304a\u6cca\u308a\u3044\u305f\u3060\u3051\u307e\u3059\u3002 \u307e\u305f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30eb\u30fc\u30e0\u306e\u304a \u5ba2\u69d8\u306f\u3001\u30a8\u30b0\u30bc\u30af\u30c6\u30a3\u30d6\u30e9\u30a6\u30f3\u30b8 \u3092\u3054\u5229\u7528\u3044\u305f\u3060\u3051\u307e\u3059\u3002\u4e8b\u524d\u306b\u3054 \u4e88\u7d04\u3044\u305f\u3060\u3051\u308b\u30bf\u30a4\u30e0\u30c8\u30a5\u30d5\u30e9\u30a4 \u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u306f\u3001\u7a7a\u6e2f\u306e\u99d0\u8eca\u6599 \u91d1\u304c\u542b\u307e\u308c\u3066\u304a\u308a\u307e\u3059\u3002''' oneline_uni = u''.join(sample2_uni.split()) sample2_utf8 = oneline_uni.encode('utf8') from reportlab.platypus import Paragraph from reportlab.lib.styles import ParagraphStyle jsty = ParagraphStyle('japanese',fontName='HeiseiMin-W3', wordWrap='CJK') jpara = Paragraph(oneline_uni, style=jsty) c.drawString(100, 710, 'Try to wrap a paragraph using a style with wordWrap="CJK"') w, h = jpara.wrap(400,400) jpara.drawOn(c, 100, 700 - h) #now try to split it... c.drawString(100, 510, 'Now try to split a paragraph as if over a page break') topPara, bottomPara = jpara.split(400, 30) w1, h1 = topPara.wrap(400, 30) topPara.drawOn(c, 100, 450) w2, h2 = bottomPara.wrap(400, 30) bottomPara.drawOn(c, 100, 400) #print 'split into heights %0.2f, %0.2f' % (topPara.height, bottomPara.height) ## c.showPage() ## ## ## # full kuten chart in EUC ## c.setFont('Helvetica', 24) ## c.drawString(72,750, 'Characters available in JIS 0208-1997') ## y = 600 ## for row in range(1, 95): ## KutenRowCodeChart(row, 'HeiseiMin-W3','EUC-H').drawOn(c, 72, y) ## y = y - 125 ## if y < 50: ## c.setFont('Helvetica',10) ## c.drawCentredString(297, 36, 'Page %d' % c.getPageNumber()) ## c.showPage() ## y = 700 ## ## c.showPage() #try with Unicode truetype - Mincho for starters ## import time ## started = time.clock() ## c.showPage() ## c.setFont('Helvetica',16) ## c.drawString(100,750, 'About to say Tokyo in MS Gothic...') ## ## from reportlab.pdfbase.ttfonts import TTFont, TTFontFile ## f = TTFontFile("msgothic.ttf") ## print f.name ## ## pdfmetrics.registerFont(TTFont(f.name, f)) ## ## utfText = u'Andr\202'.encode('utf8') ## c.setFont(f.name,16) ## c.drawString(100,700, utfText) ## ## ## #tokyoUCS2 = '\x67\x71\x4E\xAC' ## finished = time.clock() c.save() if VERBOSE: print('saved test_multibyte_jpn.pdf')
def testAutoLeading(self): from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame, PageBegin from reportlab.lib.units import inch from reportlab.platypus.flowables import AnchorFlowable class MyDocTemplate(BaseDocTemplate): _invalidInitArgs = ('pageTemplates', ) def __init__(self, filename, **kw): self.allowSplitting = 0 kw['showBoundary'] = 1 BaseDocTemplate.__init__(self, filename, **kw) self.addPageTemplates([ PageTemplate( 'normal', [ Frame(inch, inch, 6.27 * inch, 9.69 * inch, id='first', topPadding=0, rightPadding=0, leftPadding=0, bottomPadding=0, showBoundary=ShowBoundaryValue(color="red")) ], ), ]) from reportlab.lib.testutils import testsFolder styleSheet = getSampleStyleSheet() normal = ParagraphStyle(name='normal', fontName='Times-Roman', fontSize=12, leading=1.2 * 12, parent=styleSheet['Normal']) normal_sp = ParagraphStyle(name='normal_sp', parent=normal, alignment=TA_JUSTIFY, spaceBefore=12) texts = [ '''Furthermore, a subset of <font size="14">English sentences</font> interesting on quite independent grounds is not quite equivalent to a stipulation to place <font color="blue">the constructions <img src="%(testsFolder)s/../docs/images/testimg.gif"/> into these various categories.</font>''' % dict(testsFolder=testsFolder), '''We will bring <font size="18">Ugly Things</font> in favor of The following thesis: most of the methodological work in Modern Linguistics can be <img src="%(testsFolder)s/../docs/images/testimg.gif" valign="baseline" /> defined in such <img src="%(testsFolder)s/../docs/images/testimg.gif" valign="10" /> a way as to impose problems of phonemic and <u>morphological <img src="%(testsFolder)s/../docs/images/testimg.gif" valign="top"/> </u> analysis.''' % dict(testsFolder=testsFolder) ] story = [] a = story.append t = 'u' n = 1 for s in (normal, normal_sp): for autoLeading in ('', 'min', 'max'): a( Paragraph('style=%s(autoLeading=%s)' % (s.name, autoLeading), style=normal_sp)) a( Paragraph( '<para autoleading="%s"><%s>%s</%s>. %s <%s>%s</%s>. %s</para>' % (autoLeading, t, ' '.join( (n + 1) * ['A']), t, texts[0], t, ' '.join( (n + 1) * ['A']), t, texts[1]), style=s)) a( Paragraph( '''<img src="%(testsFolder)s/../docs/images/testimg.gif" valign="top"/> image is very first thing in the line.''' % dict(testsFolder=testsFolder), style=normal)) a( Paragraph( 'some text.... some more.... some text.... some more....', normal)) a( Paragraph( '<img src="%(testsFolder)s/../docs/images/testimg.gif" width="0.57in" height="0.19in" /> some text <br /> ' % dict(testsFolder=testsFolder), normal)) a( Paragraph( 'some text.... some more.... some text.... some more....', normal)) a( Paragraph( '<img src="%(testsFolder)s/../docs/images/testimg.gif" width="0.57in" height="0.19in" /> <br /> ' % dict(testsFolder=testsFolder), normal)) a( Paragraph( 'some text.... some more.... some text.... some more....', normal)) #Volker Haas' valign tests fmt = '''<font color="red">%(valign)s</font>: Furthermore, a <u>subset</u> <strike>of</strike> <font size="14">English sentences</font> interesting on quite independent grounds is not quite equivalent to a stipulation to place <img src="%(testsFolder)s/../docs/images/redsquare.png" width="0.5in" height="0.5in" valign="%(valign)s"/> the constructions into these <u>various</u> categories. We will bring <font size="18">Ugly Things</font> in favor of The following thesis: most of the methodological work in Modern Linguistics can be defined in such a way as to impose problems of phonemic and <u>morphological</u> <strike>analysis</strike>.''' p_style = ParagraphStyle('Normal') p_style.autoLeading = 'max' for valign in ( 'baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom', '0%', '2in', ): a( Paragraph(fmt % dict(valign=valign, testsFolder=testsFolder), p_style)) a( XPreformatted( fmt % dict(valign=valign, testsFolder=testsFolder), p_style)) doc = MyDocTemplate( outputfile('test_platypus_paragraphs_autoleading.pdf')) doc.build(story)
def draw(self): self.canv.saveState() self.canv.translate(0,0) self.canv.rotate(self.angle) Paragraph.draw(self) self.canv.restoreState()
def _test0(self): "This makes one long multi-page paragraph." # Build story. story = [] a = story.append styleSheet = getSampleStyleSheet() h1 = styleSheet['Heading1'] h1.pageBreakBefore = 1 h1.keepWithNext = 1 h2 = styleSheet['Heading2'] h2.frameBreakBefore = 1 h2.keepWithNext = 1 h3 = styleSheet['Heading3'] h3.backColor = colors.cyan h3.keepWithNext = 1 bt = styleSheet['BodyText'] btj = ParagraphStyle('bodyText1j', parent=bt, alignment=TA_JUSTIFY) btr = ParagraphStyle('bodyText1r', parent=bt, alignment=TA_RIGHT) btc = ParagraphStyle('bodyText1c', parent=bt, alignment=TA_CENTER) a( Paragraph( """ <a name='top'/>Subsequent pages test pageBreakBefore, frameBreakBefore and keepTogether attributes. Generated at %s. The number in brackets at the end of each paragraph is its position in the story. (%d)""" % (time.ctime(946684800.0 if invariant else time.time()), len(story)), bt)) for i in range(10): a(Paragraph('Heading 1 always starts a new page (%d)' % len(story), h1)) for j in range(3): a( Paragraph( 'Heading1 paragraphs should always' 'have a page break before. Heading 2 on the other hand' 'should always have a FRAME break before (%d)' % len(story), bt)) a( Paragraph( 'Heading 2 always starts a new frame (%d)' % len(story), h2)) a( Paragraph( 'Heading1 paragraphs should always' 'have a page break before. Heading 2 on the other hand' 'should always have a FRAME break before (%d)' % len(story), bt)) for j in range(3): a( Paragraph( randomText(theme=PYTHON, sentences=2) + ' (%d)' % len(story), bt)) a( Paragraph( 'I should never be at the bottom of a frame (%d)' % len(story), h3)) a( Paragraph( randomText(theme=PYTHON, sentences=1) + ' (%d)' % len(story), bt)) for align, bts in [('left', bt), ('JUSTIFIED', btj), ('RIGHT', btr), ('CENTER', btc)]: a(Paragraph('Now we do <br/> tests(align=%s)' % align, h1)) a(Paragraph('First off no br tags', h3)) a(Paragraph(_text1, bts)) a(Paragraph("<br/> after 'the' in line 4", h3)) a( Paragraph(_text1.replace('forms of the', 'forms of the<br/>', 1), bts)) a(Paragraph("2*<br/> after 'the' in line 4", h3)) a( Paragraph( _text1.replace('forms of the', 'forms of the<br/><br/>', 1), bts)) a(Paragraph("<br/> after 'I suggested ' in line 5", h3)) a(Paragraph(_text1.replace('I suggested ', 'I suggested<br/>', 1), bts)) a(Paragraph("2*<br/> after 'I suggested ' in line 5", h3)) a( Paragraph( _text1.replace('I suggested ', 'I suggested<br/><br/>', 1), bts)) a(Paragraph("<br/> at the end of the paragraph!", h3)) a(Paragraph("""text one<br/>text two<br/>""", bts)) a(Paragraph("Border with <br/> at the end of the paragraph!", h3)) bt1 = ParagraphStyle('bodyText1', bts) bt1.borderWidth = 0.5 bt1.borderColor = colors.toColor('red') bt1.backColor = colors.pink bt1.borderRadius = 2 bt1.borderPadding = 3 a(Paragraph("""text one<br/>text two<br/>""", bt1)) a(Paragraph("Border no <br/> at the end of the paragraph!", h3)) bt1 = ParagraphStyle('bodyText1', bts) bt1.borderWidth = 0.5 bt1.borderColor = colors.toColor('red') bt1.backColor = colors.pink bt1.borderRadius = 2 bt1.borderPadding = 3 a(Paragraph("""text one<br/>text two""", bt1)) a(Paragraph("Different border style!", h3)) bt2 = ParagraphStyle('bodyText1', bt1) bt2.borderWidth = 1.5 bt2.borderColor = colors.toColor('blue') bt2.backColor = colors.gray bt2.borderRadius = 3 bt2.borderPadding = 3 a(Paragraph("""text one<br/>text two<br/>""", bt2)) for i in 0, 1, 2: P = Paragraph( """This is a paragraph with <font color='blue'><a href='#top'>with an incredibly long and boring link in side of it that contains lots and lots of stupidly boring and worthless information. So that we can split the link and see if we get problems like Dinu's. I hope we don't, but you never do Know.</a></font>""", bt) a(P) doc = MyDocTemplate(outputfile('test_platypus_breaking.pdf')) doc.multiBuild(story)
def run(): styles = getSampleStyleSheet() styleN = styles['Normal'] styleH = styles['Heading1'] story = [] storyAdd = story.append #for codeNames in code storyAdd(Paragraph('I2of5', styleN)) storyAdd(I2of5(1234, barWidth=inch * 0.02, checksum=0)) storyAdd(Paragraph('MSI', styleN)) storyAdd(MSI(1234)) storyAdd(Paragraph('Codabar', styleN)) storyAdd(Codabar("A012345B", barWidth=inch * 0.02)) storyAdd(Paragraph('Code 11', styleN)) storyAdd(Code11("01234545634563")) storyAdd(Paragraph('Code 39', styleN)) storyAdd(Standard39("A012345B%R")) storyAdd(Paragraph('Extended Code 39', styleN)) storyAdd(Extended39("A012345B}")) storyAdd(Paragraph('Code93', styleN)) storyAdd(Standard93("CODE 93")) storyAdd(Paragraph('Extended Code93', styleN)) storyAdd(Extended93("L@@K! Code 93 :-)")) #, barWidth=0.005 * inch)) storyAdd(Paragraph('Code 128', styleN)) storyAdd(Code128("AB-12345678")) storyAdd(Paragraph('Code 128 Auto', styleN)) storyAdd(Code128Auto("AB-12345678")) storyAdd(Paragraph('USPS FIM', styleN)) storyAdd(FIM("A")) storyAdd(Paragraph('USPS POSTNET', styleN)) storyAdd(POSTNET('78247-1043')) storyAdd(Paragraph('USPS 4 State', styleN)) storyAdd(USPS_4State('01234567094987654321', '01234567891')) from reportlab.graphics.barcode import createBarcodeDrawing storyAdd(Paragraph('EAN13', styleN)) storyAdd(createBarcodeDrawing('EAN13', value='123456789012')) storyAdd(Paragraph('EAN13 quiet=False', styleN)) storyAdd(createBarcodeDrawing('EAN13', value='123456789012', quiet=False)) storyAdd(Paragraph('EAN8', styleN)) storyAdd(createBarcodeDrawing('EAN8', value='1234567')) storyAdd(PageBreak()) storyAdd(Paragraph('EAN5 price=True', styleN)) storyAdd(createBarcodeDrawing('EAN5', value='11299', price=True)) storyAdd(Paragraph('EAN5 price=True quiet=False', styleN)) storyAdd( createBarcodeDrawing('EAN5', value='11299', price=True, quiet=False)) storyAdd(Paragraph('EAN5 price=False', styleN)) storyAdd(createBarcodeDrawing('EAN5', value='11299', price=False)) storyAdd(Paragraph('ISBN alone', styleN)) storyAdd(createBarcodeDrawing('ISBN', value='9781565924796')) storyAdd(Paragraph('ISBN with ean5 price', styleN)) storyAdd(createBarcodeDrawing('ISBN', value='9781565924796', price='01299')) storyAdd(Paragraph('ISBN with ean5 price, quiet=False', styleN)) storyAdd( createBarcodeDrawing('ISBN', value='9781565924796', price='01299', quiet=False)) storyAdd(Paragraph('UPCA', styleN)) storyAdd(createBarcodeDrawing('UPCA', value='03600029145')) storyAdd(Paragraph('USPS_4State', styleN)) storyAdd( createBarcodeDrawing('USPS_4State', value='01234567094987654321', routing='01234567891')) storyAdd(Paragraph('QR', styleN)) storyAdd(createBarcodeDrawing('QR', value='01234567094987654321')) storyAdd(Paragraph('QR', styleN)) storyAdd( createBarcodeDrawing('QR', value='01234567094987654321', x=30, y=50)) storyAdd(Paragraph('QR in drawing at (0,0)', styleN)) d = Drawing(100, 100) d.add( Rect(0, 0, 100, 100, strokeWidth=1, strokeColor=colors.red, fillColor=None)) d.add(QrCodeWidget(value='01234567094987654321')) storyAdd(d) storyAdd(Paragraph('QR in drawing at (10,10)', styleN)) d = Drawing(100, 100) d.add( Rect(0, 0, 100, 100, strokeWidth=1, strokeColor=colors.red, fillColor=None)) d.add(Line(7.5, 10, 12.5, 10, strokeWidth=0.5, strokeColor=colors.blue)) d.add(Line(10, 7.5, 10, 12.5, strokeWidth=0.5, strokeColor=colors.blue)) d.add(QrCodeWidget(value='01234567094987654321', x=10, y=10)) storyAdd(d) storyAdd(Paragraph('Label Size', styleN)) storyAdd(XBox((2.0 + 5.0 / 8.0) * inch, 1 * inch, '1x2-5/8"')) storyAdd(Paragraph('Label Size', styleN)) storyAdd(XBox((1.75) * inch, .5 * inch, '1/2x1-3/4"')) SimpleDocTemplate('out.pdf').build(story) print('saved out.pdf')
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 = 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<onDraw name="drawIndexEntryEnd" label="%s"/>' % ( texts[-1], label) for text in texts: #Platypus and RML differ on how parsed XML attributes are escaped. #e.g. <index item="M&S"/>. 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 beforeDrawPage(self, canvas, doc): canvas.setFont(serif_font, 10) canvas.setLineWidth(0) # header canvas.line( header_margin_hor, page_height - header_margin_vert, page_width - header_margin_hor, page_height - header_margin_vert, ) if pdfstyles.show_page_header: canvas.saveState() canvas.resetTransforms() if not self.rtl: h_offset = header_margin_hor else: h_offset = 1.5 * header_margin_hor canvas.translate(h_offset, page_height - header_margin_vert - 0.1 * cm) p = Paragraph(self.title, text_style()) p.canv = canvas p.wrap( page_width - header_margin_hor * 2.5, page_height ) # add an extra 0.5 margin to have enough space for page number p.drawPara() canvas.restoreState() if not self.rtl: h_pos = page_width - header_margin_hor d = canvas.drawRightString else: h_pos = header_margin_hor d = canvas.drawString d(h_pos, page_height - header_margin_vert + 0.1 * cm, "%d" % doc.page) # Footer canvas.saveState() canvas.setFont(serif_font, 8) canvas.line(footer_margin_hor, footer_margin_vert, page_width - footer_margin_hor, footer_margin_vert) if pdfstyles.show_page_footer: p = Paragraph(formatter.cleanText(pagefooter, escape=False), text_style()) p.canv = canvas w, h = p.wrap(page_width - header_margin_hor * 2.5, page_height) p.drawOn(canvas, footer_margin_hor, footer_margin_vert - 10 - h) canvas.restoreState()
def addParas(words): txt = u' '.join([(len(w) > 5 and u'<index item=%s/>%s' % (quoteattr(commajoin([w[:2], w[:3], w])), w) or w) for w in words]) para = Paragraph(txt, makeBodyStyle()) story.append(para)