summaryrefslogtreecommitdiff
path: root/bin/reportlab/tools/docco/rl_doc_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/reportlab/tools/docco/rl_doc_utils.py')
-rwxr-xr-xbin/reportlab/tools/docco/rl_doc_utils.py411
1 files changed, 411 insertions, 0 deletions
diff --git a/bin/reportlab/tools/docco/rl_doc_utils.py b/bin/reportlab/tools/docco/rl_doc_utils.py
new file mode 100755
index 00000000000..c3e107642e1
--- /dev/null
+++ b/bin/reportlab/tools/docco/rl_doc_utils.py
@@ -0,0 +1,411 @@
+#! /usr/bin/python2.3
+#Copyright ReportLab Europe Ltd. 2000-2004
+#see license.txt for license details
+#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/tools/docco/rl_doc_utils.py
+__version__=''' $Id$ '''
+
+
+__doc__ = """
+This module contains utilities for generating guides
+"""
+
+import os, sys, glob
+import string
+
+from rltemplate import RLDocTemplate
+from stylesheet import getStyleSheet
+styleSheet = getStyleSheet()
+
+#from reportlab.platypus.doctemplate import SimpleDocTemplate
+from reportlab.lib.units import inch
+from reportlab.lib.pagesizes import letter, A4, A5, A3 # latter two for testing
+from reportlab.rl_config import defaultPageSize
+from reportlab.platypus import figures
+from reportlab.platypus import Paragraph, Spacer, Preformatted,\
+ PageBreak, CondPageBreak, Flowable, Table, TableStyle, \
+ NextPageTemplate, KeepTogether, Image, XPreformatted
+from reportlab.lib.styles import ParagraphStyle
+from reportlab.lib import colors
+from reportlab.lib.sequencer import getSequencer
+
+import examples
+
+appmode=0
+
+
+from t_parse import Template
+QFcodetemplate = Template("X$X$", "X")
+QFreptemplate = Template("X^X^", "X")
+codesubst = "%s<font name=Courier>%s</font>"
+QFsubst = "%s<font name=Courier><i>%s</i></font>"
+
+
+def quickfix(text):
+ """inside text find any subsequence of form $subsequence$.
+ Format the subsequence as code. If similarly if text contains ^arg^
+ format the arg as replaceable. The escape sequence for literal
+ $ is $\\$ (^ is ^\\^.
+ """
+ from string import join
+ for (template,subst) in [(QFcodetemplate, codesubst), (QFreptemplate, QFsubst)]:
+ fragment = text
+ parts = []
+ try:
+ while fragment:
+ try:
+ (matches, index) = template.PARSE(fragment)
+ except: raise ValueError
+ else:
+ [prefix, code] = matches
+ if code == "\\":
+ part = fragment[:index]
+ else:
+ part = subst % (prefix, code)
+ parts.append(part)
+ fragment = fragment[index:]
+ except ValueError:
+ parts.append(fragment)
+ text = join(parts, "")
+ return text
+#print quickfix("$testing$ testing $one$ ^two^ $three(^four^)$")
+
+
+
+H1 = styleSheet['Heading1']
+H2 = styleSheet['Heading2']
+H3 = styleSheet['Heading3']
+H4 = styleSheet['Heading4']
+B = styleSheet['BodyText']
+BU = styleSheet['Bullet']
+Comment = styleSheet['Comment']
+Centred = styleSheet['Centred']
+Caption = styleSheet['Caption']
+
+#set up numbering
+seq = getSequencer()
+seq.setFormat('Chapter','1')
+seq.setFormat('Section','1')
+seq.setFormat('Appendix','A')
+seq.setFormat('Figure', '1')
+seq.chain('Chapter','Section')
+seq.chain('Chapter','Figure')
+
+lessonnamestyle = H2
+discussiontextstyle = B
+exampletextstyle = styleSheet['Code']
+# size for every example
+examplefunctionxinches = 5.5
+examplefunctionyinches = 3
+examplefunctiondisplaysizes = (examplefunctionxinches*inch, examplefunctionyinches*inch)
+
+def getJustFontPaths():
+ '''return afm and pfb for Just's files'''
+ import reportlab
+ folder = os.path.dirname(reportlab.__file__) + os.sep + 'fonts'
+ return os.path.join(folder, 'Wargames.afm'), os.path.join(folder, 'Wargames.pfb')
+
+# for testing
+def NOP(*x,**y):
+ return None
+
+def CPage(inches):
+ getStory().append(CondPageBreak(inches*inch))
+
+def newPage():
+ getStory().append(PageBreak())
+
+def nextTemplate(templName):
+ f = NextPageTemplate(templName)
+ getStory().append(f)
+
+def disc(text, klass=Paragraph, style=discussiontextstyle):
+ text = quickfix(text)
+ P = klass(text, style)
+ getStory().append(P)
+
+def restartList():
+ getSequencer().reset('list1')
+
+def list(text, doBullet=1):
+ text=quickfix(text)
+ if doBullet:
+ text='<bullet><seq id="list1"/>.</bullet>'+text
+ P = Paragraph(text, BU)
+ getStory().append(P)
+
+def bullet(text):
+ text='<bullet><font name="Symbol">'+chr(183)+'</font></bullet>' + quickfix(text)
+ P = Paragraph(text, BU)
+ getStory().append(P)
+
+def eg(text,before=0.1,after=0):
+ space(before)
+ disc(text, klass=Preformatted, style=exampletextstyle)
+ space(after)
+
+def space(inches=1./6):
+ if inches: getStory().append(Spacer(0,inches*inch))
+
+def EmbeddedCode(code,name='t'):
+ eg(code)
+ disc("produces")
+ exec code+("\ngetStory().append(%s)\n"%name)
+
+def startKeep():
+ return len(getStory())
+
+def endKeep(s):
+ S = getStory()
+ k = KeepTogether(S[s:])
+ S[s:] = [k]
+
+def title(text):
+ """Use this for the document title only"""
+ disc(text,style=styleSheet['Title'])
+
+#AR 3/7/2000 - defining three new levels of headings; code
+#should be swapped over to using them.
+
+def heading1(text):
+ """Use this for chapters. Lessons within a big chapter
+ should now use heading2 instead. Chapters get numbered."""
+ getStory().append(PageBreak())
+ p = Paragraph('Chapter <seq id="Chapter"/> ' + quickfix(text), H1)
+ getStory().append(p)
+
+def Appendix1(text,):
+ global appmode
+ getStory().append(PageBreak())
+ if not appmode:
+ seq.setFormat('Chapter','A')
+ seq.reset('Chapter')
+ appmode = 1
+ p = Paragraph('Appendix <seq id="Chapter"/> ' + quickfix(text), H1)
+ getStory().append(p)
+
+def heading2(text):
+ """Used to be 'lesson'"""
+ getStory().append(CondPageBreak(inch))
+ p = Paragraph('<seq template="%(Chapter)s.%(Section+)s "/>' + quickfix(text), H2)
+ getStory().append(p)
+
+def heading3(text):
+ """Used to be most of the plain old 'head' sections"""
+ getStory().append(CondPageBreak(inch))
+ p = Paragraph(quickfix(text), H3)
+ getStory().append(p)
+
+def image(path, width=None, height=None ):
+ s = startKeep()
+ space(.2)
+ import reportlab
+ rlDocImageDir = os.path.join(os.path.dirname(reportlab.__file__), 'docs','images')
+ getStory().append(Image(os.path.join(rlDocImageDir,path),width,height))
+ space(.2)
+ endKeep(s)
+
+def heading4(text):
+ """Used to be most of the plain old 'head' sections"""
+ getStory().append(CondPageBreak(inch))
+ p = Paragraph(quickfix(text), H4)
+ getStory().append(p)
+
+def todo(text):
+ """Used for notes to ourselves"""
+ getStory().append(Paragraph(quickfix(text), Comment))
+
+def centred(text):
+ getStory().append(Paragraph(quickfix(text), Centred))
+
+def caption(text):
+ getStory().append(Paragraph(quickfix(text), Caption))
+
+class Illustration(figures.Figure):
+ """The examples are all presented as functions which do
+ something to a canvas, with a constant height and width
+ used. This puts them inside a figure box with a caption."""
+
+ def __init__(self, operation, caption, width=None, height=None):
+ stdwidth, stdheight = examplefunctiondisplaysizes
+ if not width:
+ width = stdwidth
+ if not height:
+ height = stdheight
+ #figures.Figure.__init__(self, stdwidth * 0.75, stdheight * 0.75)
+ figures.Figure.__init__(self, width, height,
+ 'Figure <seq template="%(Chapter)s-%(Figure+)s"/>: ' + quickfix(caption))
+ self.operation = operation
+
+ def drawFigure(self):
+ #shrink it a little...
+ #self.canv.scale(0.75, 0.75)
+ self.operation(self.canv)
+
+
+def illust(operation, caption, width=None, height=None):
+ i = Illustration(operation, caption, width=width, height=height)
+ getStory().append(i)
+
+
+class GraphicsDrawing(Illustration):
+ """Lets you include reportlab/graphics drawings seamlessly,
+ with the right numbering."""
+ def __init__(self, drawing, caption):
+ figures.Figure.__init__(self,
+ drawing.width,
+ drawing.height,
+ 'Figure <seq template="%(Chapter)s-%(Figure+)s"/>: ' + quickfix(caption)
+ )
+ self.drawing = drawing
+
+ def drawFigure(self):
+ d = self.drawing
+ d.wrap(d.width, d.height)
+ d.drawOn(self.canv, 0, 0)
+
+def draw(drawing, caption):
+ d = GraphicsDrawing(drawing, caption)
+ getStory().append(d)
+
+class ParaBox(figures.Figure):
+ """Illustrates paragraph examples, with style attributes on the left"""
+ descrStyle = ParagraphStyle('description',
+ fontName='Courier',
+ fontSize=8,
+ leading=9.6)
+
+ def __init__(self, text, style, caption):
+ figures.Figure.__init__(self, 0, 0, caption)
+ self.text = text
+ self.style = style
+ self.para = Paragraph(text, style)
+
+ styleText = self.getStyleText(style)
+ self.pre = Preformatted(styleText, self.descrStyle)
+
+ def wrap(self, availWidth, availHeight):
+ """Left 30% is for attributes, right 50% for sample,
+ 10% gutter each side."""
+ self.x0 = availWidth * 0.05 #left of box
+ self.x1 = availWidth * 0.1 #left of descriptive text
+ self.x2 = availWidth * 0.5 #left of para itself
+ self.x3 = availWidth * 0.9 #right of para itself
+ self.x4 = availWidth * 0.95 #right of box
+ self.width = self.x4 - self.x0
+ self.dx = 0.5 * (availWidth - self.width)
+
+ paw, self.pah = self.para.wrap(self.x3 - self.x2, availHeight)
+ self.pah = self.pah + self.style.spaceBefore + self.style.spaceAfter
+ prw, self.prh = self.pre.wrap(self.x2 - self.x1, availHeight)
+ self.figureHeight = max(self.prh, self.pah) * 10.0/9.0
+ return figures.Figure.wrap(self, availWidth, availHeight)
+
+ def getStyleText(self, style):
+ """Converts style to preformatted block of text"""
+ lines = []
+ for (key, value) in style.__dict__.items():
+ lines.append('%s = %s' % (key, value))
+ lines.sort()
+ return string.join(lines, '\n')
+
+ def drawFigure(self):
+
+ #now we fill in the bounding box and before/after boxes
+ self.canv.saveState()
+ self.canv.setFillGray(0.95)
+ self.canv.setDash(1,3)
+ self.canv.rect(self.x2 - self.x0,
+ self.figureHeight * 0.95 - self.pah,
+ self.x3-self.x2, self.para.height,
+ fill=1,stroke=1)
+
+ self.canv.setFillGray(0.90)
+ self.canv.rect(self.x2 - self.x0, #spaceBefore
+ self.figureHeight * 0.95 - self.pah + self.para.height,
+ self.x3-self.x2, self.style.spaceBefore,
+ fill=1,stroke=1)
+
+ self.canv.rect(self.x2 - self.x0, #spaceBefore
+ self.figureHeight * 0.95 - self.pah - self.style.spaceAfter,
+ self.x3-self.x2, self.style.spaceAfter,
+ fill=1,stroke=1)
+
+ self.canv.restoreState()
+ #self.canv.setFillColor(colors.yellow)
+ self.para.drawOn(self.canv, self.x2 - self.x0,
+ self.figureHeight * 0.95 - self.pah)
+ self.pre.drawOn(self.canv, self.x1 - self.x0,
+ self.figureHeight * 0.95 - self.prh)
+
+
+ def getStyleText(self, style):
+ """Converts style to preformatted block of text"""
+ lines = []
+ for (key, value) in style.__dict__.items():
+ if key not in ('name','parent'):
+ lines.append('%s = %s' % (key, value))
+ return string.join(lines, '\n')
+
+
+class ParaBox2(figures.Figure):
+ """Illustrates a paragraph side-by-side with the raw
+ text, to show how the XML works."""
+ def __init__(self, text, caption):
+ figures.Figure.__init__(self, 0, 0, caption)
+ descrStyle = ParagraphStyle('description',
+ fontName='Courier',
+ fontSize=8,
+ leading=9.6)
+ textStyle = B
+ self.text = text
+ self.left = Paragraph('<![CDATA[' + text + ']]>', descrStyle)
+ self.right = Paragraph(text, B)
+
+
+ def wrap(self, availWidth, availHeight):
+ self.width = availWidth * 0.9
+ colWidth = 0.4 * self.width
+ lw, self.lh = self.left.wrap(colWidth, availHeight)
+ rw, self.rh = self.right.wrap(colWidth, availHeight)
+ self.figureHeight = max(self.lh, self.rh) * 10.0/9.0
+ return figures.Figure.wrap(self, availWidth, availHeight)
+
+ def drawFigure(self):
+ self.left.drawOn(self.canv,
+ self.width * 0.05,
+ self.figureHeight * 0.95 - self.lh
+ )
+ self.right.drawOn(self.canv,
+ self.width * 0.55,
+ self.figureHeight * 0.95 - self.rh
+ )
+
+def parabox(text, style, caption):
+ p = ParaBox(text, style,
+ 'Figure <seq template="%(Chapter)s-%(Figure+)s"/>: ' + quickfix(caption)
+ )
+ getStory().append(p)
+
+def parabox2(text, caption):
+ p = ParaBox2(text,
+ 'Figure <seq template="%(Chapter)s-%(Figure+)s"/>: ' + quickfix(caption)
+ )
+ getStory().append(p)
+
+def pencilnote():
+ getStory().append(examples.NoteAnnotation())
+
+
+from reportlab.lib.colors import tan, green
+def handnote(xoffset=0, size=None, fillcolor=tan, strokecolor=green):
+ getStory().append(examples.HandAnnotation(xoffset,size,fillcolor,strokecolor))
+
+
+#make a singleton, created when requested rather
+#than each time a chapter imports it.
+_story = []
+def setStory(story=[]):
+ global _story
+ _story = story
+def getStory():
+ return _story