0
ReportLab Paragraphs
     Reloaded

      Dinu C. Gherman
      gherman@python.net

     EuroPython Conference
       2008...
Agenda
• ReportLab Overview
• Paragraphs
• Paragraphs Reloaded & Examples
• Summary
ReportLab Overview
General Features
• Generating PDF with Python (+ some C)
• Content: fonts, graphics, images, tables
• PDF features: page t...
Technologies
• PDF
• Type1 and TrueType fonts
• PIL
• libart
• Unicode (UTF-8)
Meta Info
• Developped since ca. 1996
• By Andy Robinson, Robin Becker, et al.
• Current: SVN (v. 2.1 + 12 months)
• Open ...
1st Layer: Canvas
• Corresponds to a single page with
• Text,
• Graphics,
• PDF features (hyperlinks, page transitions...)...
Example 1
#!/usr/bin/env python
# _*_ coding: UTF-8 _*_

from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pag...
###

from reportlab.lib import colors
from reportlab.lib.units import cm

# circle
canv.setStrokeColor(colors.green)
canv....
2nd Layer: Platypus
• ”Page LAyout TYPography Using Scripts“
• Frames
• PageTemplate
• DocumentTemplate
• Content: Flowabl...
Structure
   Flow.          Flow.    Flow.
   Frame
                  Flow.    Flow.
Flow.    Flow.
                  Flow...
Flowables
• Content related:
  Paragraph, Preformatted, Image, Table,
  XBox, Spacer, …
• Logic related:
  FrameBreak, Pag...
