author | Tero Marttila <terom@fixme.fi> |
Sat, 08 Jan 2011 23:41:48 +0200 | |
changeset 40 | 30a0a0fa8c54 |
parent 31 | e1b63e4d10f4 |
permissions | -rw-r--r-- |
4 | 1 |
# coding: utf-8 |
2 |
||
3 |
""" |
|
4 |
PDF output |
|
5 |
""" |
|
6 |
||
7 |
from reportlab import platypus as rlpp |
|
8 |
from reportlab.lib.units import inch |
|
9 |
from reportlab.lib import pagesizes, styles |
|
10 |
||
11 |
from cStringIO import StringIO |
|
12 |
import itertools |
|
13 |
import logging |
|
14 |
import datetime |
|
15 |
||
16 |
||
17 |
log = logging.getLogger('svv.pdf') |
|
18 |
||
19 |
class Styles (object) : |
|
20 |
""" |
|
21 |
Simple stylesheet |
|
22 |
""" |
|
23 |
||
24 |
samplestyles = styles.getSampleStyleSheet() |
|
25 |
||
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
26 |
# default |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
27 |
default = styles.ParagraphStyle('Text', samplestyles['Normal'], |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
28 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
29 |
) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
30 |
|
4 | 31 |
# normal text |
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
32 |
text = p = default |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
33 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
34 |
# headers |
4 | 35 |
h1 = styles.ParagraphStyle('Heading1', samplestyles['h1'], |
36 |
fontName = 'Times-Bold', |
|
37 |
fontSize = 22, |
|
38 |
spaceBefore = 0, |
|
39 |
spaceAfter = 0, |
|
40 |
||
41 |
) |
|
42 |
||
43 |
h2 = styles.ParagraphStyle('Heading2', samplestyles['h2'], |
|
44 |
fontName = 'Times-Bold', |
|
45 |
fontSize = 14, |
|
46 |
spaceBefore = 6, |
|
47 |
spaceAfter = 0, |
|
48 |
) |
|
49 |
||
50 |
h3 = styles.ParagraphStyle('Heading3', samplestyles['h3'], |
|
51 |
fontName = 'Times-Italic', |
|
52 |
fontSize = 12, |
|
53 |
spaceBefore = 0, |
|
54 |
spaceAfter = 0, |
|
55 |
) |
|
56 |
||
57 |
||
58 |
# list indent level |
|
59 |
list_indent = inch / 4 |
|
60 |
||
61 |
# root title |
|
62 |
list_h1 = styles.ParagraphStyle('ListHeading1', samplestyles['h1'], |
|
63 |
bulletIndent = 0, |
|
64 |
leftIndent = 0, |
|
65 |
) |
|
66 |
||
67 |
# section |
|
68 |
list_h2 = styles.ParagraphStyle('ListHeading2', samplestyles['h2'], |
|
69 |
bulletIndent = 0, |
|
70 |
leftIndent = list_indent, |
|
71 |
fontName = 'Times-Bold', |
|
72 |
fontSize = 10, |
|
73 |
leading = 12, |
|
74 |
spaceBefore = 6, |
|
75 |
spaceAfter = 0, |
|
76 |
) |
|
77 |
||
78 |
# segment |
|
79 |
list_h3 = styles.ParagraphStyle('ListHeading3', samplestyles['h3'], |
|
80 |
bulletIndent = 0, |
|
81 |
leftIndent = list_indent, |
|
82 |
fontName = 'Times-Italic', |
|
83 |
fontSize = 10, |
|
84 |
leading = 12, |
|
85 |
spaceBefore = 0, |
|
86 |
spaceAfter = 0, |
|
87 |
) |
|
88 |
||
89 |
# infot |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
90 |
list_p = styles.ParagraphStyle('ListText', samplestyles['Normal'], |
4 | 91 |
bulletIndent = 0, |
92 |
leftIndent = list_indent, |
|
93 |
) |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
94 |
list_text = list_p |
4 | 95 |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
96 |
# lookup styles by rule |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
97 |
# searched in order, first match against end of node_path wins |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
98 |
RULES = ( |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
99 |
('li p', list_p), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
100 |
('li h1', list_h1), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
101 |
('li h2', list_h2), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
102 |
('li h3', list_h3), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
103 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
104 |
('p', p), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
105 |
('h1', h1), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
106 |
('h2', h2), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
107 |
('h3', h3), |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
108 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
109 |
) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
110 |
|
4 | 111 |
@classmethod |
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
112 |
def match (cls, name=None) : |
4 | 113 |
""" |
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
114 |
Return appropriate style. |
4 | 115 |
""" |
116 |
||
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
117 |
if name : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
118 |
return getattr(cls, name, cls.default) |
4 | 119 |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
120 |
else : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
121 |
return cls.default |
4 | 122 |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
123 |
def lookup (self, node_path) : |
4 | 124 |
""" |
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
125 |
Return a suitable ParagraphStyle to use for a node |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
126 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
127 |
node_path - tag-path to node (list of tags as ancestry of node) |
4 | 128 |
""" |
129 |
||
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
130 |
# XXX: find a better hack |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
131 |
nodepath = ' '.join(node_path) |
4 | 132 |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
133 |
for rule, style in self.RULES : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
134 |
if nodepath.endswith(rule) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
135 |
return style |
4 | 136 |
|
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
137 |
# default |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
138 |
return self.default |
4 | 139 |
|
140 |
class SignatureBlock (rlpp.Flowable) : |
|
141 |
""" |
|
142 |
A signature block, with multiple sets of multiple pre-fillied fields. |
|
143 |
""" |
|
144 |
||
145 |
# vertical space per field |
|
146 |
FIELD_HEIGHT = 2 * inch / 4 |
|
147 |
||
148 |
# horizontal offset from top of field to field line |
|
149 |
FIELD_OFFSET = FIELD_HEIGHT / 2 |
|
150 |
||
151 |
# maximum width to scale columns to |
|
152 |
COL_WIDTH_MAX = 4 * inch |
|
153 |
||
154 |
# empty space to leave below the fields |
|
155 |
PADDING_BOTTOM = inch / 2 |
|
156 |
||
23
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
157 |
def __init__ (self, cols, fields, values={}, fullheight=None) : |
4 | 158 |
""" |
23
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
159 |
cols - Column titles |
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
160 |
fields - Fields titles, describing the horizontal fields |
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
161 |
values - Pre-filled values as a {(col, field): value} dict |
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
162 |
fullheight - Consume full vertical height to place at bottom of page |
4 | 163 |
|
164 |
desc/value strings can contain formatting codes: |
|
165 |
||
166 |
column - title of the current column |
|
167 |
today - today's date in %d/%m/%Y format |
|
168 |
""" |
|
169 |
||
170 |
self.cols = cols |
|
171 |
self.fields = fields |
|
172 |
self.values = values |
|
23
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
173 |
self.fullheight = fullheight |
4 | 174 |
|
175 |
def wrap (self, width, height) : |
|
176 |
""" |
|
177 |
Calculate how much space we use up, returning (width, height) |
|
178 |
""" |
|
179 |
||
180 |
self.width = width |
|
181 |
||
23
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
182 |
self.height = len(self.fields) * self.FIELD_HEIGHT |
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
183 |
|
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
184 |
if self.fullheight : |
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
185 |
# consume all available height, to place us at the bottom |
26ae1b1db3c7
pdf: add SignatureBlock(fullheight=) param
Tero Marttila <terom@fixme.fi>
parents:
17
diff
changeset
|
186 |
self.height = max(self.height, height) |
4 | 187 |
|
188 |
return self.width, self.height |
|
189 |
||
190 |
def formatString (self, text, col_title) : |
|
191 |
""" |
|
192 |
Format display string using context parameters |
|
193 |
""" |
|
17
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
194 |
|
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
195 |
# XXX: the canvas.drawString we use here does support unicode? |
4 | 196 |
return text % dict( |
197 |
column = col_title, |
|
198 |
today = datetime.date.today().strftime("%d/%m/%Y"), |
|
199 |
) |
|
200 |
||
201 |
# text above field line |
|
202 |
VALUE_FONT = "Courier-Bold" |
|
203 |
VALUE_FONT_SIZE = 14 |
|
204 |
VALUE_OFFSET = inch / 12 |
|
205 |
||
206 |
# text below field line |
|
207 |
TITLE_FONT = "Times-Italic" |
|
208 |
TITLE_FONT_SIZE = 10 |
|
209 |
TITLE_OFFSET = inch / 8 |
|
210 |
||
211 |
def draw (self) : |
|
212 |
""" |
|
213 |
Render full block onto our canvas |
|
214 |
""" |
|
215 |
||
216 |
# target canvas |
|
217 |
canvas = self.canv |
|
218 |
||
219 |
col_width = min(self.width / len(self.cols), self.COL_WIDTH_MAX) |
|
220 |
col_margin = col_width * 0.1 |
|
221 |
col_height = len(self.fields) * self.FIELD_HEIGHT + self.PADDING_BOTTOM |
|
222 |
||
223 |
for field_idx, (field_title) in enumerate(self.fields) : |
|
224 |
h = self.FIELD_HEIGHT |
|
225 |
y = col_height - h * (field_idx + 1) |
|
226 |
||
227 |
for col_idx, (col_title) in enumerate(self.cols) : |
|
228 |
w = col_width |
|
229 |
x = w * col_idx |
|
230 |
value = self.values.get((col_title, field_title)) |
|
231 |
title = field_title |
|
232 |
||
233 |
value = self.formatString(value, col_title) if value else None |
|
234 |
title = self.formatString(title, col_title) if title else None |
|
235 |
||
236 |
if value : |
|
237 |
canvas.setFont(self.VALUE_FONT, self.VALUE_FONT_SIZE) |
|
238 |
canvas.drawString(x + col_margin + self.VALUE_OFFSET, y - self.FIELD_OFFSET + 2, value) |
|
239 |
||
240 |
# field line |
|
241 |
canvas.line(x + col_margin, y - self.FIELD_OFFSET, x + w - col_margin, y - h / 2) |
|
242 |
||
243 |
# desc text |
|
244 |
canvas.setFont(self.TITLE_FONT, self.TITLE_FONT_SIZE) |
|
245 |
canvas.drawString(x + col_margin + self.TITLE_OFFSET, y - self.FIELD_OFFSET - self.TITLE_FONT_SIZE, title) |
|
246 |
||
247 |
class PageTemplate (rlpp.PageTemplate) : |
|
248 |
""" |
|
249 |
A single-frame page with header and footer. |
|
250 |
""" |
|
251 |
||
252 |
# vertical space available for footer/header, fixed because we can't really flow text vertically |
|
253 |
HEADER_HEIGHT = 1 * inch |
|
254 |
FOOTER_HEIGHT = 1 * inch |
|
255 |
||
256 |
COL_FONT_SIZE = 8 |
|
257 |
COL_TITLE_FONT_NAME, COL_TITLE_FONT_SIZE = COL_TITLE_FONT = ("Times-Bold", COL_FONT_SIZE) |
|
258 |
COL_TEXT_FONT_NAME, COL_TEXT_FONT_SIZE = COL_TEXT_FONT = ("Times-Roman", COL_FONT_SIZE) |
|
259 |
||
260 |
||
261 |
def __init__ (self, id='page', page_size=pagesizes.A4, margin=inch, header_columns=None, footer_columns=None) : |
|
262 |
""" |
|
263 |
id - identifier for this page template |
|
264 |
page_size - the (width, height) of this page |
|
265 |
margin - the base margin to use between elements |
|
266 |
||
267 |
header_columns - (title, text) list of header columns |
|
268 |
footer_columnss - (title, text) list of footer columns |
|
269 |
""" |
|
270 |
||
271 |
self.page_width, self.page_height = self.page_size = page_size |
|
272 |
self.margin = margin |
|
273 |
||
274 |
self.header_height = self.HEADER_HEIGHT |
|
275 |
self.footer_height = self.FOOTER_HEIGHT |
|
276 |
||
277 |
# calculate frame |
|
278 |
self.frame_left = self.margin |
|
279 |
self.frame_bottom = self.footer_height + self.margin / 2 |
|
280 |
self.frame_top = self.page_height - self.header_height - self.margin / 2 |
|
281 |
self.frame_right = self.page_width - self.margin |
|
282 |
||
283 |
self.frame = rlpp.Frame(self.frame_left, self.frame_bottom, self.frame_right - self.frame_left, self.frame_top - self.frame_bottom) |
|
284 |
||
285 |
# init base template |
|
286 |
rlpp.PageTemplate.__init__(self, id, frames=[self.frame]) |
|
287 |
||
288 |
self.header_columns = header_columns |
|
289 |
self.footer_columns = footer_columns |
|
290 |
||
291 |
||
292 |
def fmt_string (self, text) : |
|
293 |
""" |
|
294 |
Prepare a string for display by handling format codes |
|
295 |
""" |
|
17
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
296 |
|
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
297 |
return unicode(text % dict( |
4 | 298 |
today = datetime.date.today().strftime("%d / %m / %Y"), |
299 |
)) |
|
300 |
||
301 |
def draw_column (self, canvas, x, y, width, title, lines, gray=None) : |
|
302 |
""" |
|
303 |
Draw a column in the specified position, with the specified lines of text |
|
304 |
""" |
|
305 |
||
306 |
text = canvas.beginText(x, y) |
|
307 |
||
308 |
# grayscale text? |
|
309 |
if gray : |
|
310 |
text.setFillGray(gray) |
|
311 |
||
312 |
# title |
|
313 |
text.setFont(*self.COL_TITLE_FONT) |
|
314 |
text.textLine(self.fmt_string(title)) |
|
315 |
||
316 |
# lines |
|
317 |
text.setFont(*self.COL_TEXT_FONT) |
|
17
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
318 |
|
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
319 |
# XXX: textobject's textLine fails at unicode, but textLine should work... |
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
320 |
for line in lines : |
820c46308e45
fix pdf unicode issues, and move OrderContractForm submit inside fieldset
Tero Marttila <terom@fixme.fi>
parents:
15
diff
changeset
|
321 |
text.textLine(self.fmt_string(line)) |
4 | 322 |
|
323 |
# draw out |
|
324 |
canvas.drawText(text) |
|
325 |
||
326 |
||
327 |
def draw_columns (self, canvas, x, y, width, columns, **opts) : |
|
328 |
""" |
|
329 |
Draw a series of columns in the specified position |
|
330 |
""" |
|
331 |
||
332 |
col_count = len(columns) |
|
333 |
col_width = width / col_count |
|
334 |
||
335 |
x_base = x |
|
336 |
||
337 |
for col_idx, (col_data) in enumerate(columns) : |
|
338 |
x = x_base + (col_idx * col_width) |
|
339 |
||
340 |
# draw column data at correct offset inside our space |
|
341 |
self.draw_column(canvas, x, y - self.COL_FONT_SIZE, col_width, *col_data, **opts) |
|
342 |
||
343 |
||
344 |
def draw_header (self, canvas) : |
|
345 |
""" |
|
346 |
Draw page header |
|
347 |
""" |
|
348 |
||
349 |
# offsets |
|
350 |
x = self.margin |
|
351 |
h = self.footer_height - self.margin / 4 |
|
352 |
w = self.page_width - self.margin * 2 |
|
353 |
||
354 |
# spacer |
|
355 |
y = self.page_height - self.footer_height |
|
356 |
||
357 |
canvas.setLineWidth(0.5) |
|
358 |
canvas.line(x - self.margin / 2, y, self.page_width - self.margin / 2, y) |
|
359 |
||
360 |
# columns |
|
361 |
y = self.page_height - self.margin / 4 |
|
362 |
||
363 |
self.draw_columns(canvas, x, y, w, self.header_columns) |
|
364 |
||
365 |
||
366 |
def draw_footer (self, canvas) : |
|
367 |
""" |
|
368 |
Draw page footer |
|
369 |
""" |
|
370 |
||
371 |
# offsets |
|
372 |
x = self.margin |
|
373 |
y = self.footer_height |
|
374 |
w = self.page_width - self.margin * 2 |
|
375 |
||
376 |
# spacer |
|
377 |
canvas.setLineWidth(0.5) |
|
378 |
canvas.line(x - self.margin / 2, y, self.page_width - self.margin / 2, y) |
|
379 |
||
380 |
# columns |
|
381 |
self.draw_columns(canvas, x, y - inch / 8, w, self.footer_columns, gray=0.4) |
|
382 |
||
383 |
||
384 |
def beforeDrawPage (self, canvas, document) : |
|
385 |
""" |
|
386 |
Draw page headers/footers |
|
387 |
""" |
|
388 |
||
389 |
self.draw_header(canvas) |
|
390 |
self.draw_footer(canvas) |
|
391 |
||
392 |
class DocumentTemplate (rlpp.BaseDocTemplate) : |
|
393 |
def __init__ (self, page_templates, title, author, page_size=pagesizes.A4) : |
|
394 |
""" |
|
395 |
Initialize with fixed list of needed PageTemplates. |
|
396 |
""" |
|
397 |
||
398 |
# we supply the file later |
|
399 |
rlpp.BaseDocTemplate.__init__(self, filename=None, |
|
400 |
pageTemplates=page_templates, title=title, author=author, |
|
401 |
pageSize=page_size |
|
402 |
) |
|
403 |
||
15
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
404 |
def render_buf (self, elements) : |
4 | 405 |
""" |
15
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
406 |
Build the document using the given list of Flowables, returning a StringIO containing the PDF. |
4 | 407 |
""" |
408 |
||
409 |
buf = StringIO() |
|
410 |
||
411 |
# build |
|
412 |
self.build(elements, buf) |
|
413 |
||
15
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
414 |
# prepare for read |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
415 |
buf.seek(0) |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
416 |
|
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
417 |
return buf |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
418 |
|
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
419 |
def render_string (self, elements) : |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
420 |
""" |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
421 |
Build the document using the given list of Flowables, returning the PDF as a single str. |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
422 |
""" |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
423 |
|
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
424 |
# render |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
425 |
buf = self.render_buf(elements) |
e098ee83b363
Implement OrderContractDocument
Tero Marttila <terom@fixme.fi>
parents:
4
diff
changeset
|
426 |
|
4 | 427 |
# binary data out |
428 |
return buf.getvalue() |
|
429 |
||
31
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
430 |
class Markup (object) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
431 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
432 |
Generate Paragraphs from Markup docs. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
433 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
434 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
435 |
def __init__ (self, styles) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
436 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
437 |
Initialize render state. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
438 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
439 |
styles - Style instance to use |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
440 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
441 |
This class is stateful and single-use. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
442 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
443 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
444 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
445 |
# elment stack |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
446 |
self.stack = [] |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
447 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
448 |
# styles |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
449 |
self.styles = styles |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
450 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
451 |
def lookup_style (self, elem=None) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
452 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
453 |
Lookup style for given element, which must be at the top of the stack. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
454 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
455 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
456 |
# path to element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
457 |
path = self.stack |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
458 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
459 |
if elem is not None and path[-1] is not elem : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
460 |
# XXX: sub-elem? |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
461 |
path = path + [elem] |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
462 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
463 |
# lookup |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
464 |
return self.styles.lookup([elem.tag for elem in path]) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
465 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
466 |
## Basic text |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
467 |
def render_p (self, elem, bullet=None) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
468 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
469 |
Normal paragraph. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
470 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
471 |
XXX: inline markup? |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
472 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
473 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
474 |
style = self.lookup_style(elem) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
475 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
476 |
yield rlpp.Paragraph(elem.text, style, bullet) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
477 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
478 |
def _render_hx (self, elem, bullet=None) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
479 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
480 |
Render given h1/h2/h3 element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
481 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
482 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
483 |
# get style for <hX> tag |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
484 |
style = self.lookup_style(elem) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
485 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
486 |
# styled text |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
487 |
yield rlpp.Paragraph(elem.text, style, bullet) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
488 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
489 |
render_h1 = render_h2 = render_h3 = _render_hx |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
490 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
491 |
## Lists |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
492 |
def list_ol_seq (self) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
493 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
494 |
Numeric ordered list numbering. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
495 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
496 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
497 |
for idx in itertools.count(1) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
498 |
yield "%d." % (idx, ) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
499 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
500 |
def list_ul_seq (self) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
501 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
502 |
Bulleted unordered list numbering. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
503 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
504 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
505 |
while True : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
506 |
yield "•" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
507 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
508 |
def _render_list (self, elem, seq, bullet=None) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
509 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
510 |
Render <ul>/<ol> containing <li>s |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
511 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
512 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
513 |
indent = self.styles.list_indent |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
514 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
515 |
# following lines, indented |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
516 |
yield rlpp.Indenter(indent) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
517 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
518 |
# children |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
519 |
for sub in elem : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
520 |
# get (optional) bullet for item |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
521 |
bullet = next(seq, None) if seq else None |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
522 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
523 |
# sub-render |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
524 |
for ff in self.render(sub, bullet) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
525 |
yield ff |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
526 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
527 |
# de-dent |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
528 |
yield rlpp.Indenter(-indent) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
529 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
530 |
def render_ul (self, elem, bullet=None) : return self._render_list(elem, self.list_ul_seq(), bullet) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
531 |
def render_ol (self, elem, bullet=None) : return self._render_list(elem, self.list_ol_seq(), bullet) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
532 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
533 |
def render_li (self, elem, bullet) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
534 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
535 |
Render <li>, with given bullet on first line of text |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
536 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
537 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
538 |
children = list(elem) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
539 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
540 |
# render bullet on first item |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
541 |
if elem.text : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
542 |
# style for text pseudo-element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
543 |
style = self.lookup_style(elem.makeelement('text', {})) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
544 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
545 |
# direct text, no sub-p or such |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
546 |
yield rlpp.Paragraph(elem.text, style, bullet) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
547 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
548 |
elif children : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
549 |
sub = children.pop(0) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
550 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
551 |
# render first sub with bullet |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
552 |
for ff in self.render(sub, bullet) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
553 |
yield ff |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
554 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
555 |
# render remaining elements |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
556 |
for sub in children : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
557 |
for ff in self.render(sub) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
558 |
yield ff |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
559 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
560 |
## Root element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
561 |
def render_root (self, elem, bullet) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
562 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
563 |
Render the given root element's children, ignoring the root element itself. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
564 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
565 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
566 |
for sub in elem : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
567 |
for ff in self.render(sub) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
568 |
yield ff |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
569 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
570 |
## Top-level element render dispatch |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
571 |
def render (self, elem, bullet=None) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
572 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
573 |
Yield a series of Flowables for the given element and its children. |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
574 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
575 |
elem - Element to (recursively) render |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
576 |
bullet - optional bullet text to use for this element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
577 |
""" |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
578 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
579 |
log.debug("%r, bullet=%r", elem, bullet) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
580 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
581 |
try : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
582 |
# lookup |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
583 |
func = getattr(self, 'render_%s' % elem.tag) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
584 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
585 |
except AttributeError, ex : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
586 |
raise Exception("Unhandled tag %r" % elem) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
587 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
588 |
# enter element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
589 |
self.stack.append(elem) |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
590 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
591 |
# dispatch |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
592 |
for ff in func(elem, bullet) : |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
593 |
yield ff |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
594 |
|
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
595 |
# exit element |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
596 |
assert self.stack.pop(-1) is elem |
e1b63e4d10f4
Implement Markup rendering for PDFs, and use that for order terms
Tero Marttila <terom@fixme.fi>
parents:
23
diff
changeset
|
597 |