reportlab-3.5.34/ 0000775 0001750 0001750 00000000000 13607302651 014377 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/LICENSE.txt 0000664 0001750 0001750 00000003253 13544671343 016234 0 ustar rptlab rptlab 0000000 0000000 #####################################################################################
#
# Copyright (c) 2000-2018, ReportLab Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the company nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE OFFICERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#####################################################################################
reportlab-3.5.34/INSTALL.txt 0000664 0001750 0001750 00000000065 13544671343 016256 0 ustar rptlab rptlab 0000000 0000000 Please see README.txt for installation instructions.
reportlab-3.5.34/demos/ 0000775 0001750 0001750 00000000000 13607302651 015506 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/rlzope/ 0000775 0001750 0001750 00000000000 13607302651 017021 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/rlzope/readme.txt 0000664 0001750 0001750 00000004752 13544671343 021036 0 ustar rptlab rptlab 0000000 0000000 # rlzope : an external Zope method to show people how to use
# the ReportLab toolkit from within Zope.
#
# this method searches an image named 'logo' in the
# ZODB then prints it at the top of a simple PDF
# document made with ReportLab
#
# the resulting PDF document is returned to the
# user's web browser and, if possible, it is
# simultaneously saved into the ZODB.
#
# this method illustrates how to use both the platypus
# and canvas frameworks.
#
# License : The ReportLab Toolkit's license (similar to BSD)
#
# Author : Jerome Alet - alet@librelogiciel.com
#
Installation instructions :
===========================
0 - If not installed then install Zope.
1 - Install reportlab in the Zope/lib/python/Shared directory by unpacking
the tarball and putting a reportlabs.pth file in site-packages for the Zope
used with Python. The path value in the reportlabs.pth file must be
relative. For a typical Zope installation, the path is "../../python/Shared".
Remember to restart Zope so the new path is instantiated.
2 - Install PIL in the Zope/lib/python/Shared directory. You need to
ensure that the _imaging.so or .pyd is also installed appropriately.
It should be compatible with the python running the zope site.
3 - Copy rlzope.py to your Zope installation's "Extensions"
subdirectory, e.g. /var/lib/zope/Extensions/ under Debian GNU/Linux.
4 - From within Zope's management interface, add an External Method with
these parameters :
Id : rlzope
Title : rlzope
Module Name : rlzope
Function Name : rlzope
5 - From within Zope's management interface, add an image called "logo"
in the same Folder than rlzope, or somewhere above in the Folder
hierarchy. For example you can use ReportLab's logo which you
can find in reportlab/docs/images/replogo.gif
6 - Point your web browser to rlzope, e.g. on my laptop under
Debian GNU/Linux :
http://localhost:9673/rlzope
This will send a simple PDF document named 'dummy.pdf' to your
web browser, and if possible save it as a File object in the
Zope Object DataBase, with this name. Note, however, that if
an object with the same name already exists then it won't
be replaced for security reasons.
You can optionally add a parameter called 'name' with
a filename as the value, to specify another filename,
e.g. :
logo
http://localhost:9673/rlzope?name=sample.pdf
7 - Adapt it to your own needs.
8 - Enjoy !
Send comments or bug reports at : alet@librelogiciel.com
reportlab-3.5.34/demos/rlzope/rlzope.py 0000664 0001750 0001750 00000015226 13544671343 020723 0 ustar rptlab rptlab 0000000 0000000 #
# Using the ReportLab toolkit from within Zope
#
# WARNING : The MyPDFDoc class deals with ReportLab's platypus framework,
# while the MyPageTemplate class directly deals with ReportLab's
# canvas, this way you know how to do with both...
#
# License : the ReportLab Toolkit's one
# see : http://www.reportlab.com
#
# Author : Jerome Alet - alet@librelogiciel.com
#
#
try :
from Shared.reportlab.platypus.paragraph import Paragraph
from Shared.reportlab.platypus.doctemplate import *
from Shared.reportlab.lib.units import inch
from Shared.reportlab.lib import styles
from Shared.reportlab.lib.utils import ImageReader, getBytesIO
except ImportError :
from reportlab.platypus.paragraph import Paragraph
from reportlab.platypus.doctemplate import *
from reportlab.lib.units import inch
from reportlab.lib import styles
from reportlab.lib.utils import ImageReader, getBytesIO
class MyPDFDoc :
class MyPageTemplate(PageTemplate) :
"""Our own page template."""
def __init__(self, parent) :
"""Initialise our page template."""
#
# we must save a pointer to our parent somewhere
self.parent = parent
# Our doc is made of a single frame
content = Frame(0.75 * inch, 0.5 * inch, parent.document.pagesize[0] - 1.25 * inch, parent.document.pagesize[1] - (1.5 * inch))
PageTemplate.__init__(self, "MyTemplate", [content])
# get all the images we need now, in case we've got
# several pages this will save some CPU
self.logo = self.getImageFromZODB("logo")
def getImageFromZODB(self, name) :
"""Retrieves an Image from the ZODB, converts it to PIL,
and makes it 0.75 inch high.
"""
try :
# try to get it from ZODB
logo = getattr(self.parent.context, name)
except AttributeError :
# not found !
return None
# Convert it to PIL
image = ImageReader(getBytesIO(str(logo.data)))
(width, height) = image.getSize()
# scale it to be 0.75 inch high
multi = ((height + 0.0) / (0.75 * inch))
width = int(width / multi)
height = int(height / multi)
return ((width, height), image)
def beforeDrawPage(self, canvas, doc) :
"""Draws a logo and an contribution message on each page."""
canvas.saveState()
if self.logo is not None :
# draws the logo if it exists
((width, height), image) = self.logo
canvas.drawImage(image, inch, doc.pagesize[1] - inch, width, height)
canvas.setFont('Times-Roman', 10)
canvas.drawCentredString(inch + (doc.pagesize[0] - (1.5 * inch)) / 2, 0.25 * inch, "Contributed by Jerome Alet - alet@librelogiciel.com")
canvas.restoreState()
def __init__(self, context, filename) :
# save some datas
self.context = context
self.built = 0
self.objects = []
# we will build an in-memory document
# instead of creating an on-disk file.
self.report = getBytesIO()
# initialise a PDF document using ReportLab's platypus
self.document = BaseDocTemplate(self.report)
# add our page template
# (we could add more than one, but I prefer to keep it simple)
self.document.addPageTemplates(self.MyPageTemplate(self))
# get the default style sheets
self.StyleSheet = styles.getSampleStyleSheet()
# then build a simple doc with ReportLab's platypus
sometext = "A sample script to show how to use ReportLab from within Zope"
url = self.escapexml(context.absolute_url())
urlfilename = self.escapexml(context.absolute_url() + '/%s' % filename)
self.append(Paragraph("Using ReportLab from within Zope", self.StyleSheet["Heading3"]))
self.append(Spacer(0, 10))
self.append(Paragraph("You launched it from : %s" % url, self.StyleSheet['Normal']))
self.append(Spacer(0, 40))
self.append(Paragraph("If possible, this report will be automatically saved as : %s" % urlfilename, self.StyleSheet['Normal']))
# generation du document PDF
self.document.build(self.objects)
self.built = 1
def __str__(self) :
"""Returns the PDF document as a string of text, or None if it's not ready yet."""
if self.built :
return self.report.getvalue()
else :
return None
def append(self, object) :
"""Appends an object to our platypus "story" (using ReportLab's terminology)."""
self.objects.append(object)
def escapexml(self, s) :
"""Escape some xml entities."""
s = s.strip()
s = s.replace("&", "&")
s = s.replace("<", "<")
return s.replace(">", ">")
def rlzope(self) :
"""A sample external method to show people how to use ReportLab from within Zope."""
try:
#
# which file/object name to use ?
# append ?name=xxxxx to rlzope's url to
# choose another name
filename = self.REQUEST.get("name", "dummy.pdf")
if filename[-4:] != '.pdf' :
filename = filename + '.pdf'
# tell the browser we send some PDF document
# with the requested filename
# get the document's content itself as a string of text
content = str(MyPDFDoc(self, filename))
# we will return it to the browser, but before that we also want to
# save it into the ZODB into the current folder
try :
self.manage_addFile(id = filename, file = content, title = "A sample PDF document produced with ReportLab", precondition = '', content_type = "application/pdf")
except :
# it seems an object with this name already exists in the ZODB:
# it's more secure to not replace it, since we could possibly
# destroy an important PDF document of this name.
pass
self.REQUEST.RESPONSE.setHeader('Content-Type', 'application/pdf')
self.REQUEST.RESPONSE.setHeader('Content-Disposition', 'attachment; filename=%s' % filename)
except:
import traceback, sys, cgi
content = sys.stdout = sys.stderr = getBytesIO()
self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/html')
traceback.print_exc()
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
content = '
%s
' % cgi.escape(content.getvalue())
# then we also return the PDF content to the browser
return content
reportlab-3.5.34/demos/gadflypaper/ 0000775 0001750 0001750 00000000000 13607302651 020004 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/gadflypaper/00readme.txt 0000664 0001750 0001750 00000000151 13544671343 022146 0 ustar rptlab rptlab 0000000 0000000 This is Aaron Watters' first script;
it renders his paper for IPC8 into
PDF. A fascinating read, as well. reportlab-3.5.34/demos/gadflypaper/gfe.py 0000664 0001750 0001750 00000077333 13544671343 021143 0 ustar rptlab rptlab 0000000 0000000 #Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__doc__=''
__version__='3.3.0'
#REPORTLAB_TEST_SCRIPT
import sys
from reportlab.platypus import *
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
PAGE_HEIGHT=defaultPageSize[1]
styles = getSampleStyleSheet()
Title = "Integrating Diverse Data Sources with Gadfly 2"
Author = "Aaron Watters"
URL = "http://www.chordate.com/"
email = "arw@ifu.net"
Abstract = """This paper describes the primative methods underlying the implementation
of SQL query evaluation in Gadfly 2, a database management system implemented
in Python [Van Rossum]. The major design goals behind
the architecture described here are to simplify the implementation
and to permit flexible and efficient extensions to the gadfly
engine. Using this architecture and its interfaces programmers
can add functionality to the engine such as alternative disk based
indexed table implementations, dynamic interfaces to remote data
bases or or other data sources, and user defined computations."""
from reportlab.lib.units import inch
pageinfo = "%s / %s / %s" % (Author, email, Title)
def myFirstPage(canvas, doc):
canvas.saveState()
#canvas.setStrokeColorRGB(1,0,0)
#canvas.setLineWidth(5)
#canvas.line(66,72,66,PAGE_HEIGHT-72)
canvas.setFont('Times-Bold',16)
canvas.drawString(108, PAGE_HEIGHT-108, Title)
canvas.setFont('Times-Roman',9)
canvas.drawString(inch, 0.75 * inch, "First Page / %s" % pageinfo)
canvas.restoreState()
def myLaterPages(canvas, doc):
#canvas.drawImage("snkanim.gif", 36, 36)
canvas.saveState()
#canvas.setStrokeColorRGB(1,0,0)
#canvas.setLineWidth(5)
#canvas.line(66,72,66,PAGE_HEIGHT-72)
canvas.setFont('Times-Roman',9)
canvas.drawString(inch, 0.75 * inch, "Page %d %s" % (doc.page, pageinfo))
canvas.restoreState()
def go():
Elements.insert(0,Spacer(0,inch))
doc = SimpleDocTemplate('gfe.pdf')
doc.build(Elements,onFirstPage=myFirstPage, onLaterPages=myLaterPages)
Elements = []
HeaderStyle = styles["Heading1"] # XXXX
def header(txt, style=HeaderStyle, klass=Paragraph, sep=0.3):
s = Spacer(0.2*inch, sep*inch)
Elements.append(s)
para = klass(txt, style)
Elements.append(para)
ParaStyle = styles["Normal"]
def p(txt):
return header(txt, style=ParaStyle, sep=0.1)
#pre = p # XXX
PreStyle = styles["Code"]
def pre(txt):
s = Spacer(0.1*inch, 0.1*inch)
Elements.append(s)
p = Preformatted(txt, PreStyle)
Elements.append(p)
#header(Title, sep=0.1. style=ParaStyle)
header(Author, sep=0.1, style=ParaStyle)
header(URL, sep=0.1, style=ParaStyle)
header(email, sep=0.1, style=ParaStyle)
header("ABSTRACT")
p(Abstract)
header("Backgrounder")
p("""\
The term "database" usually refers to a persistent
collection of data. Data is persistent if it continues
to exist whether or not it is associated with a running
process on the computer, or even if the computer is
shut down and restarted at some future time. Database
management systems provide support for constructing databases,
maintaining databases, and extracting information from databases.""")
p("""\
Relational databases manipulate and store persistent
table structures called relations, such as the following
three tables""")
pre("""\
-- drinkers who frequent bars (this is a comment)
select * from frequents
DRINKER | PERWEEK | BAR
============================
adam | 1 | lolas
woody | 5 | cheers
sam | 5 | cheers
norm | 3 | cheers
wilt | 2 | joes
norm | 1 | joes
lola | 6 | lolas
norm | 2 | lolas
woody | 1 | lolas
pierre | 0 | frankies
)
""")
pre("""\
-- drinkers who like beers
select * from likes
DRINKER | PERDAY | BEER
===============================
adam | 2 | bud
wilt | 1 | rollingrock
sam | 2 | bud
norm | 3 | rollingrock
norm | 2 | bud
nan | 1 | sierranevada
woody | 2 | pabst
lola | 5 | mickies
""")
pre("""\
-- beers served from bars
select * from serves
BAR | QUANTITY | BEER
=================================
cheers | 500 | bud
cheers | 255 | samadams
joes | 217 | bud
joes | 13 | samadams
joes | 2222 | mickies
lolas | 1515 | mickies
lolas | 333 | pabst
winkos | 432 | rollingrock
frankies | 5 | snafu
""")
p("""
The relational model for database structures makes
the simplifying assumption that all data in a database
can be represented in simple table structures
such as these. Although this assumption seems extreme
it provides a good foundation for defining solid and
well defined database management systems and some
of the most successful software companies in the
world, such as Oracle, Sybase, IBM, and Microsoft,
have marketed database management systems based on
the relational model quite successfully.
""")
p("""
SQL stands for Structured Query Language.
The SQL language defines industry standard
mechanisms for creating, querying, and modified
relational tables. Several years ago SQL was one
of many Relational Database Management System
(RDBMS) query languages in use, and many would
argue not the best on. Now, largely due
to standardization efforts and the
backing of IBM, SQL is THE standard way to talk
to database systems.
""")
p("""
There are many advantages SQL offers over other
database query languages and alternative paradigms
at this time (please see [O'Neill] or [Korth and Silberschatz]
for more extensive discussions and comparisons between the
SQL/relational approach and others.)
""")
p("""
The chief advantage over all contenders at this time
is that SQL and the relational model are now widely
used as interfaces and back end data stores to many
different products with different performance characteristics,
user interfaces, and other qualities: Oracle, Sybase,
Ingres, SQL Server, Access, Outlook,
Excel, IBM DB2, Paradox, MySQL, MSQL, POSTgres, and many
others. For this reason a program designed to use
an SQL database as its data storage mechanism can
easily be ported from one SQL data manager to another,
possibly on different platforms. In fact the same
program can seamlessly use several backends and/or
import/export data between different data base platforms
with trivial ease.
No other paradigm offers such flexibility at the moment.
""")
p("""
Another advantage which is not as immediately
obvious is that the relational model and the SQL
query language are easily understood by semi-technical
and non-technical professionals, such as business
people and accountants. Human resources managers
who would be terrified by an object model diagram
or a snippet of code that resembles a conventional
programming language will frequently feel quite at
ease with a relational model which resembles the
sort of tabular data they deal with on paper in
reports and forms on a daily basis. With a little training the
same HR managers may be able to translate the request
"Who are the drinkers who like bud and frequent cheers?"
into the SQL query
""")
pre("""
select drinker
from frequents
where bar='cheers'
and drinker in (
select drinker
from likes
where beer='bud')
""")
p("""
(or at least they have some hope of understanding
the query once it is written by a technical person
or generated by a GUI interface tool). Thus the use
of SQL and the relational model enables communication
between different communities which must understand
and interact with stored information. In contrast
many other approaches cannot be understood easily
by people without extensive programming experience.
""")
p("""
Furthermore the declarative nature of SQL
lends itself to automatic query optimization,
and engines such as Gadfly can automatically translate a user query
into an optimized query plan which takes
advantage of available indices and other data characteristics.
In contrast more navigational techniques require the application
program itself to optimize the accesses to the database and
explicitly make use of indices.
""")
# HACK
Elements.append(PageBreak())
p("""
While it must be admitted that there are application
domains such as computer aided engineering design where
the relational model is unnatural, it is also important
to recognize that for many application domains (such
as scheduling, accounting, inventory, finance, personal
information management, electronic mail) the relational
model is a very natural fit and the SQL query language
make most accesses to the underlying data (even sophisticated
ones) straightforward. """)
p("""For an example of a moderately
sophisticated query using the tables given above,
the following query lists the drinkers who frequent lolas bar
and like at least two beers not served by lolas
""")
if 0:
go()
sys.exit(1)
pre("""
select f.drinker
from frequents f, likes l
where f.drinker=l.drinker and f.bar='lolas'
and l.beer not in
(select beer from serves where bar='lolas')
group by f.drinker
having count(distinct beer)>=2
""")
p("""
yielding the result
""")
pre("""
DRINKER
=======
norm
""")
p("""
Experience shows that queries of this sort are actually
quite common in many applications, and are often much more
difficult to formulate using some navigational database
organizations, such as some "object oriented" database
paradigms.
""")
p("""
Certainly,
SQL does not provide all you need to interact with
databases -- in order to do "real work" with SQL you
need to use SQL and at least one other language
(such as C, Pascal, C++, Perl, Python, TCL, Visual Basic
or others) to do work (such as readable formatting a report
from raw data) that SQL was not designed to do.
""")
header("Why Gadfly 1?")
p("""Gadfly 1.0 is an SQL based relational database implementation
implemented entirely in the Python programming language, with
optional fast data structure accellerators implemented in the
C programming language. Gadfly is relatively small, highly portable,
very easy to use (especially for programmers with previous experience
with SQL databases such as MS Access or Oracle), and reasonably
fast (especially when the kjbuckets C accellerators are used).
For moderate sized problems Gadfly offers a fairly complete
set of features such as transaction semantics, failure recovery,
and a TCP/IP based client/server mode (Please see [Gadfly] for
detailed discussion).""")
header("Why Gadfly 2?")
p("""Gadfly 1.0 also has significant limitations. An active Gadfly
1.0 database keeps all data in (virtual) memory, and hence a Gadfly
1.0 database is limited in size to available virtual memory. Important
features such as date/time/interval operations, regular expression
matching and other standard SQL features are not implemented in
Gadfly 1.0. The optimizer and the query evaluator perform optimizations
using properties of the equality predicate but do not optimize
using properties of inequalities such as BETWEEN or less-than.
It is possible to add "extension views" to a Gadfly
1.0 database, but the mechanism is somewhat clumsy and indices
over extension views are not well supported. The features of Gadfly
2.0 discussed here attempt to address these deficiencies by providing
a uniform extension model that permits addition of alternate table,
function, and predicate implementations.""")
p("""Other deficiencies, such as missing constructs like "ALTER
TABLE" and the lack of outer joins and NULL values are not
addressed here, although they may be addressed in Gadfly 2.0 or
a later release. This paper also does not intend to explain
the complete operations of the internals; it is intended to provide
at least enough information to understand the basic mechanisms
for extending gadfly.""")
p("""Some concepts and definitions provided next help with the description
of the gadfly interfaces. [Note: due to the terseness of this
format the ensuing is not a highly formal presentation, but attempts
to approach precision where precision is important.]""")
header("The semilattice of substitutions")
p("""Underlying the gadfly implementation are the basic concepts
associated with substitutions. A substitution is a mapping
of attribute names to values (implemented in gadfly using kjbuckets.kjDict
objects). Here an attribute refers to some sort of "descriptive
variable", such as NAME and a value is an assignment for that variable,
like "Dave Ascher". In Gadfly a table is implemented as a sequence
of substitutions, and substitutions are used in many other ways as well.
""")
p("""
For example consider the substitutions""")
pre("""
A = [DRINKER=>'sam']
B = [DRINKER=>'sam', BAR=>'cheers']
C = [DRINKER=>'woody', BEER=>'bud']
D = [DRINKER=>'sam', BEER=>'mickies']
E = [DRINKER=>'sam', BAR=>'cheers', BEER=>'mickies']
F = [DRINKER=>'sam', BEER=>'mickies']
G = [BEER=>'bud', BAR=>'lolas']
H = [] # the empty substitution
I = [BAR=>'cheers', CAPACITY=>300]""")
p("""A trivial but important observation is that since substitutions
are mappings, no attribute can assume more than one value in a
substitution. In the operations described below whenever an operator
"tries" to assign more than one value to an attribute
the operator yields an "overdefined" or "inconsistent"
result.""")
header("Information Semi-order:")
p("""Substitution B is said to be
more informative than A because B agrees with all assignments
in A (in addition to providing more information as well). Similarly
we say that E is more informative than A, B, D, F. and H but E
is not more informative than the others since, for example G disagrees
with E on the value assigned to the BEER attribute and I provides
additional CAPACITY information not provided in E.""")
header("Joins and Inconsistency:")
p("""A join of two substitutions
X and Y is the least informative substitution Z such that Z is
more informative (or equally informative) than both X and Y. For
example B is the join of B with A, E is the join of B with D and""")
pre("""
E join I =
[DRINKER=>'sam', BAR=>'cheers', BEER=>'mickies', CAPACITY=>300]""")
p("""For any two substitutions either (1) they disagree on the value
assigned to some attribute and have no join or (2) they agree
on all common attributes (if there are any) and their join is
the union of all (name, value) assignments in both substitutions.
Written in terms of kjbucket.kjDict operations two kjDicts X and
Y have a join Z = (X+Y) if and only if Z.Clean() is not None.
Two substitutions that have no join are said to be inconsistent.
For example I and G are inconsistent since they disagree on
the value assigned to the BAR attribute and therefore have no
join. The algebra of substitutions with joins technically defines
an abstract algebraic structure called a semilattice.""")
header("Name space remapping")
p("""Another primitive operation over substitutions is the remap
operation S2 = S.remap(R) where S is a substitution and R is a
graph of attribute names and S2 is a substitution. This operation
is defined to produce the substitution S2 such that""")
pre("""
Name=>Value in S2 if and only if
Name1=>Value in S and Name<=Name1 in R
""")
p("""or if there is no such substitution S2 the remap value is said
to be overdefined.""")
p("""For example the remap operation may be used to eliminate attributes
from a substitution. For example""")
pre("""
E.remap([DRINKER<=DRINKER, BAR<=BAR])
= [DRINKER=>'sam', BAR=>'cheers']
""")
p("""Illustrating that remapping using the [DRINKER<=DRINKER,
BAR<=BAR] graph eliminates all attributes except DRINKER and
BAR, such as BEER. More generally remap can be used in this way
to implement the classical relational projection operation. (See [Korth and Silberschatz]
for a detailed discussion of the projection operator and other relational
algebra operators such as selection, rename, difference and joins.)""")
p("""The remap operation can also be used to implement "selection
on attribute equality". For example if we are interested
in the employee names of employees who are their own bosses we
can use the remapping graph""")
pre("""
R1 = [NAME<=NAME, NAME<=BOSS]
""")
p("""and reject substitutions where remapping using R1 is overdefined.
For example""")
pre("""
S1 = [NAME=>'joe', BOSS=>'joe']
S1.remap(R1) = [NAME=>'joe']
S2 = [NAME=>'fred', BOSS=>'joe']
S2.remap(R1) is overdefined.
""")
p("""The last remap is overdefined because the NAME attribute cannot
assume both the values 'fred' and 'joe' in a substitution.""")
p("""Furthermore, of course, the remap operation can be used to
"rename attributes" or "copy attribute values"
in substitutions. Note below that the missing attribute CAPACITY
in B is effectively ignored in the remapping operation.""")
pre("""
B.remap([D<=DRINKER, B<=BAR, B2<=BAR, C<=CAPACITY])
= [D=>'sam', B=>'cheers', B2=>'cheers']
""")
p("""More interestingly, a single remap operation can be used to
perform a combination of renaming, projection, value copying,
and attribute equality selection as one operation. In kjbuckets the remapper
graph is implemented using a kjbuckets.kjGraph and the remap operation
is an intrinsic method of kjbuckets.kjDict objects.""")
header("Generalized Table Joins and the Evaluator Mainloop""")
p("""Strictly speaking the Gadfly 2.0 query evaluator only uses
the join and remap operations as its "basic assembly language"
-- all other computations, including inequality comparisons and
arithmetic, are implemented externally to the evaluator as "generalized
table joins." """)
p("""A table is a sequence of substitutions (which in keeping with
SQL semantics may contain redundant entries). The join between
two tables T1 and T2 is the sequence of all possible defined joins
between pairs of elements from the two tables. Procedurally we
might compute the join as""")
pre("""
T1JoinT2 = empty
for t1 in T1:
for t2 in T2:
if t1 join t2 is defined:
add t1 join t2 to T1joinT2""")
p("""In general circumstances this intuitive implementation is a
very inefficient way to compute the join, and Gadfly almost always
uses other methods, particularly since, as described below, a
"generalized table" can have an "infinite"
number of entries.""")
p("""For an example of a table join consider the EMPLOYEES table
containing""")
pre("""
[NAME=>'john', JOB=>'executive']
[NAME=>'sue', JOB=>'programmer']
[NAME=>'eric', JOB=>'peon']
[NAME=>'bill', JOB=>'peon']
""")
p("""and the ACTIVITIES table containing""")
pre("""
[JOB=>'peon', DOES=>'windows']
[JOB=>'peon', DOES=>'floors']
[JOB=>'programmer', DOES=>'coding']
[JOB=>'secretary', DOES=>'phone']""")
p("""then the join between EMPLOYEES and ACTIVITIES must containining""")
pre("""
[NAME=>'sue', JOB=>'programmer', DOES=>'coding']
[NAME=>'eric', JOB=>'peon', DOES=>'windows']
[NAME=>'bill', JOB=>'peon', DOES=>'windows']
[NAME=>'eric', JOB=>'peon', DOES=>'floors']
[NAME=>'bill', JOB=>'peon', DOES=>'floors']""")
p("""A compiled gadfly subquery ultimately appears to the evaluator
as a sequence of generalized tables that must be joined (in combination
with certain remapping operations that are beyond the scope of
this discussion). The Gadfly mainloop proceeds following the very
loose pseudocode:""")
pre("""
Subs = [ [] ] # the unary sequence containing "true"
While some table hasn't been chosen yet:
Choose an unchosen table with the least cost join estimate.
Subs = Subs joined with the chosen table
return Subs""")
p("""[Note that it is a property of the join operation that the
order in which the joins are carried out will not affect the result,
so the greedy strategy of evaluating the "cheapest join next"
will not effect the result. Also note that the treatment of logical
OR and NOT as well as EXIST, IN, UNION, and aggregation and so
forth are not discussed here, even though they do fit into this
approach.]""")
p("""The actual implementation is a bit more complex than this,
but the above outline may provide some useful intuition. The "cost
estimation" step and the implementation of the join operation
itself are left up to the generalized table object implementation.
A table implementation has the ability to give an "infinite"
cost estimate, which essentially means "don't join me in
yet under any circumstances." """)
header("Implementing Functions")
p("""As mentioned above operations such as arithmetic are implemented
using generalized tables. For example the arithmetic Add operation
is implemented in Gadfly internally as an "infinite generalized
table" containing all possible substitutions""")
pre("""
ARG0=>a, ARG1=>b, RESULT=>a+b]
""")
p("""Where a and b are all possible values which can be summed.
Clearly, it is not possible to enumerate this table, but given
a sequence of substitutions with defined values for ARG0 and ARG1
such as""")
pre("""
[ARG0=>1, ARG1=-4]
[ARG0=>2.6, ARG1=50]
[ARG0=>99, ARG1=1]
""")
p("""it is possible to implement a "join operation" against
this sequence that performs the same augmentation as a join with
the infinite table defined above:""")
pre("""
[ARG0=>1, ARG1=-4, RESULT=-3]
[ARG0=>2.6, ARG1=50, RESULT=52.6]
[ARG0=>99, ARG1=1, RESULT=100]
""")
p("""Furthermore by giving an "infinite estimate" for
all attempts to evaluate the join where ARG0 and ARG1 are not
available the generalized table implementation for the addition
operation can refuse to compute an "infinite join." """)
p("""More generally all functions f(a,b,c,d) are represented in
gadfly as generalized tables containing all possible relevant
entries""")
pre("""
[ARG0=>a, ARG1=>b, ARG2=>c, ARG3=>d, RESULT=>f(a,b,c,d)]""")
p("""and the join estimation function refuses all attempts to perform
a join unless all the arguments are provided by the input substitution
sequence.""")
header("Implementing Predicates")
p("""Similarly to functions, predicates such as less-than and BETWEEN
and LIKE are implemented using the generalized table mechanism.
For example the "x BETWEEN y AND z" predicate is implemented
as a generalized table "containing" all possible""")
pre("""
[ARG0=>a, ARG1=>b, ARG2=>c]""")
p("""where b<a<c. Furthermore joins with this table are not
permitted unless all three arguments are available in the sequence
of input substitutions.""")
header("Some Gadfly extension interfaces")
p("""A gadfly database engine may be extended with user defined
functions, predicates, and alternative table and index implementations.
This section snapshots several Gadfly 2.0 interfaces, currently under
development and likely to change before the package is released.""")
p("""The basic interface for adding functions and predicates (logical tests)
to a gadfly engine are relatively straightforward. For example to add the
ability to match a regular expression within a gadfly query use the
following implementation.""")
pre("""
from re import match
def addrematch(gadflyinstance):
gadflyinstance.add_predicate("rematch", match)
""")
p("""
Then upon connecting to the database execute
""")
pre("""
g = gadfly(...)
...
addrematch(g)
""")
p("""
In this case the "semijoin operation" associated with the new predicate
"rematch" is automatically generated, and after the add_predicate
binding operation the gadfly instance supports queries such as""")
pre("""
select drinker, beer
from likes
where rematch('b*', beer) and drinker not in
(select drinker from frequents where rematch('c*', bar))
""")
p("""
By embedding the "rematch" operation within the query the SQL
engine can do "more work" for the programmer and reduce or eliminate the
need to process the query result externally to the engine.
""")
p("""
In a similar manner functions may be added to a gadfly instance,""")
pre("""
def modulo(x,y):
return x % y
def addmodulo(gadflyinstance):
gadflyinstance.add_function("modulo", modulo)
...
g = gadfly(...)
...
addmodulo(g)
""")
p("""
Then after the binding the modulo function can be used whereever
an SQL expression can occur.
""")
p("""
Adding alternative table implementations to a Gadfly instance
is more interesting and more difficult. An "extension table" implementation
must conform to the following interface:""")
pre("""
# get the kjbuckets.kjSet set of attribute names for this table
names = table.attributes()
# estimate the difficulty of evaluating a join given known attributes
# return None for "impossible" or n>=0 otherwise with larger values
# indicating greater difficulty or expense
estimate = table.estimate(known_attributes)
# return the join of the rows of the table with
# the list of kjbuckets.kjDict mappings as a list of mappings.
resultmappings = table.join(listofmappings)
""")
p("""
In this case add the table to a gadfly instance using""")
pre("""
gadflyinstance.add_table("table_name", table)
""")
p("""
For example to add a table which automatically queries filenames
in the filesystems of the host computer a gadfly instance could
be augmented with a GLOB table implemented using the standard
library function glob.glob as follows:""")
pre("""
import kjbuckets
class GlobTable:
def __init__(self): pass
def attributes(self):
return kjbuckets.kjSet("PATTERN", "NAME")
def estimate(self, known_attributes):
if known_attributes.member("PATTERN"):
return 66 # join not too difficult
else:
return None # join is impossible (must have PATTERN)
def join(self, listofmappings):
from glob import glob
result = []
for m in listofmappings:
pattern = m["PATTERN"]
for name in glob(pattern):
newmapping = kjbuckets.kjDict(m)
newmapping["NAME"] = name
if newmapping.Clean():
result.append(newmapping)
return result
...
gadfly_instance.add_table("GLOB", GlobTable())
""")
p("""
Then one could formulate queries such as "list the files in directories
associated with packages installed by guido"
""")
pre("""
select g.name as filename
from packages p, glob g
where p.installer = 'guido' and g.pattern=p.root_directory
""")
p("""
Note that conceptually the GLOB table is an infinite table including
all filenames on the current computer in the "NAME" column, paired with
a potentially infinite number of patterns.
""")
p("""
More interesting examples would allow queries to remotely access
data served by an HTTP server, or from any other resource.
""")
p("""
Furthermore an extension table can be augmented with update methods
""")
pre("""
table.insert_rows(listofmappings)
table.update_rows(oldlist, newlist)
table.delete_rows(oldlist)
""")
p("""
Note: at present the implementation does not enforce recovery or
transaction semantics for updates to extension tables, although this
may change in the final release.
""")
p("""
The table implementation is free to provide its own implementations of
indices which take advantage of data provided by the join argument.
""")
header("Efficiency Notes")
p("""The following thought experiment attempts to explain why the
Gadfly implementation is surprisingly fast considering that it
is almost entirely implemented in Python (an interpreted programming
language which is not especially fast when compared to alternatives).
Although Gadfly is quite complex, at an abstract level the process
of query evaluation boils down to a series of embedded loops.
Consider the following nested loops:""")
pre("""
iterate 1000:
f(...) # fixed cost of outer loop
iterate 10:
g(...) # fixed cost of middle loop
iterate 10:
# the real work (string parse, matrix mul, query eval...)
h(...)""")
p("""In my experience many computations follow this pattern where
f, g, are complex, dynamic, special purpose and h is simple, general
purpose, static. Some example computations that follow this pattern
include: file massaging (perl), matrix manipulation (python, tcl),
database/cgi page generation, and vector graphics/imaging.""")
p("""Suppose implementing f, g, h in python is easy but result in
execution times10 times slower than a much harder implementation
in C, choosing arbitrary and debatable numbers assume each function
call consumes 1 tick in C, 5 ticks in java, 10 ticks in python
for a straightforward implementation of each function f, g, and
h. Under these conditions we get the following cost analysis,
eliminating some uninteresting combinations, of implementing the
function f, g, and h in combinations of Python, C and java:""")
pre("""
COST | FLANG | GLANG | HLANG
==================================
111000 | C | C | C
115000 | java | C | C
120000 | python | C | C
155000 | java | java | C
210000 | python | python | C
555000 | java | java | java
560000 | python | java | java
610000 | python | python | java
1110000 | python | python | python
""")
p("""Note that moving only the innermost loop to C (python/python/C)
speeds up the calculation by half an order of magnitude compared
to the python-only implementation and brings the speed to within
a factor of 2 of an implementation done entirely in C.""")
p("""Although this artificial and contrived thought experiment is
far from conclusive, we may be tempted to draw the conclusion
that generally programmers should focus first on obtaining a working
implementation (because as John Ousterhout is reported to have
said "the biggest performance improvement is the transition
from non-working to working") using the methodology that
is most likely to obtain a working solution the quickest (Python). Only then if the performance
is inadequate should the programmer focus on optimizing
the inner most loops, perhaps moving them to a very efficient
implementation (C). Optimizing the outer loops will buy little
improvement, and should be done later, if ever.""")
p("""This was precisely the strategy behind the gadfly implementations,
where most of the inner loops are implemented in the kjbuckets
C extension module and the higher level logic is all in Python.
This also explains why gadfly appears to be "slower"
for simple queries over small data sets, but seems to be relatively
"faster" for more complex queries over larger data sets,
since larger queries and data sets take better advantage of the
optimized inner loops.""")
header("A Gadfly variant for OLAP?")
p("""In private correspondence Andy Robinson points out that the
basic logical design underlying Gadfly could be adapted to provide
Online Analytical Processing (OLAP) and other forms of data warehousing
and data mining. Since SQL is not particularly well suited for
the kinds of requests common in these domains the higher level
interfaces would require modification, but the underlying logic
of substitutions and name mappings seems to be appropriate.""")
header("Conclusion")
p("""The revamped query engine design in Gadfly 2 supports
a flexible and general extension methodology that permits programmers
to extend the gadfly engine to include additional computations
and access to remote data sources. Among other possibilities this
will permit the gadfly engine to make use of disk based indexed
tables and to dynamically retrieve information from remote data
sources (such as an Excel spreadsheet or an Oracle database).
These features will make gadfly a very useful tool for data manipulation
and integration.""")
header("References")
p("""[Van Rossum] Van Rossum, Python Reference Manual, Tutorial, and Library Manuals,
please look to http://www.python.org
for the latest versions, downloads and links to printed versions.""")
p("""[O'Neill] O'Neill, P., Data Base Principles, Programming, Performance,
Morgan Kaufmann Publishers, San Francisco, 1994.""")
p("""[Korth and Silberschatz] Korth, H. and Silberschatz, A. and Sudarshan, S.
Data Base System Concepts, McGraw-Hill Series in Computer Science, Boston,
1997""")
p("""[Gadfly]Gadfly: SQL Relational Database in Python,
http://www.chordate.com/kwParsing/gadfly.html""")
go()
reportlab-3.5.34/demos/stdfonts/ 0000775 0001750 0001750 00000000000 13607302651 017352 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/stdfonts/00readme.txt 0000664 0001750 0001750 00000000345 13544671343 021521 0 ustar rptlab rptlab 0000000 0000000 This lists out the standard 14 fonts
in a very plain and simple fashion.
Notably, the output is huge - it makes
two separate text objects for each glyph.
Smarter programming would make tighter
PDF, but more lines of Python!
reportlab-3.5.34/demos/stdfonts/stdfonts.py 0000664 0001750 0001750 00000004515 13544671343 021604 0 ustar rptlab rptlab 0000000 0000000 #Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__doc__="""
This generates tables showing the 14 standard fonts in both
WinAnsi and MacRoman encodings, and their character codes.
Supply an argument of 'hex' or 'oct' to get code charts
in those encodings; octal is what you need for \\n escape
sequences in Python literals.
usage: standardfonts.py [dec|hex|oct]
"""
__version__='3.3.0'
import sys
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfgen import canvas
import string
label_formats = {'dec':('%d=', 'Decimal'),
'oct':('%o=','Octal'),
'hex':('0x%x=', 'Hexadecimal')}
def run(mode):
label_formatter, caption = label_formats[mode]
for enc in ['MacRoman', 'WinAnsi']:
canv = canvas.Canvas(
'StandardFonts_%s.pdf' % enc,
)
canv.setPageCompression(0)
for faceName in pdfmetrics.standardFonts:
if faceName in ['Symbol', 'ZapfDingbats']:
encLabel = faceName+'Encoding'
else:
encLabel = enc + 'Encoding'
fontName = faceName + '-' + encLabel
pdfmetrics.registerFont(pdfmetrics.Font(fontName,
faceName,
encLabel)
)
canv.setFont('Times-Bold', 18)
canv.drawString(80, 744, fontName)
canv.setFont('Times-BoldItalic', 12)
canv.drawRightString(515, 744, 'Labels in ' + caption)
#for dingbats, we need to use another font for the numbers.
#do two parallel text objects.
for byt in range(32, 256):
col, row = divmod(byt - 32, 32)
x = 72 + (66*col)
y = 720 - (18*row)
canv.setFont('Helvetica', 14)
canv.drawString(x, y, label_formatter % byt)
canv.setFont(fontName, 14)
canv.drawString(x+44, y, chr(byt).decode(encLabel,'ignore').encode('utf8'))
canv.showPage()
canv.save()
if __name__ == '__main__':
if len(sys.argv)==2:
mode = string.lower(sys.argv[1])
if mode not in ['dec','oct','hex']:
print(__doc__)
elif len(sys.argv) == 1:
mode = 'dec'
run(mode)
else:
print(__doc__)
reportlab-3.5.34/demos/odyssey/ 0000775 0001750 0001750 00000000000 13607302651 017205 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/odyssey/00readme.txt 0000664 0001750 0001750 00000004074 13544671343 021357 0 ustar rptlab rptlab 0000000 0000000 This contains a number of benchmarks and demos
based on Homer's Odyssey (which is widely available
in plain, line-oriented text format).
The version used here was obtained from Project Gutenberg.
The URL is as follows:
http://www.gutenberg.org/etext/1727
Our distribution ships with just the first chapter
in odyssey.txt. For a more meaningful speed test,
download the full copy from
http://www.reportlab.com/ftp/odyssey.full.zip
and unzip to extract odyssey.full.txt (608kb).
Benchmark speed depends quite critically
on the presence of our accelerator module,
_rl_accel, which is a C (or Java) extension.
Serious users ought to compile or download this!
The times quoted are from one machine (Andy Robinson's
home PC, approx 1.2Ghz 128Mb Ram, Win2k in Sep 2003)
in order to give a rough idea of what features cost
what performance.
The tests are as follows:
(1) odyssey.py (produces odyssey.pdf)
This demo takes a large volume of text and prints it
in the simplest way possible. It is a demo of the
basic technique of looping down a page manually and
breaking at the bottom. On my 1.2 Ghz machine this takes
1.91 seconds (124 pages per second)
(2) fodyssey.py (produces fodyssey.pdf)
This is a 'flowing document' we parse the file and
throw away line breaks to make proper paragraphs.
The Platypus framework renders these. This necessitates
measuring the width of every word in every paragraph
for wrapping purposes.
This takes 3.27 seconds on the same machine. Paragraph
wrapping basically doubles the work. The text is more
compact with about 50% more words per page. Very roughly,
we can wrap 40 pages of ten-point text per second and save
to PDF.
(3) dodyssey.py (produced dodyssey.pdf)
This is a slightly fancier version which uses different
page templates (one column for first page in a chapter,
two column for body poages). The additional layout logic
adds about 15%, going up to 3.8 seconds. This is probably
a realistic benchmark for a simple long text document
with a single pass. Documents doing cross-references
and a table of contents might need twice as long.
reportlab-3.5.34/demos/odyssey/odyssey.txt 0000664 0001750 0001750 00000025306 13544671343 021462 0 ustar rptlab rptlab 0000000 0000000 The Odyssey
By Homer
rendered into English prose by Samuel Butler
Book I
THE GODS IN COUNCIL--MIVERVA'S VISIT TO ITHACA--THE CHALLENGE
FROM TELEMACHUS TO THE SUITORS.
ITellme, O Muse, of that ingenious hero who travelled far and
a b c &| & | A' A ' wide after he had sacked the famous town of Troy. Many cities
did he visit, and many were the nations with whose manners and
customs he was acquainted; moreover he suffered much by sea
while trying to save his own life and bring his men safely home;
but do what he might he could not save his men, for they
perished through their own sheer folly in eating the cattle of
the Sun-god Hyperion; so the god prevented them from ever
reaching home. Tell me, too, about all these things, oh daughter
of Jove, from whatsoever source you may know them.
So now all who escaped death in battle or by shipwreck had got
safely home except Ulysses, and he, though he was longing to
return to his wife and country, was detained by the goddess
Calypso, who had got him into a large cave and wanted to marry
him. But as years went by, there came a time when the gods
settled that he should go back to Ithaca; even then, however,
when he was among his own people, his troubles were not yet
over; nevertheless all the gods had now begun to pity him except
Neptune, who still persecuted him without ceasing and would not
let him get home.
Now Neptune had gone off to the Ethiopians, who are at the
world's end, and lie in two halves, the one looking West and the
other East.1 He had gone there to accept a hecatomb of sheep
and oxen, and was enjoying himself at his festival; but the
other gods met in the house of Olympian Jove, and the sire of
gods and men spoke first. At that moment he was thinking of
Aegisthus, who had been killed by Agamemnon's son Orestes; so he
said to the other gods:
"See now, how men lay blame upon us gods for what is after all
nothing but their own folly. Look at Aegisthus; he must needs
make love to Agamemnon's wife unrighteously and then kill
Agamemnon, though he knew it would be the death of him; for I
sent Mercury to warn him not to do either of these things,
inasmuch as Orestes would be sure to take his revenge when he
grew up and wanted to return home. Mercury told him this in all
good will but he would not listen, and now he has paid for
everything in full."
Then Minerva said, "Father, son of Saturn, King of kings, it
served Aegisthus right, and so it would any one else who does as
he did; but Aegisthus is neither here nor there; it is for
Ulysses that my heart bleeds, when I think of his sufferings in
that lonely sea-girt island, far away, poor man, from all his
friends. It is an island covered with forest, in the very middle
of the sea, and a goddess lives there, daughter of the magician
Atlas, who looks after the bottom of the ocean, and carries the
great columns that keep heaven and earth asunder. This daughter
of Atlas has got hold of poor unhappy Ulysses, and keeps trying
by every kind of blandishment to make him forget his home, so
that he is tired of life, and thinks of nothing but how he may
once more see the smoke of his own chimneys. You, sir, take no
heed of this, and yet when Ulysses was before Troy did he not
propitiate you with many a burnt sacrifice? Why then should you
keep on being so angry with him?"
And Jove said, "My child, what are you talking about? How can I
forget Ulysses than whom there is no more capable man on earth,
nor more liberal in his offerings to the immortal gods that live
in heaven? Bear in mind, however, that Neptune is still furious
with Ulysses for having blinded an eye of Polyphemus king of the
Cyclopes. Polyphemus is son to Neptune by the nymph Thoosa,
daughter to the sea-king Phorcys; therefore though he will not
kill Ulysses outright, he torments him by preventing him from
getting home. Still, let us lay our heads together and see how
we can help him to return; Neptune will then be pacified, for if
we are all of a mind he can hardly stand out against us."
And Minerva said, "Father, son of Saturn, King of kings, if,
then, the gods now mean that Ulysses should get home, we should
first send Mercury to the Ogygian island to tell Calypso that we
have made up our minds and that he is to return. In the meantime
I will go to Ithaca, to put heart into Ulysses' son Telemachus;
I will embolden him to call the Achaeans in assembly, and speak
out to the suitors of his mother Penelope, who persist in eating
up any number of his sheep and oxen; I will also conduct him to
Sparta and to Pylos, to see if he can hear anything about the
return of his dear father--for this will make people speak well
of him."
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
Ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis ellipsis.
"Men of Ithaca, it is all your own fault that things have turned
out as they have; you would not listen to me, nor yet to Mentor,
when we bade you check the folly of your sons who were doing
much wrong in the wantonness of their hearts--wasting the
substance and dishonouring the wife of a chieftain who they
thought would not return. Now, however, let it be as I say, and
do as I tell you. Do not go out against Ulysses, or you may find
that you have been drawing down evil on your own heads."
This was what he said, and more than half raised a loud shout,
and at once left the assembly. But the rest stayed where they
were, for the speech of Halitherses displeased them, and they
sided with Eupeithes; they therefore hurried off for their
armour, and when they had armed themselves, they met together in
front of the city, and Eupeithes led them on in their folly. He
thought he was going to avenge the murder of his son, whereas in
truth he was never to return, but was himself to perish in his
attempt.
Then Minerva said to Jove, "Father, son of Saturn, king of
kings, answer me this question--What do you propose to do? Will
you set them fighting still further, or will you make peace
between them?"
And Jove answered, "My child, why should you ask me? Was it not
by your own arrangement that Ulysses came home and took his
revenge upon the suitors? Do whatever you like, but I will tell
you what I think will be most reasonable arrangement. Now that
Ulysses is revenged, let them swear to a solemn covenant, in
virtue of which he shall continue to rule, while we cause the
others to forgive and forget the massacre of their sons and
brothers. Let them then all become friends as heretofore, and
let peace and plenty reign."
This was what Minerva was already eager to bring about, so down
she darted from off the topmost summits of Olympus.
Now when Laertes and the others had done dinner, Ulysses began
by saying, "Some of you go out and see if they are not getting
close up to us." So one of Dolius's sons went as he was bid.
Standing on the threshold he could see them all quite near, and
said to Ulysses, "Here they are, let us put on our armour at
once."
They put on their armour as fast as they could--that is to say
Ulysses, his three men, and the six sons of Dolius. Laertes
also and Dolius did the same--warriors by necessity in spite of
their grey hair. When they had all put on their armour, they
opened the gate and sallied forth, Ulysses leading the way.
Then Jove's daughter Minerva came up to them, having assumed the
form and voice of Mentor. Ulysses was glad when he saw her, and
said to his son Telemachus, "Telemachus, now that you are about
to fight in an engagement, which will show every man's mettle,
be sure not to disgrace your ancestors, who were eminent for
their strength and courage all the world over."
"You say truly, my dear father," answered Telemachus, "and you
shall see, if you will, that I am in no mind to disgrace your
family."
Laertes was delighted when he heard this. "Good heavens," he
exclaimed, "what a day I am enjoying: I do indeed rejoice at it.
My son and grandson are vying with one another in the matter of
valour."
On this Minerva came close up to him and said, "Son of
Arceisius---best friend I have in the world--pray to the
blue-eyed damsel, and to Jove her father; then poise your spear
and hurl it."
As she spoke she infused fresh vigour into him, and when he had
prayed to her he poised his spear and hurled it. He hit
Eupeithes' helmet, and the spear went right through it, for the
helmet stayed it not, and his armour rang rattling round him as
he fell heavily to the ground. Meantime Ulysses and his son
fell upon the front line of the foe and smote them with their
swords and spears; indeed, they would have killed every one of
them, and prevented them from ever getting home again, only
Minerva raised her voice aloud, and made every one pause. "Men
of Ithaca," she cried, "cease this dreadful war, and settle the
matter at once without further bloodshed."
On this pale fear seized every one; they were so frightened that
their arms dropped from their hands and fell upon the ground at
the sound of the goddess' voice, and they fled back to the city
for their lives. But Ulysses gave a great cry, and gathering
himself together swooped down like a soaring eagle. Then the son
of Saturn sent a thunderbolt of fire that fell just in front of
Minerva, so she said to Ulysses, "Ulysses, noble son of Laertes,
stop this warful strife, or Jove will be angry with you."
Thus spoke Minerva, and Ulysses obeyed her gladly. Then Minerva
assumed the form and voice of Mentor, and presently made a
covenant of peace between the two contending parties.
----------------------------------------------------------------------
Copyright statement:
This text is in the public domain and has been modified by ReportLab.
The source of the text specifies that all references to them must be
removed if the text is distributed in modified form, so we cannot
mention them here. They are credited in the 00readme.txt.
This modified form of the text remains in the public domain. No
copyright is asserted.
To really test that reportlab can produce pages quickly download the
complete version of the test from ftp://ftp.reportlab.com/odyssey.full.zip
and copy it to this directory as odyssey.full.txt.
reportlab-3.5.34/demos/odyssey/dodyssey.py 0000664 0001750 0001750 00000016741 13544671343 021442 0 ustar rptlab rptlab 0000000 0000000 #Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__version__='3.3.0'
__doc__=''
#REPORTLAB_TEST_SCRIPT
import sys, copy, os
from reportlab.platypus import *
_NEW_PARA=os.environ.get('NEW_PARA','0')[0] in ('y','Y','1')
_REDCAP=int(os.environ.get('REDCAP','0'))
_CALLBACK=os.environ.get('CALLBACK','0')[0] in ('y','Y','1')
if _NEW_PARA:
def Paragraph(s,style):
from rlextra.radxml.para import Paragraph as PPPP
return PPPP(s,style)
from reportlab.lib.units import inch
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
import reportlab.rl_config
reportlab.rl_config.invariant = 1
styles = getSampleStyleSheet()
Title = "The Odyssey"
Author = "Homer"
def myTitlePage(canvas, doc):
canvas.saveState()
canvas.restoreState()
def myLaterPages(canvas, doc):
canvas.saveState()
canvas.setFont('Times-Roman',9)
canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
canvas.restoreState()
def go():
def myCanvasMaker(fn,**kw):
from reportlab.pdfgen.canvas import Canvas
canv = Canvas(fn,**kw)
# attach our callback to the canvas
canv.myOnDrawCB = myOnDrawCB
return canv
doc = BaseDocTemplate('dodyssey.pdf',showBoundary=0)
#normal frame as for SimpleFlowDocument
frameT = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
#Two Columns
frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width/2-6, doc.height, id='col1')
frame2 = Frame(doc.leftMargin+doc.width/2+6, doc.bottomMargin, doc.width/2-6,
doc.height, id='col2')
doc.addPageTemplates([PageTemplate(id='First',frames=frameT, onPage=myTitlePage),
PageTemplate(id='OneCol',frames=frameT, onPage=myLaterPages),
PageTemplate(id='TwoCol',frames=[frame1,frame2], onPage=myLaterPages),
])
doc.build(Elements,canvasmaker=myCanvasMaker)
Elements = []
ChapterStyle = copy.deepcopy(styles["Heading1"])
ChapterStyle.alignment = TA_CENTER
ChapterStyle.fontsize = 14
InitialStyle = copy.deepcopy(ChapterStyle)
InitialStyle.fontsize = 16
InitialStyle.leading = 20
PreStyle = styles["Code"]
def newPage():
Elements.append(PageBreak())
chNum = 0
def myOnDrawCB(canv,kind,label):
print('myOnDrawCB(%s)'%kind, 'Page number=', canv.getPageNumber(), 'label value=', label)
def chapter(txt, style=ChapterStyle):
global chNum
Elements.append(NextPageTemplate('OneCol'))
newPage()
chNum += 1
if _NEW_PARA or not _CALLBACK:
Elements.append(Paragraph(txt, style))
else:
Elements.append(Paragraph(('foo '%chNum)+txt, style))
Elements.append(Spacer(0.2*inch, 0.3*inch))
if useTwoCol:
Elements.append(NextPageTemplate('TwoCol'))
def fTitle(txt,style=InitialStyle):
Elements.append(Paragraph(txt, style))
ParaStyle = copy.deepcopy(styles["Normal"])
ParaStyle.spaceBefore = 0.1*inch
if 'right' in sys.argv:
ParaStyle.alignment = TA_RIGHT
elif 'left' in sys.argv:
ParaStyle.alignment = TA_LEFT
elif 'justify' in sys.argv:
ParaStyle.alignment = TA_JUSTIFY
elif 'center' in sys.argv or 'centre' in sys.argv:
ParaStyle.alignment = TA_CENTER
else:
ParaStyle.alignment = TA_JUSTIFY
useTwoCol = 'notwocol' not in sys.argv
def spacer(inches):
Elements.append(Spacer(0.1*inch, inches*inch))
def p(txt, style=ParaStyle):
if _REDCAP:
fs, fe = '', ''
n = len(txt)
for i in range(n):
if 'a'<=txt[i]<='z' or 'A'<=txt[i]<='Z':
txt = (txt[:i]+(fs+txt[i]+fe))+txt[i+1:]
break
if _REDCAP>=2 and n>20:
j = i+len(fs)+len(fe)+1+int((n-1)/2)
while not ('a'<=txt[j]<='z' or 'A'<=txt[j]<='Z'): j += 1
txt = (txt[:j]+(''+txt[j]+''))+txt[j+1:]
if _REDCAP==3 and n>20:
n = len(txt)
fs = ''
for i in range(n-1,-1,-1):
if 'a'<=txt[i]<='z' or 'A'<=txt[i]<='Z':
txt = txt[:i]+((fs+txt[i]+fe)+txt[i+1:])
break
Elements.append(Paragraph(txt, style))
firstPre = 1
def pre(txt, style=PreStyle):
global firstPre
if firstPre:
Elements.append(NextPageTemplate('OneCol'))
newPage()
firstPre = 0
spacer(0.1)
p = Preformatted(txt, style)
Elements.append(p)
def parseOdyssey(fn):
from time import time
E = []
t0=time()
text = open(fn,'r').read()
i0 = text.index('Book I')
endMarker = 'covenant of peace between the two contending parties.'
i1 = text.index(endMarker)+len(endMarker)
PREAMBLE=list(map(str.strip,text[0:i0].split('\n')))
L=list(map(str.strip,text[i0:i1].split('\n')))
POSTAMBLE=list(map(str.strip,text[i1:].split('\n')))
def ambleText(L):
while L and not L[0]: L.pop(0)
while L:
T=[]
while L and L[0]:
T.append(L.pop(0))
yield T
while L and not L[0]: L.pop(0)
def mainText(L):
while L:
B = L.pop(0)
while not L[0]: L.pop(0)
T=[]
while L and L[0]:
T.append(L.pop(0))
while not L[0]: L.pop(0)
P = []
while L and not (L[0].startswith('Book ') and len(L[0].split())==2):
E=[]
while L and L[0]:
E.append(L.pop(0))
P.append(E)
if L:
while not L[0]: L.pop(0)
yield B,T,P
t1 = time()
print("open(%s,'r').read() took %.4f seconds" %(fn,t1-t0))
E.append([spacer,2])
E.append([fTitle,'%s' % Title, InitialStyle])
E.append([fTitle,'by %s' % Author, InitialStyle])
for T in ambleText(PREAMBLE):
E.append([p,'\n'.join(T)])
for (B,T,P) in mainText(L):
E.append([chapter,B])
E.append([p,'%s' % '\n'.join(T),ParaStyle])
for x in P:
E.append([p,' '.join(x)])
firstPre = 1
for T in ambleText(POSTAMBLE):
E.append([p,'\n'.join(T)])
t3 = time()
print("Parsing into memory took %.4f seconds" %(t3-t1))
del L
t4 = time()
print("Deleting list of lines took %.4f seconds" %(t4-t3))
for i in range(len(E)):
E[i][0](*E[i][1:])
t5 = time()
print("Moving into platypus took %.4f seconds" %(t5-t4))
del E
t6 = time()
print("Deleting list of actions took %.4f seconds" %(t6-t5))
go()
t7 = time()
print("saving to PDF took %.4f seconds" %(t7-t6))
print("Total run took %.4f seconds"%(t7-t0))
import hashlib
print('file digest: %s' % hashlib.md5(open('dodyssey.pdf','rb').read()).hexdigest())
def run():
for fn in ('odyssey.full.txt','odyssey.txt'):
if os.path.isfile(fn):
parseOdyssey(fn)
break
def doProf(profname,func,*args,**kwd):
import hotshot, hotshot.stats
prof = hotshot.Profile(profname)
prof.runcall(func)
prof.close()
stats = hotshot.stats.load(profname)
stats.strip_dirs()
stats.sort_stats('time', 'calls')
stats.print_stats(20)
if __name__=='__main__':
if '--prof' in sys.argv:
doProf('dodyssey.prof',run)
else:
run()
reportlab-3.5.34/demos/odyssey/fodyssey.py 0000664 0001750 0001750 00000010744 13544671343 021441 0 ustar rptlab rptlab 0000000 0000000 #Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__version__='3.3.0'
__doc__=''
#REPORTLAB_TEST_SCRIPT
import sys, copy, os
from reportlab.platypus import *
from reportlab.lib.units import inch
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
import reportlab.rl_config
reportlab.rl_config.invariant = 1
styles = getSampleStyleSheet()
Title = "The Odyssey"
Author = "Homer"
def myFirstPage(canvas, doc):
canvas.saveState()
canvas.restoreState()
def myLaterPages(canvas, doc):
canvas.saveState()
canvas.setFont('Times-Roman',9)
canvas.drawString(inch, 0.75 * inch, "Page %d" % doc.page)
canvas.restoreState()
def go():
doc = SimpleDocTemplate('fodyssey.pdf',showBoundary='showboundary' in sys.argv)
doc.allowSplitting = not 'nosplitting' in sys.argv
doc.build(Elements,myFirstPage,myLaterPages)
Elements = []
ChapterStyle = copy.copy(styles["Heading1"])
ChapterStyle.alignment = TA_CENTER
ChapterStyle.fontsize = 16
InitialStyle = copy.deepcopy(ChapterStyle)
InitialStyle.fontsize = 16
InitialStyle.leading = 20
PreStyle = styles["Code"]
def newPage():
Elements.append(PageBreak())
def chapter(txt, style=ChapterStyle):
newPage()
Elements.append(Paragraph(txt, style))
Elements.append(Spacer(0.2*inch, 0.3*inch))
def fTitle(txt,style=InitialStyle):
Elements.append(Paragraph(txt, style))
ParaStyle = copy.deepcopy(styles["Normal"])
ParaStyle.spaceBefore = 0.1*inch
if 'right' in sys.argv:
ParaStyle.alignment = TA_RIGHT
elif 'left' in sys.argv:
ParaStyle.alignment = TA_LEFT
elif 'justify' in sys.argv:
ParaStyle.alignment = TA_JUSTIFY
elif 'center' in sys.argv or 'centre' in sys.argv:
ParaStyle.alignment = TA_CENTER
else:
ParaStyle.alignment = TA_JUSTIFY
def spacer(inches):
Elements.append(Spacer(0.1*inch, inches*inch))
def p(txt, style=ParaStyle):
Elements.append(Paragraph(txt, style))
def pre(txt, style=PreStyle):
spacer(0.1)
p = Preformatted(txt, style)
Elements.append(p)
def parseOdyssey(fn):
from time import time
E = []
t0=time()
text = open(fn,'r').read()
i0 = text.index('Book I')
endMarker = 'covenant of peace between the two contending parties.'
i1 = text.index(endMarker)+len(endMarker)
PREAMBLE=list(map(str.strip,text[0:i0].split('\n')))
L=list(map(str.strip,text[i0:i1].split('\n')))
POSTAMBLE=list(map(str.strip,text[i1:].split('\n')))
def ambleText(L):
while L and not L[0]: L.pop(0)
while L:
T=[]
while L and L[0]:
T.append(L.pop(0))
yield T
while L and not L[0]: L.pop(0)
def mainText(L):
while L:
B = L.pop(0)
while not L[0]: L.pop(0)
T=[]
while L and L[0]:
T.append(L.pop(0))
while not L[0]: L.pop(0)
P = []
while L and not (L[0].startswith('Book ') and len(L[0].split())==2):
E=[]
while L and L[0]:
E.append(L.pop(0))
P.append(E)
if L:
while not L[0]: L.pop(0)
yield B,T,P
t1 = time()
print("open(%s,'r').read() took %.4f seconds" %(fn,t1-t0))
E.append([spacer,2])
E.append([fTitle,'%s' % Title, InitialStyle])
E.append([fTitle,'by %s' % Author, InitialStyle])
for T in ambleText(PREAMBLE):
E.append([p,'\n'.join(T)])
for (B,T,P) in mainText(L):
E.append([chapter,B])
E.append([p,'%s' % '\n'.join(T),ParaStyle])
for x in P:
E.append([p,' '.join(x)])
firstPre = 1
for T in ambleText(POSTAMBLE):
E.append([p,'\n'.join(T)])
t3 = time()
print("Parsing into memory took %.4f seconds" %(t3-t1))
del L
t4 = time()
print("Deleting list of lines took %.4f seconds" %(t4-t3))
for i in range(len(E)):
E[i][0](*E[i][1:])
t5 = time()
print("Moving into platypus took %.4f seconds" %(t5-t4))
del E
t6 = time()
print("Deleting list of actions took %.4f seconds" %(t6-t5))
go()
t7 = time()
print("saving to PDF took %.4f seconds" %(t7-t6))
print("Total run took %.4f seconds"%(t7-t0))
for fn in ('odyssey.full.txt','odyssey.txt'):
if os.path.isfile(fn):
break
if __name__=='__main__':
parseOdyssey(fn)
reportlab-3.5.34/demos/odyssey/odyssey.py 0000664 0001750 0001750 00000010353 13544671343 021267 0 ustar rptlab rptlab 0000000 0000000 #Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__version__='3.3.0'
___doc__=''
#odyssey.py
#
#Demo/benchmark of PDFgen rendering Homer's Odyssey.
#results on my humble P266 with 64MB:
# Without page compression:
# 239 pages in 3.76 seconds = 77 pages per second
# With textOut rather than textLine, i.e. computing width
# of every word as we would for wrapping:
# 239 pages in 10.83 seconds = 22 pages per second
# With page compression and textLine():
# 239 pages in 39.39 seconds = 6 pages per second
from reportlab.pdfgen import canvas
import time, os, sys
#find out what platform we are on and whether accelerator is
#present, in order to print this as part of benchmark info.
try:
import _rl_accel
ACCEL = 1
except ImportError:
ACCEL = 0
from reportlab.lib.units import inch, cm
from reportlab.lib.pagesizes import A4
#precalculate some basics
top_margin = A4[1] - inch
bottom_margin = inch
left_margin = inch
right_margin = A4[0] - inch
frame_width = right_margin - left_margin
def drawPageFrame(canv):
canv.line(left_margin, top_margin, right_margin, top_margin)
canv.setFont('Times-Italic',12)
canv.drawString(left_margin, top_margin + 2, "Homer's Odyssey")
canv.line(left_margin, top_margin, right_margin, top_margin)
canv.line(left_margin, bottom_margin, right_margin, bottom_margin)
canv.drawCentredString(0.5*A4[0], 0.5 * inch,
"Page %d" % canv.getPageNumber())
def run(verbose=1):
if sys.platform[0:4] == 'java':
impl = 'Jython'
else:
impl = 'Python'
verStr = '%d.%d' % (sys.version_info[0:2])
if ACCEL:
accelStr = 'with _rl_accel'
else:
accelStr = 'without _rl_accel'
print('Benchmark of %s %s %s' % (impl, verStr, accelStr))
started = time.time()
canv = canvas.Canvas('odyssey.pdf', invariant=1)
canv.setPageCompression(1)
drawPageFrame(canv)
#do some title page stuff
canv.setFont("Times-Bold", 36)
canv.drawCentredString(0.5 * A4[0], 7 * inch, "Homer's Odyssey")
canv.setFont("Times-Bold", 18)
canv.drawCentredString(0.5 * A4[0], 5 * inch, "Translated by Samuel Burton")
canv.setFont("Times-Bold", 12)
tx = canv.beginText(left_margin, 3 * inch)
tx.textLine("This is a demo-cum-benchmark for PDFgen. It renders the complete text of Homer's Odyssey")
tx.textLine("from a text file. On my humble P266, it does 77 pages per secondwhile creating a 238 page")
tx.textLine("document. If it is asked to computer text metrics, measuring the width of each word as ")
tx.textLine("one would for paragraph wrapping, it still manages 22 pages per second.")
tx.textLine("")
tx.textLine("Andy Robinson, Robinson Analytics Ltd.")
canv.drawText(tx)
canv.showPage()
#on with the text...
drawPageFrame(canv)
canv.setFont('Times-Roman', 12)
tx = canv.beginText(left_margin, top_margin - 0.5*inch)
for fn in ('odyssey.full.txt','odyssey.txt'):
if os.path.isfile(fn):
break
data = open(fn,'r').readlines()
for line in data:
#this just does it the fast way...
tx.textLine(line.rstrip())
#page breaking
y = tx.getY() #get y coordinate
if y < bottom_margin + 0.5*inch:
canv.drawText(tx)
canv.showPage()
drawPageFrame(canv)
canv.setFont('Times-Roman', 12)
tx = canv.beginText(left_margin, top_margin - 0.5*inch)
#page
pg = canv.getPageNumber()
if verbose and pg % 10 == 0:
print('formatted page %d' % canv.getPageNumber())
if tx:
canv.drawText(tx)
canv.showPage()
drawPageFrame(canv)
if verbose:
print('about to write to disk...')
canv.save()
finished = time.time()
elapsed = finished - started
pages = canv.getPageNumber()-1
speed = pages / elapsed
fileSize = os.stat('odyssey.pdf')[6] / 1024
print('%d pages in %0.2f seconds = %0.2f pages per second, file size %d kb' % (
pages, elapsed, speed, fileSize))
import hashlib
print('file digest: %s' % hashlib.md5(open('odyssey.pdf','rb').read()).hexdigest())
if __name__=='__main__':
quiet = ('-q' in sys.argv)
run(verbose = not quiet)
reportlab-3.5.34/demos/colors/ 0000775 0001750 0001750 00000000000 13607302651 017007 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/colors/colortest.py 0000664 0001750 0001750 00000005250 13544671343 021410 0 ustar rptlab rptlab 0000000 0000000 #Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__version__='3.3.0'
import reportlab.pdfgen.canvas
from reportlab.lib import colors
from reportlab.lib.units import inch
def run():
c = reportlab.pdfgen.canvas.Canvas('colortest.pdf')
#do a test of CMYK interspersed with RGB
#first do RGB values
framePage(c, 'Color Demo - RGB Space and CMYK spaces interspersed' )
y = 700
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'cyan')
c.setFillColorCMYK(1,0,0,0)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'red')
c.setFillColorRGB(1,0,0)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'magenta')
c.setFillColorCMYK(0,1,0,0)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'green')
c.setFillColorRGB(0,1,0)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'yellow')
c.setFillColorCMYK(0,0,1,0)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'blue')
c.setFillColorRGB(0,0,1)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.setFillColorRGB(0,0,0)
c.drawString(100, y, 'black')
c.setFillColorCMYK(0,0,0,1)
c.rect(200, y, 300, 30, fill=1)
y = y - 40
c.showPage()
#do all named colors
framePage(c, 'Color Demo - RGB Space - page %d' % c.getPageNumber())
all_colors = list(reportlab.lib.colors.getAllNamedColors().items())
all_colors.sort() # alpha order by name
c.setFont('Times-Roman', 12)
c.drawString(72,730, 'This shows all the named colors in the HTML standard.')
y = 700
for (name, color) in all_colors:
c.setFillColor(colors.black)
c.drawString(100, y, name)
c.setFillColor(color)
c.rect(200, y-10, 300, 30, fill=1)
y = y - 40
if y < 100:
c.showPage()
framePage(c, 'Color Demo - RGB Space - page %d' % c.getPageNumber())
y = 700
c.save()
def framePage(canvas, title):
canvas.setFont('Times-BoldItalic',20)
canvas.drawString(inch, 10.5 * inch, title)
canvas.setFont('Times-Roman',10)
canvas.drawCentredString(4.135 * inch, 0.75 * inch,
'Page %d' % canvas.getPageNumber())
#draw a border
canvas.setStrokeColorRGB(1,0,0)
canvas.setLineWidth(5)
canvas.line(0.8 * inch, inch, 0.8 * inch, 10.75 * inch)
#reset carefully afterwards
canvas.setLineWidth(1)
canvas.setStrokeColorRGB(0,0,0)
if __name__ == '__main__':
run()
reportlab-3.5.34/demos/tests/ 0000775 0001750 0001750 00000000000 13607302651 016650 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/demos/tests/testdemos.py 0000664 0001750 0001750 00000001015 13544671343 021235 0 ustar rptlab rptlab 0000000 0000000 #!/bin/env python
#Copyright ReportLab Europe Ltd. 2000-2017
#see license.txt for license details
__doc__='Test all demos'
__version__='3.3.0'
_globals=globals().copy()
import os, sys
from reportlab import pdfgen
for p in ('pythonpoint/pythonpoint.py','stdfonts/stdfonts.py','odyssey/odyssey.py', 'gadflypaper/gfe.py'):
fn = os.path.normcase(os.path.normpath(os.path.join(os.path.dirname(pdfgen.__file__),'..','demos',p)))
os.chdir(os.path.dirname(fn))
exec(compile(open(fn).read(), fn, 'exec'),_globals.copy())
reportlab-3.5.34/src/ 0000775 0001750 0001750 00000000000 13607302651 015166 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/src/reportlab.egg-info/ 0000775 0001750 0001750 00000000000 13607302651 020652 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/src/reportlab.egg-info/SOURCES.txt 0000664 0001750 0001750 00000045220 13607302651 022541 0 ustar rptlab rptlab 0000000 0000000 .appveyor.yml
.travis.yml
CHANGES.md
INSTALL.txt
LICENSE.txt
MANIFEST.in
README.txt
VERSION.txt
setup.cfg
setup.py
demos/colors/colortest.py
demos/gadflypaper/00readme.txt
demos/gadflypaper/gfe.py
demos/odyssey/00readme.txt
demos/odyssey/dodyssey.py
demos/odyssey/fodyssey.py
demos/odyssey/odyssey.py
demos/odyssey/odyssey.txt
demos/rlzope/readme.txt
demos/rlzope/rlzope.py
demos/stdfonts/00readme.txt
demos/stdfonts/stdfonts.py
demos/tests/testdemos.py
docs/00readme.txt
docs/Makefile
docs/genAll.py
docs/gen_epydoc
docs/make.bat
docs/images/Edit_Prefs.gif
docs/images/Python_21.gif
docs/images/Python_21_HINT.gif
docs/images/fileExchange.gif
docs/images/jpn.gif
docs/images/jpnchars.jpg
docs/images/lj8100.jpg
docs/images/redsquare.png
docs/images/replogo.a85
docs/images/replogo.gif
docs/images/testimg.gif
docs/reference/build.bat
docs/reference/genreference.py
docs/reference/reference.yml
docs/source/conf.py
docs/source/graphics.rst
docs/source/index.rst
docs/source/lib.rst
docs/source/pdfgen.rst
docs/source/platypus.rst
docs/source/_static/basic.css
docs/source/_static/default.css
docs/source/_templates/layout.html
docs/source/_templates/page.html
docs/userguide/app_demos.py
docs/userguide/ch1_intro.py
docs/userguide/ch2_graphics.py
docs/userguide/ch2a_fonts.py
docs/userguide/ch3_pdffeatures.py
docs/userguide/ch4_platypus_concepts.py
docs/userguide/ch5_paragraphs.py
docs/userguide/ch6_tables.py
docs/userguide/ch7_custom.py
docs/userguide/genuserguide.py
docs/userguide/graph_charts.py
docs/userguide/graph_concepts.py
docs/userguide/graph_intro.py
docs/userguide/graph_shapes.py
docs/userguide/graph_widgets.py
docs/userguide/testfile.txt
src/reportlab/MANIFEST.in
src/reportlab/__init__.py
src/reportlab/license.txt
src/reportlab/rl_config.py
src/reportlab/rl_settings.py
src/reportlab.egg-info/PKG-INFO
src/reportlab.egg-info/SOURCES.txt
src/reportlab.egg-info/dependency_links.txt
src/reportlab.egg-info/requires.txt
src/reportlab.egg-info/top_level.txt
src/reportlab/fonts/00readme.txt
src/reportlab/fonts/DarkGarden-changelog.txt
src/reportlab/fonts/DarkGarden-copying-gpl.txt
src/reportlab/fonts/DarkGarden-copying.txt
src/reportlab/fonts/DarkGarden-readme.txt
src/reportlab/fonts/DarkGarden.sfd
src/reportlab/fonts/DarkGardenMK.afm
src/reportlab/fonts/DarkGardenMK.pfb
src/reportlab/fonts/Vera.ttf
src/reportlab/fonts/VeraBI.ttf
src/reportlab/fonts/VeraBd.ttf
src/reportlab/fonts/VeraIt.ttf
src/reportlab/fonts/_a______.pfb
src/reportlab/fonts/_ab_____.pfb
src/reportlab/fonts/_abi____.pfb
src/reportlab/fonts/_ai_____.pfb
src/reportlab/fonts/_eb_____.pfb
src/reportlab/fonts/_ebi____.pfb
src/reportlab/fonts/_ei_____.pfb
src/reportlab/fonts/_er_____.pfb
src/reportlab/fonts/bitstream-vera-license.txt
src/reportlab/fonts/callig15.afm
src/reportlab/fonts/callig15.pfb
src/reportlab/fonts/cob_____.pfb
src/reportlab/fonts/cobo____.pfb
src/reportlab/fonts/com_____.pfb
src/reportlab/fonts/coo_____.pfb
src/reportlab/fonts/sy______.pfb
src/reportlab/fonts/zd______.pfb
src/reportlab/fonts/zx______.pfb
src/reportlab/fonts/zy______.pfb
src/reportlab/graphics/__init__.py
src/reportlab/graphics/renderPDF.py
src/reportlab/graphics/renderPM.py
src/reportlab/graphics/renderPS.py
src/reportlab/graphics/renderSVG.py
src/reportlab/graphics/renderbase.py
src/reportlab/graphics/shapes.py
src/reportlab/graphics/testdrawings.py
src/reportlab/graphics/testshapes.py
src/reportlab/graphics/widgetbase.py
src/reportlab/graphics/barcode/README
src/reportlab/graphics/barcode/TODO
src/reportlab/graphics/barcode/__init__.py
src/reportlab/graphics/barcode/code128.py
src/reportlab/graphics/barcode/code39.py
src/reportlab/graphics/barcode/code93.py
src/reportlab/graphics/barcode/common.py
src/reportlab/graphics/barcode/eanbc.py
src/reportlab/graphics/barcode/ecc200datamatrix.py
src/reportlab/graphics/barcode/fourstate.py
src/reportlab/graphics/barcode/lto.py
src/reportlab/graphics/barcode/qr.py
src/reportlab/graphics/barcode/qrencoder.py
src/reportlab/graphics/barcode/test.py
src/reportlab/graphics/barcode/usps.py
src/reportlab/graphics/barcode/usps4s.py
src/reportlab/graphics/barcode/widgets.py
src/reportlab/graphics/charts/__init__.py
src/reportlab/graphics/charts/areas.py
src/reportlab/graphics/charts/axes.py
src/reportlab/graphics/charts/barcharts.py
src/reportlab/graphics/charts/dotbox.py
src/reportlab/graphics/charts/doughnut.py
src/reportlab/graphics/charts/legends.py
src/reportlab/graphics/charts/linecharts.py
src/reportlab/graphics/charts/lineplots.py
src/reportlab/graphics/charts/markers.py
src/reportlab/graphics/charts/piecharts.py
src/reportlab/graphics/charts/slidebox.py
src/reportlab/graphics/charts/spider.py
src/reportlab/graphics/charts/textlabels.py
src/reportlab/graphics/charts/utils.py
src/reportlab/graphics/charts/utils3d.py
src/reportlab/graphics/samples/__init__.py
src/reportlab/graphics/samples/bubble.py
src/reportlab/graphics/samples/clustered_bar.py
src/reportlab/graphics/samples/clustered_column.py
src/reportlab/graphics/samples/excelcolors.py
src/reportlab/graphics/samples/exploded_pie.py
src/reportlab/graphics/samples/filled_radar.py
src/reportlab/graphics/samples/line_chart.py
src/reportlab/graphics/samples/linechart_with_markers.py
src/reportlab/graphics/samples/radar.py
src/reportlab/graphics/samples/runall.py
src/reportlab/graphics/samples/scatter.py
src/reportlab/graphics/samples/scatter_lines.py
src/reportlab/graphics/samples/scatter_lines_markers.py
src/reportlab/graphics/samples/simple_pie.py
src/reportlab/graphics/samples/stacked_bar.py
src/reportlab/graphics/samples/stacked_column.py
src/reportlab/graphics/widgets/__init__.py
src/reportlab/graphics/widgets/eventcal.py
src/reportlab/graphics/widgets/flags.py
src/reportlab/graphics/widgets/grids.py
src/reportlab/graphics/widgets/markers.py
src/reportlab/graphics/widgets/signsandsymbols.py
src/reportlab/graphics/widgets/table.py
src/reportlab/lib/PyFontify.py
src/reportlab/lib/__init__.py
src/reportlab/lib/abag.py
src/reportlab/lib/arciv.py
src/reportlab/lib/attrmap.py
src/reportlab/lib/boxstuff.py
src/reportlab/lib/codecharts.py
src/reportlab/lib/colors.py
src/reportlab/lib/corp.py
src/reportlab/lib/enums.py
src/reportlab/lib/extformat.py
src/reportlab/lib/fontfinder.py
src/reportlab/lib/fonts.py
src/reportlab/lib/formatters.py
src/reportlab/lib/geomutils.py
src/reportlab/lib/hyphen.mashed
src/reportlab/lib/logger.py
src/reportlab/lib/normalDate.py
src/reportlab/lib/pagesizes.py
src/reportlab/lib/pdfencrypt.py
src/reportlab/lib/pygments2xpre.py
src/reportlab/lib/randomtext.py
src/reportlab/lib/rl_accel.py
src/reportlab/lib/rl_safe_eval.py
src/reportlab/lib/rltempfile.py
src/reportlab/lib/rparsexml.py
src/reportlab/lib/sequencer.py
src/reportlab/lib/styles.py
src/reportlab/lib/testutils.py
src/reportlab/lib/textsplit.py
src/reportlab/lib/units.py
src/reportlab/lib/utils.py
src/reportlab/lib/validators.py
src/reportlab/lib/yaml.py
src/reportlab/pdfbase/__init__.py
src/reportlab/pdfbase/_can_cmap_data.py
src/reportlab/pdfbase/_cidfontdata.py
src/reportlab/pdfbase/_fontdata.py
src/reportlab/pdfbase/_fontdata_enc_macexpert.py
src/reportlab/pdfbase/_fontdata_enc_macroman.py
src/reportlab/pdfbase/_fontdata_enc_pdfdoc.py
src/reportlab/pdfbase/_fontdata_enc_standard.py
src/reportlab/pdfbase/_fontdata_enc_symbol.py
src/reportlab/pdfbase/_fontdata_enc_winansi.py
src/reportlab/pdfbase/_fontdata_enc_zapfdingbats.py
src/reportlab/pdfbase/_fontdata_widths_courier.py
src/reportlab/pdfbase/_fontdata_widths_courierbold.py
src/reportlab/pdfbase/_fontdata_widths_courierboldoblique.py
src/reportlab/pdfbase/_fontdata_widths_courieroblique.py
src/reportlab/pdfbase/_fontdata_widths_helvetica.py
src/reportlab/pdfbase/_fontdata_widths_helveticabold.py
src/reportlab/pdfbase/_fontdata_widths_helveticaboldoblique.py
src/reportlab/pdfbase/_fontdata_widths_helveticaoblique.py
src/reportlab/pdfbase/_fontdata_widths_symbol.py
src/reportlab/pdfbase/_fontdata_widths_timesbold.py
src/reportlab/pdfbase/_fontdata_widths_timesbolditalic.py
src/reportlab/pdfbase/_fontdata_widths_timesitalic.py
src/reportlab/pdfbase/_fontdata_widths_timesroman.py
src/reportlab/pdfbase/_fontdata_widths_zapfdingbats.py
src/reportlab/pdfbase/_glyphlist.py
src/reportlab/pdfbase/acroform.py
src/reportlab/pdfbase/cidfonts.py
src/reportlab/pdfbase/pdfdoc.py
src/reportlab/pdfbase/pdfform.py
src/reportlab/pdfbase/pdfmetrics.py
src/reportlab/pdfbase/pdfpattern.py
src/reportlab/pdfbase/pdfutils.py
src/reportlab/pdfbase/rl_codecs.py
src/reportlab/pdfbase/ttfonts.py
src/reportlab/pdfgen/__init__.py
src/reportlab/pdfgen/canvas.py
src/reportlab/pdfgen/pathobject.py
src/reportlab/pdfgen/pdfgeom.py
src/reportlab/pdfgen/pdfimages.py
src/reportlab/pdfgen/textobject.py
src/reportlab/platypus/__init__.py
src/reportlab/platypus/doctemplate.py
src/reportlab/platypus/figures.py
src/reportlab/platypus/flowables.py
src/reportlab/platypus/frames.py
src/reportlab/platypus/multicol.py
src/reportlab/platypus/para.py
src/reportlab/platypus/paragraph.py
src/reportlab/platypus/paraparser.py
src/reportlab/platypus/tableofcontents.py
src/reportlab/platypus/tables.py
src/reportlab/platypus/xpreformatted.py
src/rl_addons/README
src/rl_addons/renderPM/_renderPM.c
src/rl_addons/renderPM/pfm.py
src/rl_addons/renderPM/test_renderPM.py
src/rl_addons/renderPM/tr.py
src/rl_addons/renderPM/gt1/gt1-dict.c
src/rl_addons/renderPM/gt1/gt1-dict.h
src/rl_addons/renderPM/gt1/gt1-misc.h
src/rl_addons/renderPM/gt1/gt1-namecontext.c
src/rl_addons/renderPM/gt1/gt1-namecontext.h
src/rl_addons/renderPM/gt1/gt1-parset1.c
src/rl_addons/renderPM/gt1/gt1-parset1.h
src/rl_addons/renderPM/gt1/gt1-region.c
src/rl_addons/renderPM/gt1/gt1-region.h
src/rl_addons/renderPM/gt1/gt1-value.h
src/rl_addons/renderPM/gt1/parseAFM.c
src/rl_addons/renderPM/gt1/parseAFM.h
src/rl_addons/renderPM/libart_lgpl/AUTHORS
src/rl_addons/renderPM/libart_lgpl/COPYING
src/rl_addons/renderPM/libart_lgpl/ChangeLog
src/rl_addons/renderPM/libart_lgpl/Makefile.am
src/rl_addons/renderPM/libart_lgpl/NEWS
src/rl_addons/renderPM/libart_lgpl/README
src/rl_addons/renderPM/libart_lgpl/README.CVS
src/rl_addons/renderPM/libart_lgpl/acconfig.h
src/rl_addons/renderPM/libart_lgpl/art_affine.c
src/rl_addons/renderPM/libart_lgpl/art_affine.h
src/rl_addons/renderPM/libart_lgpl/art_alphagamma.c
src/rl_addons/renderPM/libart_lgpl/art_alphagamma.h
src/rl_addons/renderPM/libart_lgpl/art_bpath.c
src/rl_addons/renderPM/libart_lgpl/art_bpath.h
src/rl_addons/renderPM/libart_lgpl/art_config.h
src/rl_addons/renderPM/libart_lgpl/art_filterlevel.h
src/rl_addons/renderPM/libart_lgpl/art_gray_svp.c
src/rl_addons/renderPM/libart_lgpl/art_gray_svp.h
src/rl_addons/renderPM/libart_lgpl/art_misc.c
src/rl_addons/renderPM/libart_lgpl/art_misc.h
src/rl_addons/renderPM/libart_lgpl/art_pathcode.h
src/rl_addons/renderPM/libart_lgpl/art_pixbuf.c
src/rl_addons/renderPM/libart_lgpl/art_pixbuf.h
src/rl_addons/renderPM/libart_lgpl/art_point.h
src/rl_addons/renderPM/libart_lgpl/art_rect.c
src/rl_addons/renderPM/libart_lgpl/art_rect.h
src/rl_addons/renderPM/libart_lgpl/art_rect_svp.c
src/rl_addons/renderPM/libart_lgpl/art_rect_svp.h
src/rl_addons/renderPM/libart_lgpl/art_rect_uta.c
src/rl_addons/renderPM/libart_lgpl/art_rect_uta.h
src/rl_addons/renderPM/libart_lgpl/art_render.c
src/rl_addons/renderPM/libart_lgpl/art_render.h
src/rl_addons/renderPM/libart_lgpl/art_render_gradient.c
src/rl_addons/renderPM/libart_lgpl/art_render_gradient.h
src/rl_addons/renderPM/libart_lgpl/art_render_mask.c
src/rl_addons/renderPM/libart_lgpl/art_render_mask.h
src/rl_addons/renderPM/libart_lgpl/art_render_svp.c
src/rl_addons/renderPM/libart_lgpl/art_render_svp.h
src/rl_addons/renderPM/libart_lgpl/art_rgb.c
src/rl_addons/renderPM/libart_lgpl/art_rgb.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_a_affine.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_a_affine.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_affine.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_affine.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_affine_private.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_affine_private.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_bitmap_affine.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_bitmap_affine.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_pixbuf_affine.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_pixbuf_affine.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_rgba_affine.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_rgba_affine.h
src/rl_addons/renderPM/libart_lgpl/art_rgb_svp.c
src/rl_addons/renderPM/libart_lgpl/art_rgb_svp.h
src/rl_addons/renderPM/libart_lgpl/art_rgba.c
src/rl_addons/renderPM/libart_lgpl/art_rgba.h
src/rl_addons/renderPM/libart_lgpl/art_svp.c
src/rl_addons/renderPM/libart_lgpl/art_svp.h
src/rl_addons/renderPM/libart_lgpl/art_svp_intersect.c
src/rl_addons/renderPM/libart_lgpl/art_svp_intersect.h
src/rl_addons/renderPM/libart_lgpl/art_svp_ops.c
src/rl_addons/renderPM/libart_lgpl/art_svp_ops.h
src/rl_addons/renderPM/libart_lgpl/art_svp_point.c
src/rl_addons/renderPM/libart_lgpl/art_svp_point.h
src/rl_addons/renderPM/libart_lgpl/art_svp_render_aa.c
src/rl_addons/renderPM/libart_lgpl/art_svp_render_aa.h
src/rl_addons/renderPM/libart_lgpl/art_svp_vpath.c
src/rl_addons/renderPM/libart_lgpl/art_svp_vpath.h
src/rl_addons/renderPM/libart_lgpl/art_svp_vpath_stroke.c
src/rl_addons/renderPM/libart_lgpl/art_svp_vpath_stroke.h
src/rl_addons/renderPM/libart_lgpl/art_svp_wind.c
src/rl_addons/renderPM/libart_lgpl/art_svp_wind.h
src/rl_addons/renderPM/libart_lgpl/art_uta.c
src/rl_addons/renderPM/libart_lgpl/art_uta.h
src/rl_addons/renderPM/libart_lgpl/art_uta_ops.c
src/rl_addons/renderPM/libart_lgpl/art_uta_ops.h
src/rl_addons/renderPM/libart_lgpl/art_uta_rect.c
src/rl_addons/renderPM/libart_lgpl/art_uta_rect.h
src/rl_addons/renderPM/libart_lgpl/art_uta_svp.c
src/rl_addons/renderPM/libart_lgpl/art_uta_svp.h
src/rl_addons/renderPM/libart_lgpl/art_uta_vpath.c
src/rl_addons/renderPM/libart_lgpl/art_uta_vpath.h
src/rl_addons/renderPM/libart_lgpl/art_vpath.c
src/rl_addons/renderPM/libart_lgpl/art_vpath.h
src/rl_addons/renderPM/libart_lgpl/art_vpath_bpath.c
src/rl_addons/renderPM/libart_lgpl/art_vpath_bpath.h
src/rl_addons/renderPM/libart_lgpl/art_vpath_dash.c
src/rl_addons/renderPM/libart_lgpl/art_vpath_dash.h
src/rl_addons/renderPM/libart_lgpl/art_vpath_svp.c
src/rl_addons/renderPM/libart_lgpl/art_vpath_svp.h
src/rl_addons/renderPM/libart_lgpl/autogen.sh
src/rl_addons/renderPM/libart_lgpl/config.h
src/rl_addons/renderPM/libart_lgpl/configure.in
src/rl_addons/renderPM/libart_lgpl/gen_art_config.c
src/rl_addons/renderPM/libart_lgpl/libart-2.0.pc.in
src/rl_addons/renderPM/libart_lgpl/libart-config.in
src/rl_addons/renderPM/libart_lgpl/libart-features.c
src/rl_addons/renderPM/libart_lgpl/libart-features.h.in
src/rl_addons/renderPM/libart_lgpl/libart.h
src/rl_addons/renderPM/libart_lgpl/libart.m4
src/rl_addons/renderPM/libart_lgpl/libartConf.sh.in
src/rl_addons/renderPM/libart_lgpl/test_gradient.c
src/rl_addons/renderPM/libart_lgpl/testart.c
src/rl_addons/renderPM/libart_lgpl/testuta.c
src/rl_addons/rl_accel/README.extensions
src/rl_addons/rl_accel/_rl_accel.c
src/rl_addons/rl_accel/_rl_accel.java
src/rl_addons/rl_accel/hnjalloc.c
src/rl_addons/rl_accel/hnjalloc.h
src/rl_addons/rl_accel/hyphen.c
src/rl_addons/rl_accel/hyphen.h
src/rl_addons/rl_accel/hyphen.mashed
src/rl_addons/rl_accel/pyHnjmodule.c
src/rl_addons/rl_accel/tests/getrc.py
src/rl_addons/rl_accel/tests/t0.py
src/rl_addons/rl_accel/tests/t1.py
src/rl_addons/rl_accel/tests/t2.py
src/rl_addons/rl_accel/tests/t3.py
src/rl_addons/rl_accel/tests/t4.py
src/rl_addons/rl_accel/tests/t5.py
tests/00readme.txt
tests/__init__.py
tests/alpha_test.png
tests/gray-alpha.png
tests/pythonpowered-gs.gif
tests/pythonpowered.gif
tests/rltw-icon-tr.png
tests/runAll.py
tests/solid_red_alpha.png
tests/tall_red.png
tests/test-cross.tiff
tests/test-indexed.png
tests/test-rgba.png
tests/test_charts_textlabels.py
tests/test_crypto_algorithms.py
tests/test_docs_build.py
tests/test_docstrings.py
tests/test_extra.py
tests/test_geomutils.py
tests/test_graphics_barcode.py
tests/test_graphics_charts.py
tests/test_graphics_images.py
tests/test_graphics_layout.py
tests/test_graphics_render.py
tests/test_graphics_speed.py
tests/test_hello.py
tests/test_images.py
tests/test_invariant.py
tests/test_issues.py
tests/test_lib_colors.py
tests/test_lib_normaldate.py
tests/test_lib_pdfencrypt.py
tests/test_lib_rl_safe_eval.py
tests/test_lib_sequencer.py
tests/test_lib_utils.py
tests/test_lib_validators.py
tests/test_multibyte_chs.py
tests/test_multibyte_cht.py
tests/test_multibyte_jpn.py
tests/test_multibyte_kor.py
tests/test_paragraphs.py
tests/test_pdfbase_encodings.py
tests/test_pdfbase_fontembed.py
tests/test_pdfbase_pdfdoc.py
tests/test_pdfbase_pdfform.py
tests/test_pdfbase_pdfmetrics.py
tests/test_pdfbase_pdfutils.py
tests/test_pdfbase_postscript.py
tests/test_pdfbase_ttfonts.py
tests/test_pdfgen_callback.py
tests/test_pdfgen_general.py
tests/test_pdfgen_links.py
tests/test_pdfgen_overprint.py
tests/test_pdfgen_pagemodes.py
tests/test_platypus_accum.py
tests/test_platypus_breaking.py
tests/test_platypus_cjk_wrap.py
tests/test_platypus_general.py
tests/test_platypus_images.py
tests/test_platypus_indents.py
tests/test_platypus_index.py
tests/test_platypus_leftright.py
tests/test_platypus_lists.py
tests/test_platypus_paragraphs.py
tests/test_platypus_paraparser.py
tests/test_platypus_pleaseturnover.py
tests/test_platypus_preformatted.py
tests/test_platypus_programming.py
tests/test_platypus_tables.py
tests/test_platypus_toc.py
tests/test_platypus_wrapping.py
tests/test_platypus_xref.py
tests/test_pyfiles.py
tests/test_renderPS.py
tests/test_renderSVG.py
tests/test_rl_accel.py
tests/test_source_chars.py
tests/test_table_layout.py
tests/test_tools_pythonpoint.py
tests/test_utils.py
tests/test_widgetbase_tpc.py
tests/test_widgets_grids.py
tests/unimportable.py
tools/README
tools/__init__.py
tools/docco/README
tools/docco/__init__.py
tools/docco/codegrab.py
tools/docco/docpy.py
tools/docco/examples.py
tools/docco/graphdocpy.py
tools/docco/rl_doc_utils.py
tools/docco/rltemplate.py
tools/docco/stylesheet.py
tools/docco/t_parse.py
tools/docco/yaml.py
tools/docco/yaml2pdf.py
tools/pythonpoint/README
tools/pythonpoint/__init__.py
tools/pythonpoint/customshapes.py
tools/pythonpoint/pythonpoint.dtd
tools/pythonpoint/pythonpoint.py
tools/pythonpoint/stdparser.py
tools/pythonpoint/demos/examples.py
tools/pythonpoint/demos/figures.xml
tools/pythonpoint/demos/htu.xml
tools/pythonpoint/demos/leftlogo.a85
tools/pythonpoint/demos/leftlogo.gif
tools/pythonpoint/demos/lj8100.jpg
tools/pythonpoint/demos/monterey.xml
tools/pythonpoint/demos/outline.gif
tools/pythonpoint/demos/pplogo.gif
tools/pythonpoint/demos/python.gif
tools/pythonpoint/demos/pythonpoint.xml
tools/pythonpoint/demos/slidebox.py
tools/pythonpoint/demos/spectrum.png
tools/pythonpoint/demos/vertpython.gif
tools/pythonpoint/styles/__init__.py
tools/pythonpoint/styles/horrible.py
tools/pythonpoint/styles/htu.py
tools/pythonpoint/styles/modern.py
tools/pythonpoint/styles/projection.py
tools/pythonpoint/styles/standard.py
tools/utils/add_bleed.py
tools/utils/dumpttf.py reportlab-3.5.34/src/reportlab.egg-info/dependency_links.txt 0000664 0001750 0001750 00000000001 13607302651 024720 0 ustar rptlab rptlab 0000000 0000000
reportlab-3.5.34/src/reportlab.egg-info/requires.txt 0000664 0001750 0001750 00000000016 13607302651 023247 0 ustar rptlab rptlab 0000000 0000000 pillow>=4.0.0
reportlab-3.5.34/src/reportlab.egg-info/top_level.txt 0000664 0001750 0001750 00000000012 13607302651 023375 0 ustar rptlab rptlab 0000000 0000000 reportlab
reportlab-3.5.34/src/reportlab.egg-info/PKG-INFO 0000664 0001750 0001750 00000002007 13607302651 021746 0 ustar rptlab rptlab 0000000 0000000 Metadata-Version: 1.1
Name: reportlab
Version: 3.5.34
Summary: The Reportlab Toolkit
Home-page: http://www.reportlab.com/
Author: Andy Robinson, Robin Becker, the ReportLab team and the community
Author-email: reportlab-users@lists2.reportlab.com
License: BSD license (see license.txt for details), Copyright (c) 2000-2018, ReportLab Inc.
Description: The ReportLab Toolkit. An Open Source Python library for generating PDFs and graphics.
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Topic :: Printing
Classifier: Topic :: Text Processing :: Markup
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
reportlab-3.5.34/src/reportlab/ 0000775 0001750 0001750 00000000000 13607302651 017160 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/src/reportlab/fonts/ 0000775 0001750 0001750 00000000000 13607302651 020311 5 ustar rptlab rptlab 0000000 0000000 reportlab-3.5.34/src/reportlab/fonts/zd______.pfb 0000664 0001750 0001750 00000140671 13607302650 022521 0 ustar rptlab rptlab 0000000 0000000 €K %!PS-AdobeFont-1.0: ZapfDingbats 002.000
%%CreationDate: Thu May 1 15:14:10 1997
%%VMusage: 45775 55535
%% ITC Zapf Dingbats is a registered trademark of International Typeface
%% Corporation.
11 dict begin
/FontInfo 10 dict dup begin
/version (002.000) readonly def
/Notice (Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.) readonly def
/FullName (ITC Zapf Dingbats) readonly def
/FamilyName (ITC Zapf Dingbats) readonly def
/Weight (Medium) readonly def
/isFixedPitch false def
/ItalicAngle 0 def
/UnderlinePosition -100 def
/UnderlineThickness 50 def
end readonly def
/FontName /ZapfDingbats def
/Encoding 256 array
0 1 255 {1 index exch /.notdef put} for
dup 32 /space put
dup 33 /a1 put
dup 34 /a2 put
dup 35 /a202 put
dup 36 /a3 put
dup 37 /a4 put
dup 38 /a5 put
dup 39 /a119 put
dup 40 /a118 put
dup 41 /a117 put
dup 42 /a11 put
dup 43 /a12 put
dup 44 /a13 put
dup 45 /a14 put
dup 46 /a15 put
dup 47 /a16 put
dup 48 /a105 put
dup 49 /a17 put
dup 50 /a18 put
dup 51 /a19 put
dup 52 /a20 put
dup 53 /a21 put
dup 54 /a22 put
dup 55 /a23 put
dup 56 /a24 put
dup 57 /a25 put
dup 58 /a26 put
dup 59 /a27 put
dup 60 /a28 put
dup 61 /a6 put
dup 62 /a7 put
dup 63 /a8 put
dup 64 /a9 put
dup 65 /a10 put
dup 66 /a29 put
dup 67 /a30 put
dup 68 /a31 put
dup 69 /a32 put
dup 70 /a33 put
dup 71 /a34 put
dup 72 /a35 put
dup 73 /a36 put
dup 74 /a37 put
dup 75 /a38 put
dup 76 /a39 put
dup 77 /a40 put
dup 78 /a41 put
dup 79 /a42 put
dup 80 /a43 put
dup 81 /a44 put
dup 82 /a45 put
dup 83 /a46 put
dup 84 /a47 put
dup 85 /a48 put
dup 86 /a49 put
dup 87 /a50 put
dup 88 /a51 put
dup 89 /a52 put
dup 90 /a53 put
dup 91 /a54 put
dup 92 /a55 put
dup 93 /a56 put
dup 94 /a57 put
dup 95 /a58 put
dup 96 /a59 put
dup 97 /a60 put
dup 98 /a61 put
dup 99 /a62 put
dup 100 /a63 put
dup 101 /a64 put
dup 102 /a65 put
dup 103 /a66 put
dup 104 /a67 put
dup 105 /a68 put
dup 106 /a69 put
dup 107 /a70 put
dup 108 /a71 put
dup 109 /a72 put
dup 110 /a73 put
dup 111 /a74 put
dup 112 /a203 put
dup 113 /a75 put
dup 114 /a204 put
dup 115 /a76 put
dup 116 /a77 put
dup 117 /a78 put
dup 118 /a79 put
dup 119 /a81 put
dup 120 /a82 put
dup 121 /a83 put
dup 122 /a84 put
dup 123 /a97 put
dup 124 /a98 put
dup 125 /a99 put
dup 126 /a100 put
dup 128 /a89 put
dup 129 /a90 put
dup 130 /a93 put
dup 131 /a94 put
dup 132 /a91 put
dup 133 /a92 put
dup 134 /a205 put
dup 135 /a85 put
dup 136 /a206 put
dup 137 /a86 put
dup 138 /a87 put
dup 139 /a88 put
dup 140 /a95 put
dup 141 /a96 put
dup 161 /a101 put
dup 162 /a102 put
dup 163 /a103 put
dup 164 /a104 put
dup 165 /a106 put
dup 166 /a107 put
dup 167 /a108 put
dup 168 /a112 put
dup 169 /a111 put
dup 170 /a110 put
dup 171 /a109 put
dup 172 /a120 put
dup 173 /a121 put
dup 174 /a122 put
dup 175 /a123 put
dup 176 /a124 put
dup 177 /a125 put
dup 178 /a126 put
dup 179 /a127 put
dup 180 /a128 put
dup 181 /a129 put
dup 182 /a130 put
dup 183 /a131 put
dup 184 /a132 put
dup 185 /a133 put
dup 186 /a134 put
dup 187 /a135 put
dup 188 /a136 put
dup 189 /a137 put
dup 190 /a138 put
dup 191 /a139 put
dup 192 /a140 put
dup 193 /a141 put
dup 194 /a142 put
dup 195 /a143 put
dup 196 /a144 put
dup 197 /a145 put
dup 198 /a146 put
dup 199 /a147 put
dup 200 /a148 put
dup 201 /a149 put
dup 202 /a150 put
dup 203 /a151 put
dup 204 /a152 put
dup 205 /a153 put
dup 206 /a154 put
dup 207 /a155 put
dup 208 /a156 put
dup 209 /a157 put
dup 210 /a158 put
dup 211 /a159 put
dup 212 /a160 put
dup 213 /a161 put
dup 214 /a163 put
dup 215 /a164 put
dup 216 /a196 put
dup 217 /a165 put
dup 218 /a192 put
dup 219 /a166 put
dup 220 /a167 put
dup 221 /a168 put
dup 222 /a169 put
dup 223 /a170 put
dup 224 /a171 put
dup 225 /a172 put
dup 226 /a173 put
dup 227 /a162 put
dup 228 /a174 put
dup 229 /a175 put
dup 230 /a176 put
dup 231 /a177 put
dup 232 /a178 put
dup 233 /a179 put
dup 234 /a193 put
dup 235 /a180 put
dup 236 /a199 put
dup 237 /a181 put
dup 238 /a200 put
dup 239 /a182 put
dup 241 /a201 put
dup 242 /a183 put
dup 243 /a184 put
dup 244 /a197 put
dup 245 /a185 put
dup 246 /a194 put
dup 247 /a198 put
dup 248 /a186 put
dup 249 /a195 put
dup 250 /a187 put
dup 251 /a188 put
dup 252 /a189 put
dup 253 /a190 put
dup 254 /a191 put
readonly def
/PaintType 0 def
/FontType 1 def
/FontMatrix [0.001 0 0 0.001 0 0] def
/UniqueID 43082 def
/FontBBox{-1 -143 981 820}readonly def
currentdict end
currentfile eexec
€F® F^#ÿ‚Íß¡Ý}ŠþX(ÍxWhãç#ök{ņºí4X^Ár”è–ZúÆ{—ÁK«Vö_-IÆ<Ñ åBçJPË,*¯•NC=Þ BŽGª¼øÀs§M"û^¦ˆ5ó'Th\.°èD/±D[ÊW¯ªÑ8õ‰Cw¬Ë÷<ÿ3eã†u˜àÁ*;é0°þC•ò…"3"è£çKìê1Tõ°Îî£5Iü:—>þ${•¹ŽŸœÃ I|¨n_«ø4{•¯L\rÉ·9ª·š§’Í.µÈÀý‹h1¾e¹v%A6±ª3n˯ñŽ‹œß¯½d•6o¹e/ÖhÞ“„µ/²#4AxrS£@Šë¢P”HxŸKñ×Ã%$ ÛiPWÐ8»-ûô´ V׿ÐÊs›ÌQã²›-péYÓ§âÆ%w %2Á«
EÎäöº— †sþŽ2É÷Ïh:¶øüZNµKF1HÓ¡×ògáµK³M]%3/hi¼7ndÀZ{|[gņ¨¨,cåîr€¢”ëVlfÒ³#k(Ï'xÜDRunq,¹Îȱ!ÛæÇˆŽ‡H†”LªAV#¥ç$t#îZцM¾EÛi%ûáXÿüS³†Ù¸œ}ý„L¾dé.žr¬8æÒÒß`ݪ(ƒT.HJ Ìÿ¡K…à ‚:~Ly(ðÝ@è¶F>¤›ùØÏ?Qã´¸eñ9r ®ö¢Ê]Ž7u%¶ò»ÝNüòýC¢qþk2Œ²×^8ÕqKAEÞF2(É›c9ˆ®<χ¤-2p’Ý|£Æ‰Ë¸ÿïØ"TÐù\‘˨ö± Y4ÉÞÕɤŠÃä5³QÛT
/¥ž¸¨Èa@WœC±¡1™øSFn’Láëåc3l³– õy*‰%‘u`@ª¬ rËÝC‚^Ú3‰-Š<úB"oŽ2F&Ó…‰+ìì.ÒŽ’ÆéëV¨ÖòÃy2§”¼‹YÆã‹†žç¥7Vf«" C«_™FakôæØH{ØÖ(·™¢Â‡®–Ø‚{Ž™´°¦J¾.%у¿ìOî©Í«ºýä|Æ•ZTLžì¯¢Ô8üN;š˜L¡CûÂì Õ‘'çLžíξæÞ´®³²QP4D†S>Rt ±DM`€ÙOs8ø´Sñ)'¹æÚJÁõñ#˜¿¤Ë„,q™„¸â‚J´G*ulh®ü¥Às9ƒ(àYܰ«ñ“K*ÉÍÐPšÉšÒMÄA'ö° d¿%¤‰8#4ÿƹvJþçsG(ø´}rInL¸Å°\Ü d“ª¾ÈÓ¨Sß{]^è½HQ+9šÖe•ù
é_ÞV`,
ž©NP4
[ýƒ
)Ûå2°7²f´ÔIñ%ñºaª¿Ãuîv™²Šz1³6Ã