Example 2
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen.canvas import Ca...
class TwoColumnDocTemplate(BaseDocTemplate):
    "A simple two-column document template."

   def __init__(self, filename,...
explicabo distinctio animi ad ipsam veniam enim,
                                                Maiores cupiditate placea...
3rd Layer: RML
• ”Report Markup Language“
• Platypus in XML + Black Box + ¥$€
• See also: z3c.rml (S. Richter et al. – fre...
Paragraphs
Features
• Subclass of the Flowable class
• Core class in Platypus (paragraph.py)
• No alternative (except para.py – R.I.P...
Global Style Attributes
• fontName, fontSize, textColor, backColor
• firstLineIndent, leftIndent, rightIndent
• alignment, ...
Local Style Attributes
• XML tags in paragraph text:
• font, br, b, i, u, strong, strike, a, link, img
• superscript, subs...
Lacking…
• Inline images (new in SVN)
• Hyphenation
• Kerning
• Code comprehensibility
• Code extensibility
          ”Rep...
Paragraphs Reloaded
New Approach
• New Flowable!
• MinimalParagraph class
• Easily extensible (shown in subclasses)
• Linebreaks (and not much...
Sample: XBox
class XBox(Flowable):

    def __init__(self, width, height, text='A Box'):
        Flowable.__init__(self)
 ...
Key Idea: ”Events“
• Input text: "Hello world"
• Parsed: [{"text":"Hello"}, {"text":"world"}]
• Word widths: [{"text":"Hel...
MinimalParagraph
• Global attributes: fontName, fontSize,
  leading, firstLineIndent, leftIndent,
  rightIndent, textColor,...
Alice was beginning to get very tired of sitting   well, and noticed that they were filled with
by her sister on the bank,...
ColouredParagraph
#!/bin/env/python                        def draw(self):
# -*- coding: utf-8 -*-                    "Ren...
!"#$% &'( )# *+(, -+( .+(,/ 0 $#")-123 4")         1+(L5#6-E ,5- !"-6( )#$" +") 6##!-) +6#"8 (5-
5-1- 467*- .-8+" (# 8-( 1...
!"#$% &'( )# *+(, -+( .+(,/ 0 $#")-123 4")         1+(L5#6-E ,5- !"-6( )#$" +") 6##!-) +6#"8 (5-
5-1- 467*- .-8+" (# 8-( 1...
R1#*6" .#00%*;-%%7< >"# O%'0# $):# )
")+ 0%/#"%, 2)..#* 4*&% &"# 0#)5 =)*+ 4* &")&     0'++#* .#)( %'& %2 &"# ,)&#15 )*+ 0...
R1#*6" .#00%*;-%%7< >"# O%'0# $):# )
 ")+ 0%/#"%, 2)..#* 4*&% &"# 0#)5 =)*+ 4* &")&     0'++#* .#)( %'& %2 &"# ,)&#15 )*+ ...
IconizedParagraph
• Input text: "Hello file://smiley.jpeg world"
• Events: [{"text":"Hello", …}, {"text":"file://
  smiley.j...
*"56 N35 *$, /3';,( #3 ;,# 34# 3= #$"# ("-1
$"//& "'( 5"'(,- "%34# "23'; #$3*, %,(* 3=
%-0;$# =/35,-* "'( #$3*, !33/ =34'#...
CHAPTER II

The Pool of Tears

`Curiouser       and curiouser!' cried Alice (she
was so much surprised, that for the momen...
ReportLab Paragraph                  CountingParagraph

 If you need something that      0    If you need something that
 ...
Summary
Code Length
rlpara dinu$ pycount2.py *.py
   lines    code     doc comment    blank   file
    2380    1831      66      3...
$ run_performance_test.py --mnp 500 ../input/alice30.txt
input file: ../input/alice30.txt

                    Runtime
#wo...
Current State
• Family of paragraph classes
• Usually domain specific (e.g. kerning)
• Small code size
• Ca. 2–3 x slower t...
Future
• Further Paragraph attributes
• KerningParagraph
• XMLParagraph (tags)
• General callback mechanism
• RTLParagraph...
Links
•   http://www.dinu-gherman.net/tmp/
    alterparagraphs-0.3.2.tar.gz

•   http://www.reportlab.com

•   http://pypi...
Questions?
            ” three questions, and that is enough,‘
’I have answered
      Said his father; ’don't give yoursel...
Upcoming SlideShare
Loading in...5
×

ReportLab Paragraphs Reloaded-EuroPython 2008

1,193

Published on

A presentation about alternative implementations for ReportLab paragraphs given at EuroPython 2008.

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,193
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "ReportLab Paragraphs Reloaded-EuroPython 2008"

  1. 1. ReportLab Paragraphs Reloaded Dinu C. Gherman gherman@python.net EuroPython Conference 2008-07-07, Vilnius
  2. 2. Agenda • ReportLab Overview • Paragraphs • Paragraphs Reloaded & Examples • Summary
  3. 3. ReportLab Overview
  4. 4. General Features • Generating PDF with Python (+ some C) • Content: fonts, graphics, images, tables • PDF features: page transitions, hyperlinks, outline, … • Graphics import as bitmaps and SVG (ext.) • Graphics export as bitmaps, PDF, EPS, SVG
  5. 5. Technologies • PDF • Type1 and TrueType fonts • PIL • libart • Unicode (UTF-8)
  6. 6. Meta Info • Developped since ca. 1996 • By Andy Robinson, Robin Becker, et al. • Current: SVN (v. 2.1 + 12 months) • Open Source • Closed Source: RML, PDF encryption, PDF import
  7. 7. 1st Layer: Canvas • Corresponds to a single page with • Text, • Graphics, • PDF features (hyperlinks, page transitions...) • Can also be saved as a bitmap, EPS, SVG
  8. 8. Example 1 #!/usr/bin/env python # _*_ coding: UTF-8 _*_ from reportlab.pdfgen.canvas import Canvas from reportlab.lib.pagesizes import A4 canv = Canvas("helloworld.pdf", pagesize=A4) ### ... canv.showPage() canv.save() …
  9. 9. ### from reportlab.lib import colors from reportlab.lib.units import cm # circle canv.setStrokeColor(colors.green) canv.setFillColor(colors.red) canv.setLineWidth(0.5*cm) x, y = 10*cm, 10*cm canv.circle(x, y, 5*cm, stroke=True, fill=True) Hello world! # text canv.setFillColor(colors.yellow) canv.setFont("Helvetica", 36) canv.drawCentredString(x, y, u"Hello world!")
  10. 10. 2nd Layer: Platypus • ”Page LAyout TYPography Using Scripts“ • Frames • PageTemplate • DocumentTemplate • Content: Flowables & Styles (”Story“) • Rendered as PDF document
  11. 11. Structure Flow. Flow. Flow. Frame Flow. Flow. Flow. Flow. Flow. Flow. Flow. Flow. Flow. Flow. Frame Frame Frame Frame PageTemplate PageTemplate DocumentTemplate
  12. 12. Flowables • Content related: Paragraph, Preformatted, Image, Table, XBox, Spacer, … • Logic related: FrameBreak, PageBreak, CondPageBreak, … • Layout related: KeepWithNext, KeepInFrame, …
  13. 13. Example 2 from reportlab.lib.units import cm from reportlab.lib.pagesizes import A4 from reportlab.pdfgen.canvas import Canvas from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame, Paragraph from reportlab.lib.styles import getSampleStyleSheet from django.contrib.webdesign import lorem_ipsum as li PAGESIZE = A4 …
  14. 14. class TwoColumnDocTemplate(BaseDocTemplate): "A simple two-column document template." def __init__(self, filename, **kw): m = margin = 2*cm tm = topMargin = 2*cm bm = bottomMargin = 2*cm cw, ch = (PAGESIZE[0]-2*m)/2., (PAGESIZE[1]-tm) leftCol = Frame(m, bm, cw-0.75*cm, ch-tm, leftPadding=0, topPadding=0, rightPadding=0, bottomPadding=0, id="left", showBoundary=True ) rightCol = Frame(cw+2.7*cm, bm, cw-0.75*cm, ch-tm, leftPadding=0, topPadding=0, rightPadding=0, bottomPadding=0, id="right", showBoundary=True ) apply(BaseDocTemplate.__init__, (self, filename), kw) allPages = PageTemplate("all", [leftCol, rightCol]) self.addPageTemplates([allPages]) …
  15. 15. explicabo distinctio animi ad ipsam veniam enim, Maiores cupiditate placeat fugit quis recusandae amet eveniet praesentium def generateTwoColDocument(outPath): veniam obcaecati consectetur maxime delectus? Dolorem perferendis accusantium Harum molestias iure at nemo labore quod repellat veniam optio quas ducimus eum similique, incidunt facilis itaque "Create a 2-col doc with rand. text." obcaecati iusto fugiat, enim unde voluptas illo? Enim Quidem explicabo officiis quasi soluta exercitationem eaque repudiandae cupiditate ad accusantium, alias blanditiis ullam nobis suscipit praesentium? Nostrum error tempore ducimus a dicta aut voluptates vitae, quaerat ullam recusandae esse nulla maiores eos error cupiditate assumenda quia culpa id illum rerum eligendi adipisci consequatur dolores, sequi cum ipsam ipsum, quisquam blanditiis corporis fugiat veniam dolor voluptates ipsa tempora, quibusdam excepturi facilis quaerat exercitationem cum tempore nostrum quasi labore nobis perspiciatis illo eaque vero voluptas repudiandae? Eos hic reiciendis excepturi pariatur quos? Ipsum odio ipsa quidem amet impedit recusandae ad esse. stylesheet = getSampleStyleSheet() recusandae quis, corporis cupiditate laboriosam alias ratione tempore? Exercitationem voluptates alias aspernatur odio laboriosam dolores unde vero. Excepturi sed repellendus facere Blanditiis quo at consectetur impedit, iure fugiat sed ullam h1 = stylesheet['Heading1'] voluptate nesciunt temporibus facilis, dignissimos aspernatur maiores assumenda nostrum, error nisi accusamus officiis quo deleniti facere recusandae Ipsum omnis deleniti saepe sapiente, quibusdam neque aspernatur delectus quasi iusto a facilis, tenetur nostrum incidunt nesciunt veritatis, velit sunt nostrum h2 = stylesheet['Heading2'] animi quidem ea excepturi, recusandae quasi dolor quo quae necessitatibus? Delectus suscipit soluta nulla molestiae unde repellendus odit sint non officia veniam harum sunt, laudantium iusto voluptatibus, omnis. fuga facere nihil sed aspernatur placeat, impedit libero Cupiditate minima pariatur itaque alias suscipit, nulla repellendus laudantium nisi nihil eveniet reiciendis? bt = stylesheet['BodyText'] culpa atque deleniti id et tenetur aliquid unde qui vel Exercitationem nemo possimus debitis? Aliquid sint, cumque rerum maiores voluptate, quas et quia? nesciunt cum natus eveniet obcaecati fugiat Quam debitis praesentium vitae, nesciunt quas repellendus, et numquam odit velit alias, dolor aut distinctio quisquam, impedit tempora architecto aut? quasi ut tempora itaque nemo earum animi, ipsa Perspiciatis et ullam sit commodi cumque optio similique natus inventore nobis sed quia eaque totam pariatur, eum totam minus et quis, vero itaque tempore incidunt dolorum, molestias rem blanditiis ad molestias eius sed eligendi veniam quae dolore autem. doloribus, unde rem odit similique sapiente eveniet? st = story = [] Tempora voluptatibus quo dicta expedita tempore harum porro? Cumque blanditiis ut facilis quasi Cupiditate possimus dignissimos laborum consectetur laudantium, illum ipsa perferendis adipisci veritatis p = li.words(3, common=False) Aut omnis atque molestiae est inventore delectus ipsam a commodi, tempora ratione unde quia non nemo voluptate, assumenda molestias unde aperiam pariatur nobis dolores, quisquam corporis iste quaerat quisquam cumque debitis, ea incidunt odit expedita illum atque ea sint doloribus iusto nemo, amet quidem facilis, molestiae quam sint doloremque officia nemo explicabo qui. Libero maxime magnam, dolores p = p.capitalize() nesciunt dolor commodi accusantium cumque ipsum, praesentium illum pariatur? Dicta nobis culpa placeat quaerat quos nisi dolorem libero eaque at, nobis eaque tenetur repellat distinctio pariatur debitis praesentium, omnis labore libero magnam officia. Quis aperiam exercitationem repudiandae dolore et fugiat neque? tempore perferendis asperiores pariatur cum, st.append(Paragraph(p, style=h1)) Doloremque et non architecto quas, laudantium accusamus error ratione, consectetur minus saepe repellat a deserunt minima explicabo beatae possimus, veritatis harum, similique aliquid exercitationem cum facilis fugit similique ad porro sapiente suscipit odit assumenda, natus unde non veniam quas illum enim alias quod qui excepturi, autem provident fugiat amet sequi quis molestias. for i in range(10): pariatur ullam perferendis ipsa fugit. Minus fugiat sint consequatur delectus necessitatibus eius eum. Voluptate sit ratione nobis aperiam omnis fugit Mollitia amet voluptatum facere blanditiis p = li.words(5, common=False) accusantium totam sequi accusamus, nulla perspiciatis ut corporis eos possimus, ducimus id veniam earum, Et ullam placeat ut accusamus recusandae quidem molestias ipsa dolorum aut eligendi doloremque totam veritatis voluptatibus. Officia quae voluptates laudantium atque aliquam voluptatibus hic esse, necessitatibus beatae atque laudantium voluptas voluptate veritatis sequi vero, dolore asperiores at p = p.capitalize() explicabo amet assumenda eaque autem molestiae exercitationem fugiat quasi sequi? Facilis tenetur qui molestias iusto eum ab necessitatibus, voluptatibus eveniet obcaecati saepe porro repellat doloremque quis minus? Distinctio eos dolore corporis corrupti magni, dolor assumenda error recusandae rem ducimus facilis iste doloribus nisi eligendi. st.append(Paragraph(p, style=h2)) for j in range(3): p = li.paragraph() st.append(Paragraph(p, style=bt)) doc = TwoColumnDocTemplate(outPath, pagesize=PAGESIZE) doc.build(story)
  16. 16. 3rd Layer: RML • ”Report Markup Language“ • Platypus in XML + Black Box + ¥$€ • See also: z3c.rml (S. Richter et al. – free) • PageCatcher (more ¥$€) for PDF import • See also: one of my next announcements…
  17. 17. Paragraphs
  18. 18. Features • Subclass of the Flowable class • Core class in Platypus (paragraph.py) • No alternative (except para.py – R.I.P.) • Central feature: linebreaks • Knows style attributes
  19. 19. Global Style Attributes • fontName, fontSize, textColor, backColor • firstLineIndent, leftIndent, rightIndent • alignment, leading, (spaceBefore, spaceAfter) • bulletColor, bulletFontName, bulletFontSize, bulletIndent, bulletOffsetY • Sample: stylesheet = getSampleStyleSheet() bt = stylesheet['BodyText'] bt.leading = 16 bt.textColor = colors.blue
  20. 20. Local Style Attributes • XML tags in paragraph text: • font, br, b, i, u, strong, strike, a, link, img • superscript, subscript, greek • seq, seqDefault, seqReset • Sample: t = "Hello <font color='red'>red</font> world!" p = Paragraph(t, style=myStyle)
  21. 21. Lacking… • Inline images (new in SVN) • Hyphenation • Kerning • Code comprehensibility • Code extensibility ”Reporting Solutions“!? Efficiency!?
  22. 22. Paragraphs Reloaded
  23. 23. New Approach • New Flowable! • MinimalParagraph class • Easily extensible (shown in subclasses) • Linebreaks (and not much more)! • Critical methods: wrap, split, draw
  24. 24. Sample: XBox class XBox(Flowable): def __init__(self, width, height, text='A Box'): Flowable.__init__(self) self.width, self.height, self.text = width, height, text def draw(self): canv, w, h = self.canv, self.width, self.height canv.rect(0, 0, w, h) canv.line(0, 0, w, h) canv.line(0, h, w, 0) canv.setFont('Times-Roman', 12) canv.drawCentredString(0.5*w, 0.5*h, self.text) # inherited by Flowable: def wrap(self, availWidth, availHeight): return (self.width, self.height) def split(self, availWidth, availheight): return []
  25. 25. Key Idea: ”Events“ • Input text: "Hello world" • Parsed: [{"text":"Hello"}, {"text":"world"}] • Word widths: [{"text":"Hello", "width":10}, {text:"world", "width":11}] • Placement: [{"text":"Hello", "width":10, "pos":(10, 5)}, {"text":"world", "width":11, "pos":(23, 5)}] • Add attributes as needed
  26. 26. MinimalParagraph • Global attributes: fontName, fontSize, leading, firstLineIndent, leftIndent, rightIndent, textColor, (spaceBefore, spaceAfter) • No alignment (left only), … • Focus on linebreaks and RL compliance
  27. 27. Alice was beginning to get very tired of sitting well, and noticed that they were filled with by her sister on the bank, and of having cupboards and book-shelves; here and there nothing to do: once or twice she had peeped she saw maps and pictures hung upon pegs. into the book her sister was reading, but it She took down a jar from one of the shelves had no pictures or conversations in it, `and as she passed; it was labelled `ORANGE what is the use of a book,' thought Alice MARMALADE', but to her great `without pictures or conversation?' disappointment it was empty: she did not like to drop the jar for fear of killing somebody, so So she was considering in her own mind (as managed to put it into one of the cupboards well as she could, for the hot day made her as she fell past it. feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be `Well!' thought Alice to herself, `after such a worth the trouble of getting up and picking fall as this, I shall think nothing of tumbling the daisies, when suddenly a White Rabbit down stairs! How brave they'll all think me at with pink eyes ran close by her. home! Why, I wouldn't say anything about it, even if I fell off the top of the house!' (Which There was nothing so VERY remarkable in was very likely true.) that; nor did Alice think it so VERY much out of the way to hear the Rabbit say to itself, Down, down, down. Would the fall NEVER `Oh dear! Oh dear! I shall be late!' (when she come to an end! `I wonder how many miles thought it over afterwards, it occurred to her I've fallen by this time?' she said aloud. `I that she ought to have wondered at this, but must be getting somewhere near the centre at the time it all seemed quite natural); but of the earth. Let me see: that would be four when the Rabbit actually TOOK A WATCH thousand miles down, I think--' (for, you see, OUT OF ITS WAISTCOAT- POCKET, and Alice had learnt several things of this sort in MinimalParagraph looked at it, and then hurried on, Alice her lessons in the schoolroom, and though started to her feet, for it flashed across her this was not a VERY good opportunity for mind that she had never before seen a rabbit showing off her knowledge, as there was no with either a waistcoat-pocket, or a watch to one to listen to her, still it was good practice take out of it, and burning with curiosity, she to say it over) `--yes, that's about the right ran across the field after it, and fortunately distance--but then I wonder what Latitude or was just in time to see it pop down a large Longitude I've got to?' (Alice had no idea
  28. 28. ColouredParagraph #!/bin/env/python def draw(self): # -*- coding: utf-8 -*- "Render words in paragraph on randomly coloured background." "An example for a coloured paragraph subclass." if not self.words: return import random canvas = self.canv style = self.style from reportlab.lib import colors canvas.saveState() from minimalparagraph import MinimalParagraph canvas.setFont(style.fontName, style.fontSize) for word in self.words: RL_COLORS = [v for (k, v) in if "meta" in word or not "pos" in word: colors.__dict__.items() continue if isinstance(v, colors.Color)] text, (x, y) = word["text"], word["pos"] col = random.choice(RL_COLORS) canvas.setStrokeColor(col) class ColouredParagraph(MinimalParagraph): canvas.setFillColor(col) "A colourful tiny subclass canvas.rect(x, y - self.dy, of MinimalParagraph." word["width"], style.fontSize, fill=True, stroke=True) canvas.setFillColor(style.textColor) canvas.drawString(x, y - self.dy, text) canvas.restoreState()
  29. 29. !"#$% &'( )# *+(, -+( .+(,/ 0 $#")-123 4") 1+(L5#6-E ,5- !"-6( )#$" +") 6##!-) +6#"8 (5- 5-1- 467*- .-8+" (# 8-( 1+(5-1 ,6--9:/ +") 9+,,+8- 7"(# (5- 6#C-67-,( 8+1)-" :#' -C-1 $-"( #" ,+:7"8 (# 5-1,-6;/ 7" + )1-+<: ,#1( #; ,+$% N#$ ,5- 6#"8-) (# 8-( #'( #; (5+( )+1! $+:/ =># *+(, -+( .+(,2 ># *+(, -+( .+(,23 +") 5+66/ +") $+")-1 +.#'( +<#"8 (5#,- .-), #; ,#<-(7<-,/ =># .+(, -+( *+(,23 ;#1/ :#' ,--/ +, .1785( ;6#$-1, +") (5#,- *##6 ;#'"(+7",/ .'( ,5- *#'6)"3( +",$-1 -7(5-1 ?'-,(7#"/ 7( )7)"3( ,5- *#'6) "#( -C-" 8-( 5-1 5-+) (51#'85 (5- <'*5 <+((-1 $57*5 $+: ,5- 9'( 7(% @5- ;-6( )##1$+:G =+") -C-" 7; <: 5-+) $#'6) 8# (5+( ,5- $+, )#A7"8 #;;/ +") 5+) B',( .-8'" (# (51#'85/3 (5#'85( 9##1 467*-/ =7( $#'6) .- #; )1-+< (5+( ,5- $+, $+6!7"8 5+") 7" 5+") $7(5 C-1: 67((6- ',- $7(5#'( <: ,5#'6)-1,% K5/ 5#$ 0 >7"+5/ +") ,+:7"8 (# 5-1 C-1: -+1"-,(6:/ =D#$/ $7,5 0 *#'6) ,5'( '9 67!- + (-6-,*#9-F 0 (57"! 0 >7"+5/ (-66 <- (5- (1'(5E )7) :#' -C-1 -+( + *#'6)/ 7; 0 #"6: !"#$ 5#$ (# .-87"%3 O#1/ :#' .+(23 $5-" ,'))-"6:/ (5'<9F (5'<9F )#$" ,--/ ,# <+": #'(L#;L(5-L$+: (57"8, 5+) ,5- *+<- '9#" + 5-+9 #; ,(7*!, +") )1: 6-+C-,/ 5+99-"-) 6+(-6:/ (5+( 467*- 5+) .-8'" (# (57"! +") (5- ;+66 $+, #C-1% (5+( C-1: ;-$ (57"8, 7")--) $-1- 1-+66: 7<9#,,7.6-% 467*- $+, "#( + .7( 5'1(/ +") ,5- B'<9-) '9 #" (# 5-1 ;--( 7" + <#<-"(E ,5- 6##!-) '9/ .'( 7( J5-1- ,--<-) (# .- "# ',- 7" $+7(7"8 .: (5- $+, +66 )+1! #C-15-+)G .-;#1- 5-1 $+, +"#(5-1 67((6- )##1/ ,# ,5- $-"( .+*! (# (5- (+.6-/ 5+6; 6#"8 9+,,+8-/ +") (5- H57(- I+..7( $+, ,(766 7" 5#97"8 ,5- <785( ;7") +"#(5-1 !-: #" 7(/ #1 +( ,785(/ 5'11:7"8 )#$" 7(% J5-1- $+, "#( + +": 1+(- + .##! #; 1'6-, ;#1 ,5'((7"8 9-#96- '9 <#<-"( (# .- 6#,(E +$+: $-"( 467*- 67!- (5- 67!- (-6-,*#9-,E (57, (7<- ,5- ;#'") + 67((6- $7")/ +") $+, B',( 7" (7<- (# 5-+1 7( ,+:/ +, 7( .#((6- #" 7(/ P=$57*5 *-1(+7"6: $+, "#( 5-1- ('1"-) + *#1"-1/ =K5 <: -+1, +") $57,!-1,/ .-;#1-/3 ,+7) 467*-/Q +") 1#'") (5- "-*! #; (5- 5#$ 6+(- 7(3, 8-((7"8F3 @5- $+, *6#,- .-57") 7( .#((6- $+, + 9+9-1 6+.-6/ $7(5 (5- $#1), $5-" ,5- ('1"-) (5- *#1"-1/ .'( (5- I+..7( =>I0DR ST3 .-+'(7;'66: 917"(-) #" 7( 7" 6+18- ColouredParagraph $+, "# 6#"8-1 (# .- ,--"E ,5- ;#'") 5-1,-6; 7" 6-((-1,% + 6#"8/ 6#$ 5+66/ $57*5 $+, 67( '9 .: + 1#$ #; 6+<9, 5+"87"8 ;1#< (5- 1##;% 0( $+, +66 C-1: $-66 (# ,+: =>17"! <-/3 .'( (5- $7,- 67((6- 467*- $+, "#( 8#7"8 (# )# JN4J 7" + J5-1- $-1- )##1, +66 1#'") (5- 5+66/ .'( (5-: 5'11:% =D#/ 0366 6##! ;71,(/3 ,5- ,+7)/ =+") ,-- $-1- +66 6#*!-)G +") $5-" 467*- 5+) .--" +66 $5-(5-1 7(3, <+1!-) U9#7,#"U #1 "#(3G ;#1 ,5- (5- $+: )#$" #"- ,7)- +") '9 (5- #(5-1/ 5+) 1-+) ,-C-1+6 "7*- 67((6- 57,(#17-, +.#'(
  30. 30. !"#$% &'( )# *+(, -+( .+(,/ 0 $#")-123 4") 1+(L5#6-E ,5- !"-6( )#$" +") 6##!-) +6#"8 (5- 5-1- 467*- .-8+" (# 8-( 1+(5-1 ,6--9:/ +") 9+,,+8- 7"(# (5- 6#C-67-,( 8+1)-" :#' -C-1 $-"( #" ,+:7"8 (# 5-1,-6;/ 7" + )1-+<: ,#1( #; ,+$% N#$ ,5- 6#"8-) (# 8-( #'( #; (5+( )+1! $+:/ =># *+(, -+( .+(,2 ># *+(, -+( .+(,23 +") 5+66/ +") $+")-1 +.#'( +<#"8 (5#,- .-), #; ,#<-(7<-,/ =># .+(, -+( *+(,23 ;#1/ :#' ,--/ +, .1785( ;6#$-1, +") (5#,- *##6 ;#'"(+7",/ .'( ,5- *#'6)"3( +",$-1 -7(5-1 ?'-,(7#"/ 7( )7)"3( ,5- *#'6) "#( -C-" 8-( 5-1 5-+) (51#'85 (5- <'*5 <+((-1 $57*5 $+: ,5- 9'( 7(% @5- ;-6( )##1$+:G =+") -C-" 7; <: 5-+) $#'6) 8# (5+( ,5- $+, )#A7"8 #;;/ +") 5+) B',( .-8'" (# (51#'85/3 (5#'85( 9##1 467*-/ =7( $#'6) .- #; )1-+< (5+( ,5- $+, $+6!7"8 5+") 7" 5+") $7(5 C-1: 67((6- ',- $7(5#'( <: ,5#'6)-1,% K5/ 5#$ 0 >7"+5/ +") ,+:7"8 (# 5-1 C-1: -+1"-,(6:/ =D#$/ $7,5 0 *#'6) ,5'( '9 67!- + (-6-,*#9-F 0 (57"! 0 >7"+5/ (-66 <- (5- (1'(5E )7) :#' -C-1 -+( + *#'6)/ 7; 0 #"6: !"#$ 5#$ (# .-87"%3 O#1/ :#' .+(23 $5-" ,'))-"6:/ (5'<9F (5'<9F )#$" ,--/ ,# <+": #'(L#;L(5-L$+: (57"8, 5+) ,5- *+<- '9#" + 5-+9 #; ,(7*!, +") )1: 6-+C-,/ 5+99-"-) 6+(-6:/ (5+( 467*- 5+) .-8'" (# (57"! +") (5- ;+66 $+, #C-1% (5+( C-1: ;-$ (57"8, 7")--) $-1- 1-+66: 7<9#,,7.6-% 467*- $+, "#( + .7( 5'1(/ +") ,5- B'<9-) '9 #" (# 5-1 ;--( 7" + <#<-"(E ,5- 6##!-) '9/ .'( 7( J5-1- ,--<-) (# .- "# ',- 7" $+7(7"8 .: (5- $+, +66 )+1! #C-15-+)G .-;#1- 5-1 $+, +"#(5-1 67((6- )##1/ ,# ,5- $-"( .+*! (# (5- (+.6-/ 5+6; 6#"8 9+,,+8-/ +") (5- H57(- I+..7( $+, ,(766 7" 5#97"8 ,5- <785( ;7") +"#(5-1 !-: #" 7(/ #1 +( ,785(/ 5'11:7"8 )#$" 7(% J5-1- $+, "#( + +": 1+(- + .##! #; 1'6-, ;#1 ,5'((7"8 9-#96- '9 <#<-"( (# .- 6#,(E +$+: $-"( 467*- 67!- (5- 67!- (-6-,*#9-,E (57, (7<- ,5- ;#'") + 67((6- $7")/ +") $+, B',( 7" (7<- (# 5-+1 7( ,+:/ +, 7( .#((6- #" 7(/ P=$57*5 *-1(+7"6: $+, "#( 5-1- ('1"-) + *#1"-1/ =K5 <: -+1, +") $57,!-1,/ .-;#1-/3 ,+7) 467*-/Q +") 1#'") (5- "-*! #; (5- 5#$ 6+(- 7(3, 8-((7"8F3 @5- $+, *6#,- .-57") 7( .#((6- $+, + 9+9-1 6+.-6/ $7(5 (5- $#1), $5-" ,5- ('1"-) (5- *#1"-1/ .'( (5- I+..7( =>I0DR ST3 .-+'(7;'66: 917"(-) #" 7( 7" 6+18- HighlightedParagraph $+, "# 6#"8-1 (# .- ,--"E ,5- ;#'") 5-1,-6; 7" 6-((-1,% + 6#"8/ 6#$ 5+66/ $57*5 $+, 67( '9 .: + 1#$ #; 6+<9, 5+"87"8 ;1#< (5- 1##;% 0( $+, +66 C-1: $-66 (# ,+: =>17"! <-/3 .'( (5- $7,- 67((6- 467*- $+, "#( 8#7"8 (# )# JN4J 7" + J5-1- $-1- )##1, +66 1#'") (5- 5+66/ .'( (5-: 5'11:% =D#/ 0366 6##! ;71,(/3 ,5- ,+7)/ =+") ,-- $-1- +66 6#*!-)G +") $5-" 467*- 5+) .--" +66 $5-(5-1 7(3, <+1!-) U9#7,#"U #1 "#(3G ;#1 ,5- (5- $+: )#$" #"- ,7)- +") '9 (5- #(5-1/ 5+) 1-+) ,-C-1+6 "7*- 67((6- 57,(#17-, +.#'(
  31. 31. R1#*6" .#00%*;-%%7< >"# O%'0# $):# ) ")+ 0%/#"%, 2)..#* 4*&% &"# 0#)5 =)*+ 4* &")& 0'++#* .#)( %'& %2 &"# ,)&#15 )*+ 0##/#+ &% 6)0# E 6)* $% -)67 -3 1)4.,)35B 0"# 0)4+ &% K'4:#1 ).. %:#1 ,4&" 214$"&< =N"5 E -#$ 3%'1 "#10#.2< G@.46# ")+ -##* &% &"# 0#)04+# %*6# 4* ()1+%*AB 614#+ @.46# ")0&4.35 )21)4+ &")& 0"# ")+ "#1 .42#5 )*+ ")+ 6%/# &% &"# $#*#1). 6%*6.'; "'1& &"# (%%1 )*4/).B0 2##.4*$0< =E K'4&# 2%1$%& 04%*5 &")& ,"#1#:#1 3%' $% &% %* &"# H*$.40" 3%' +4+*B& .47# 6)&0<B 6%)0& 3%' 24*+ ) *'/-#1 %2 -)&"4*$ /)6"4*#0 4* &"# 0#)5 0%/# 6"4.+1#* +4$$4*$ 4* &"# 0)*+ =T%& .47# 6)&0AB 614#+ &"# O%'0#5 4* ) 0"14..5 ()0; ,4&" ,%%+#* 0()+#05 &"#* ) 1%, %2 .%+$4*$ 04%*)&# :%46#< =?%'.+ UNV .47# 6)&0 42 3%' ,#1# "%'0#05 )*+ -#"4*+ &"#/ ) 1)4.,)3 0&)&4%*<I /#MB F%,#:#15 0"# 0%%* /)+# %'& &")& 0"# ,)0 4* &"# (%%. %2 &#)10 ,"46" 0"# ")+ ,#(& ,"#* 0"# ,)0 *4*# 2##& "4$"< =E ,40" E ")+*B& 614#+ 0% /'6"AB 0)4+ @.46#5 )0 0"# 0,)/ )-%'&5 &134*$ &% 24*+ "#1 ,)3 %'&< =E 0").. -# ('*40"#+ 2%1 4& *%,5 E 0'((%0#5 -3 -#4*$ +1%,*#+ 4* /3 %,* &#)10A >")& ?EJJ -# ) K'##1 &"4*$5 &% -# 0'1#A F%,#:#15 #:#13&"4*$ 40 K'##1 &%;+)3<B L'0& &"#* 0"# "#)1+ 0%/#&"4*$ 0(.)0"4*$ )-%'& 4* &"# (%%. ) .4&&.# ,)3 %225 )*+ 0"# 0,)/ *#)1#1 &% /)7# %'& ,")& 4& ,)08 )& 2410& 0"# &"%'$"& 4& /'0& -# ) ,).1'0 %1 "4((%(%&; )/'05 -'& &"#* 0"# 1#/#/-#1#+ "%, 0/).. 0"# ,)0 *%,5 )*+ 0"# 0%%* /)+# %'& &")& 4& ,)0 %*.3 ) /%'0# &")& ")+ 0.4((#+ 4* .47# "#10#.2< HyphenatedParagraph
  32. 32. R1#*6" .#00%*;-%%7< >"# O%'0# $):# ) ")+ 0%/#"%, 2)..#* 4*&% &"# 0#)5 =)*+ 4* &")& 0'++#* .#)( %'& %2 &"# ,)&#15 )*+ 0##/#+ &% 6)0# E 6)* $% -)67 -3 1)4.,)35B 0"# 0)4+ &% K'4:#1 ).. %:#1 ,4&" 214$"&< =N"5 E -#$ 3%'1 "#10#.2< G@.46# ")+ -##* &% &"# 0#)04+# %*6# 4* ()1+%*AB 614#+ @.46# ")0&4.35 )21)4+ &")& 0"# ")+ "#1 .42#5 )*+ ")+ 6%/# &% &"# $#*#1). 6%*6.'; "'1& &"# (%%1 )*4/).B0 2##.4*$0< =E K'4&# 2%1$%& 04%*5 &")& ,"#1#:#1 3%' $% &% %* &"# H*$.40" 3%' +4+*B& .47# 6)&0<B 6%)0& 3%' 24*+ ) *'/-#1 %2 -)&"4*$ /)6"4*#0 4* &"# 0#)5 0%/# 6"4.+1#* +4$$4*$ 4* &"# 0)*+ =T%& .47# 6)&0AB 614#+ &"# O%'0#5 4* ) 0"14..5 ()0; ,4&" ,%%+#* 0()+#05 &"#* ) 1%, %2 .%+$4*$ 04%*)&# :%46#< =?%'.+ UNV .47# 6)&0 42 3%' ,#1# "%'0#05 )*+ -#"4*+ &"#/ ) 1)4.,)3 0&)&4%*<I /#MB F%,#:#15 0"# 0%%* /)+# %'& &")& 0"# ,)0 4* &"# (%%. %2 &#)10 ,"46" 0"# ")+ ,#(& ,"#* 0"# ,)0 *4*# 2##& "4$"< =E ,40" E ")+*B& 614#+ 0% /'6"AB 0)4+ @.46#5 )0 0"# 0,)/ )-%'&5 &134*$ &% 24*+ "#1 ,)3 %'&< =E 0").. -# ('*40"#+ 2%1 4& *%,5 E 0'((%0#5 -3 -#4*$ +1%,*#+ 4* /3 %,* &#)10A >")& ?EJJ -# ) K'##1 &"4*$5 &% -# 0'1#A F%,#:#15 #:#13&"4*$ 40 K'##1 &%;+)3<B L'0& &"#* 0"# "#)1+ 0%/#&"4*$ 0(.)0"4*$ )-%'& 4* &"# (%%. ) .4&&.# ,)3 %225 )*+ 0"# 0,)/ *#)1#1 &% /)7# %'& ,")& 4& ,)08 )& 2410& 0"# &"%'$"& 4& /'0& -# ) ,).1'0 %1 "4((%(%&; )/'05 -'& &"#* 0"# 1#/#/-#1#+ "%, 0/).. 0"# ,)0 *%,5 )*+ 0"# 0%%* /)+# %'& &")& 4& ,)0 %*.3 ) /%'0# &")& ")+ 0.4((#+ 4* .47# "#10#.2< HyphenlightedParagraph
  33. 33. IconizedParagraph • Input text: "Hello file://smiley.jpeg world" • Events: [{"text":"Hello", …}, {"text":"file:// smiley.jpg", "type":"Image", "width":16, "height":16}, {"text":"world", …}] • draw method picks and renders image events…
  34. 34. *"56 N35 *$, /3';,( #3 ;,# 34# 3= #$"# ("-1 $"//& "'( 5"'(,- "%34# "23'; #$3*, %,(* 3= %-0;$# =/35,-* "'( #$3*, !33/ =34'#"0'*& %4# *$, !34/( '3# ,+,' ;,# $,- $,"( #$-34;$ #$, (33-5".G >"'( ,+,' 0= 2. $,"( 534/( ;3 #$-34;$&) #$34;$# <33- :/0!,& >0# 534/( %, 3= +,-. /0##/, 4*, 50#$34# 2. *$34/(,-*6 K$& $35 8 50*$ 8 !34/( *$4# 4< /01, " #,/,*!3<,F 8 #$0'1 8 !34/(& 0= 8 3'/. 1'35 $35 #3 %,;0'6) O3-& .34 *,,& *3 2"'. 34#L3=L#$,L5". #$0';* $"( $"<<,',( /"#,/.& #$"# :/0!, $"( %,;4' #3 #$0'1 #$"# +,-. =,5 #$0';* 0'(,,( 5,-, -,"//. IconizedParagraph 02<3**0%/,6
  35. 35. CHAPTER II The Pool of Tears `Curiouser and curiouser!' cried Alice (she was so much surprised, that for the moment she quite forgot how to speak good English); `now I'm opening out like the largest telescope that ever was! Good-bye, feet!' (for when she looked down at her feet, they seemed to be almost out of sight, they were getting so far off). `Oh, my poor GraphicsParagraph little feet, I wonder who will put on your shoes and stockings for you now, dears? I'm sure _I_ shan't be able! I shall be a great deal too far off to
  36. 36. ReportLab Paragraph CountingParagraph If you need something that 0 If you need something that isn't on the feature list, 1 isn't on the feature list, please check the mailing-list 2 please check the mailing-list archives. Lots of features 3 archives. Lots of features are yet to be documented, 4 are yet to be documented, but most of the functionality 5 but most of the functionality has been commented in the 6 has been commented in the mailing-list. If you have a 7 mailing-list. If you have a problem that has not been 0 problem that has not been CountingParagraph dealt with yet... 1 dealt with yet...
  37. 37. Summary
  38. 38. Code Length rlpara dinu$ pycount2.py *.py lines code doc comment blank file 2380 1831 66 338 145 para-svn.py 1432 1127 131 59 115 paragraph-svn.py 1299 998 129 58 114 paragraph-2.1.py alterparagraphs dinu$ pycount2.py *paragraph.py lines code doc comment blank file 48 30 0 2 16 colouredparagraph.py 101 64 0 7 30 graphicsparagraph.py 75 53 0 3 19 highlightedparagraph.py 204 132 0 33 39 hyphenatedparagraph.py 264 182 0 32 50 hyphenlightedparagraph.py 186 128 0 11 47 iconizedparagraph.py 202 111 25 13 53 minimalparagraph.py 271 163 26 18 64 simpleparagraph.py 31 15 2 4 10 ttfparagraph.py
  39. 39. $ run_performance_test.py --mnp 500 ../input/alice30.txt input file: ../input/alice30.txt Runtime #words: 28200 #lines: 3854 #paragraphs: 500 Paragraph, time needed: 0.564515 (s) file size: 91901 (Byte) MinimalParagraph, time needed: 1.143239 (2.03 x) file size: 210104 (2.29 x) SimpleParagraph, time needed: 1.872415 (3.32 x) file size: 262991 (2.86 x) TTFParagraph, time needed: 1.635452 (2.90 x) file size: 244040 (2.66 x) ColouredParagraph, time needed: 2.368929 (4.20 x) file size: 544549 (5.93 x) HyphenatedParagraph, time needed: 4.455254 (4.86 x) file size: 363638 (2.51 x) HighlightedParagraph, time needed: 2.958230 (3.23 x) file size: 403546 (2.79 x) HyphenlightedParagraph, time needed: 4.993915 (5.45 x) file size: 413874 (2.86 x) IconizedParagraph, time needed: 1.979934 (3.51 x) file size: 270026 (2.94 x) GraphicsParagraph, time needed: 1.799298 (3.19 x) file size: 269538 (2.93 x)
  40. 40. Current State • Family of paragraph classes • Usually domain specific (e.g. kerning) • Small code size • Ca. 2–3 x slower than RL (pure text) • Easier extensible than RL
  41. 41. Future • Further Paragraph attributes • KerningParagraph • XMLParagraph (tags) • General callback mechanism • RTLParagraph? (Right to Left)
  42. 42. Links • http://www.dinu-gherman.net/tmp/ alterparagraphs-0.3.2.tar.gz • http://www.reportlab.com • http://pypi.python.org/pypi/z3c.rml (z3c.rml) • http://deco-cow.sourceforge.net (wordaxe)
  43. 43. Questions? ” three questions, and that is enough,‘ ’I have answered Said his father; ’don't give yourself airs! Do you think I can listen all day to such stuff? Be off, or I'll kick you down stairs!‘ “ Alice‘s Adventures in Wonderland, Lewis Carroll
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×