Merge lp:~aelkner/schooltool/schooltool.zambia into lp:~schooltool-owners/schooltool/schooltool.zambia

Proposed by Alan Elkner
Status: Merged
Merged at revision: 59
Proposed branch: lp:~aelkner/schooltool/schooltool.zambia
Merge into: lp:~schooltool-owners/schooltool/schooltool.zambia
Diff against target: 702 lines (+612/-3)
7 files modified
src/schooltool/zambia/app/browser/app.py (+307/-1)
src/schooltool/zambia/app/browser/configure.zcml (+52/-0)
src/schooltool/zambia/app/browser/resources/zambia.css (+20/-0)
src/schooltool/zambia/app/browser/templates/subgroups_timetable.pt (+55/-0)
src/schooltool/zambia/app/browser/templates/subgroups_timetable_pdf.pt (+88/-0)
src/schooltool/zambia/app/browser/templates/teachers_timetable.pt (+2/-2)
src/schooltool/zambia/app/browser/templates/teachers_timetable_pdf.pt (+88/-0)
To merge this branch: bzr merge lp:~aelkner/schooltool/schooltool.zambia
Reviewer Review Type Date Requested Status
SchoolTool Owners Pending
Review via email: mp+34671@code.launchpad.net
To post a comment you must log in.
59. By Alan Elkner <aelkner@ubuntu>

cosmetic changes to timetable pdfs

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/schooltool/zambia/app/browser/app.py'
2--- src/schooltool/zambia/app/browser/app.py 2010-08-08 18:28:59 +0000
3+++ src/schooltool/zambia/app/browser/app.py 2010-09-26 22:01:04 +0000
4@@ -19,14 +19,19 @@
5 """
6 SchoolTool Zambia application views.
7 """
8+from reportlab.lib import pagesizes
9
10+from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
11 from zope.publisher.browser import BrowserView
12 from zope.security.proxy import removeSecurityProxy
13 from zope.traversing.browser.absoluteurl import absoluteURL
14
15+from schooltool.app.browser.report import ReportPDFView
16 from schooltool.app.interfaces import ISchoolToolApplication
17-from schooltool.course.interfaces import IInstructor
18+from schooltool.course.interfaces import IInstructor, ISectionContainer
19+from schooltool.group.interfaces import IGroupContainer
20 from schooltool.schoolyear.interfaces import ISchoolYearContainer
21+from schooltool.schoolyear.interfaces import ISchoolYear
22 from schooltool.skin.skin import NavigationViewlet
23 from schooltool.term.interfaces import ITerm
24 from schooltool.timetable.interfaces import ITimetables
25@@ -38,6 +43,10 @@
26 ERROR_INVALID_MODEL = _('Timetable model must be WeeklyTimetableModel.')
27 ERROR_TIMETABLE_MISMATCH = _('Timetables must be consistent for the term.')
28
29+TEACHER_HEADING = _('Teacher')
30+TOTAL_HEADING = _('Total')
31+SUBGROUP_HEADING = _('Sub-\ngroup')
32+
33
34 class ManageYearlyViewlet(NavigationViewlet):
35 @property
36@@ -193,3 +202,300 @@
37 results.append(result)
38 return results
39
40+
41+class SubgroupsTimetableView(BrowserView):
42+ """A view for the term's subgroup-based timetable"""
43+
44+ def __init__(self, context, request):
45+ super(SubgroupsTimetableView, self).__init__(context, request)
46+ self.term = removeSecurityProxy(self.context)
47+ self.schoolyear = ISchoolYear(self.term)
48+ self.groups = IGroupContainer(self.schoolyear)
49+
50+ def error(self, error_message):
51+ self.error_message = error_message
52+
53+ def update(self):
54+ self.error_message = ''
55+ self.data = {
56+ 'days': [],
57+ 'rows': [],
58+ }
59+
60+ subgroup_sections = {}
61+ for section in ISectionContainer(self.context).values():
62+ title = section.title.upper()
63+ subgroup_sections.setdefault(title, []).append(section)
64+
65+ for subgroup_title, sections in sorted(subgroup_sections.items()):
66+ subgroup_dict = {}
67+
68+ teacher = ''
69+ if subgroup_title in self.groups:
70+ leaders = [l for l in self.groups[subgroup_title].leaders]
71+ if leaders:
72+ teacher = leaders[0].title
73+
74+ for section in sections:
75+ titles = [course.title.lower()
76+ for course in section.courses]
77+ course_title = ', '.join(titles)
78+
79+ timetables = ITimetables(section).timetables
80+ if len(timetables.keys()) != 1:
81+ return self.error(ERROR_TOO_COMPLEX)
82+ timetable = timetables[timetables.keys()[0]]
83+ if timetable.model.factory_id != 'WeeklyTimetableModel':
84+ return self.error(ERROR_INVALID_MODEL)
85+
86+ days = [[day_id, timetable[day_id].periods]
87+ for day_id in timetable.day_ids]
88+ if not self.data['days']:
89+ self.data['days'] = days
90+ elif days != self.data['days']:
91+ return self.error(ERROR_TIMETABLE_MISMATCH)
92+
93+ for day_id, periods in days:
94+ subgroup_day = subgroup_dict.setdefault(day_id, {})
95+ for period in periods:
96+ if timetable[day_id].activities[period]:
97+ cell = subgroup_day.setdefault(period, {})
98+ cell[course_title] = 0
99+
100+ if subgroup_dict:
101+ row = {
102+ 'name': subgroup_title,
103+ 'teacher': teacher,
104+ 'days': subgroup_dict,
105+ }
106+ self.data['rows'].append(row)
107+
108+ used_days = {}
109+ for row in self.data['rows']:
110+ for day_id in row['days']:
111+ used_day = used_days.setdefault(day_id, set())
112+ for period in row['days'][day_id]:
113+ used_day.add(period)
114+
115+ adjusted_days = []
116+ for day_id, periods in days:
117+ if day_id not in used_days:
118+ continue
119+ adjusted_periods = []
120+ for period in periods:
121+ if period in used_days[day_id]:
122+ adjusted_periods.append(period)
123+ if adjusted_periods:
124+ adjusted_days.append([day_id, adjusted_periods])
125+ self.data['days'] = adjusted_days
126+
127+ def days(self):
128+ dayNames = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
129+ results = []
130+ for day_id, day_periods in self.data['days']:
131+ periods = []
132+ for period_index, value in enumerate(day_periods):
133+ if period_index == 0:
134+ cell = ' heading_left'
135+ else:
136+ cell = ' heading'
137+ cls = 'odd border_top period' + cell
138+ period = {
139+ 'class': cls,
140+ 'value': unicode(value)[:3],
141+ }
142+ periods.append(period)
143+ result = {
144+ 'text': dayNames[day_id],
145+ 'span': len(periods),
146+ 'periods': periods,
147+ }
148+ results.append(result)
149+ return results
150+
151+ def rows(self):
152+ results = []
153+ for index, row in enumerate(self.data['rows']):
154+ if index % 2 == 0:
155+ even_odd = ' even'
156+ else:
157+ even_odd = ' odd'
158+ days = []
159+ for day_id, day_periods in self.data['days']:
160+ if day_id not in row['days']:
161+ continue
162+ periods = []
163+ for period_index, period in enumerate(day_periods):
164+ if period_index == 0:
165+ cell = ' sg_cell_left'
166+ else:
167+ cell = ' sg_cell'
168+
169+ value = ''
170+ if day_id in row['days']:
171+ values = row['days'][day_id].get(period, {})
172+ value = '\n'.join([unicode(value)[:4]
173+ for value in sorted(values)])
174+
175+ cls = 'period' + even_odd + cell
176+
177+ period_cell = {
178+ 'class': cls,
179+ 'value': value,
180+ }
181+ periods.append(period_cell)
182+ days.append(periods)
183+
184+ result = {
185+ 'name': row['name'],
186+ 'teacher': row['teacher'],
187+ 'days': days,
188+ 'class': 'cell' + even_odd,
189+ 'class_left': 'cell_left' + even_odd,
190+ }
191+ results.append(result)
192+ return results
193+
194+
195+class TeachersTimetablePDFView(ReportPDFView, TeachersTimetableView):
196+ """A view for the term's teacher-based timetable pdf"""
197+
198+ template=ViewPageTemplateFile('templates/teachers_timetable_pdf.pt')
199+ pageSize = pagesizes.landscape(ReportPDFView.pageSize)
200+ rotation = 90
201+ name_width = '2.5cm'
202+ period_width = 0.55
203+ empty_width = 0.03
204+ total_width = ',1cm'
205+
206+ def __call__(self):
207+ self.term = removeSecurityProxy(self.context)
208+ self.update()
209+ return super(TeachersTimetablePDFView, self).__call__()
210+
211+ def heading_widths1(self):
212+ results = self.name_width
213+ for day in self.days():
214+ day_width = self.empty_width + day['span'] * self.period_width
215+ results += ',%fcm' % day_width
216+ results += ',%fcm' % self.empty_width
217+ results += self.total_width
218+ return results
219+
220+ def heading_widths2(self):
221+ results = self.name_width
222+ for day in self.days():
223+ results += ',%fcm' % self.empty_width
224+ for period in day['periods']:
225+ results += ',%fcm' % self.period_width
226+ results += ',%fcm' % self.empty_width
227+ results += self.total_width
228+ return results
229+
230+ def headings1(self):
231+ results = ['']
232+ for day in self.days():
233+ results.append(day['text'])
234+ results.extend(['', ''])
235+ return results
236+
237+ def headings2(self):
238+ results = [TEACHER_HEADING]
239+ for day in self.days():
240+ results.append('')
241+ for period in day['periods']:
242+ results.append(period['value'])
243+ results.extend(['', TOTAL_HEADING])
244+ return results
245+
246+ def row_heights(self):
247+ result = 1
248+ rows = self.rows()
249+ for row in rows:
250+ for day in row['days']:
251+ for period in day:
252+ size = len(period['value'].split('\n'))
253+ if size > result:
254+ result = size
255+ if result == 1:
256+ height = 0.65
257+ else:
258+ height = 0.28 * result
259+ return ','.join(['%fcm' % height] * len(rows))
260+
261+ def pdf_rows(self):
262+ results = []
263+ for row in self.rows():
264+ result_row = [row['name']]
265+ for day in row['days']:
266+ result_row.append('')
267+ for period in day:
268+ value = period['value']
269+ result_row.append(value)
270+ result_row.extend(['', row['total']])
271+ results.append(result_row)
272+ return results
273+
274+
275+class SubgroupsTimetablePDFView(ReportPDFView, SubgroupsTimetableView):
276+ """A view for the term's subgroup-based timetable pdf"""
277+
278+ template=ViewPageTemplateFile('templates/subgroups_timetable_pdf.pt')
279+ pageSize = pagesizes.landscape(ReportPDFView.pageSize)
280+ rotation = 90
281+ name_width = '1.2cm'
282+ teacher_width = ',1.7cm'
283+ period_width = 0.56
284+ empty_width = 0.03
285+
286+ def __call__(self):
287+ self.term = removeSecurityProxy(self.context)
288+ self.schoolyear = ISchoolYear(self.term)
289+ self.groups = IGroupContainer(self.schoolyear)
290+ self.update()
291+ return super(SubgroupsTimetablePDFView, self).__call__()
292+
293+ def heading_widths1(self):
294+ results = self.name_width + self.teacher_width
295+ for day in self.days():
296+ day_width = self.empty_width + day['span'] * self.period_width
297+ results += ',%fcm' % day_width
298+ return results
299+
300+ def heading_widths2(self):
301+ results = self.name_width + self.teacher_width
302+ for day in self.days():
303+ results += ',%fcm' % self.empty_width
304+ for period in day['periods']:
305+ results += ',%fcm' % self.period_width
306+ return results
307+
308+ def headings1(self):
309+ results = ['', '']
310+ for day in self.days():
311+ results.append(day['text'])
312+ return results
313+
314+ def headings2(self):
315+ results = [SUBGROUP_HEADING, TEACHER_HEADING]
316+ for day in self.days():
317+ results.append('')
318+ for period in day['periods']:
319+ results.append(period['value'])
320+ return results
321+
322+ def row_heights(self):
323+ return ','.join(['0.65cm'] * len(self.rows()))
324+
325+ def pdf_rows(self):
326+ results = []
327+ for row in self.rows():
328+ result_row = [row['name'], row['teacher']]
329+ for day in row['days']:
330+ result_row.append('')
331+ for period in day:
332+ value = period['value']
333+ result_row.append(value)
334+ results.append(result_row)
335+ return results
336+
337
338=== modified file 'src/schooltool/zambia/app/browser/configure.zcml'
339--- src/schooltool/zambia/app/browser/configure.zcml 2010-08-08 18:28:59 +0000
340+++ src/schooltool/zambia/app/browser/configure.zcml 2010-09-26 22:01:04 +0000
341@@ -52,6 +52,36 @@
342 title="Teachers Timetable"
343 order="50"
344 />
345+ <navigationViewlet
346+ name="subgroups_timetable.html"
347+ for="schooltool.term.interfaces.ITerm"
348+ manager="schooltool.skin.IActionMenuManager"
349+ template="templates/actionsViewlet.pt"
350+ permission="schooltool.edit"
351+ link="subgroups_timetable.html"
352+ title="Subgroups Timetable"
353+ order="60"
354+ />
355+ <navigationViewlet
356+ name="teachers_timetable.pdf"
357+ for="schooltool.term.interfaces.ITerm"
358+ manager="schooltool.skin.IActionMenuManager"
359+ template="templates/actionsViewlet.pt"
360+ permission="schooltool.edit"
361+ link="teachers_timetable.pdf"
362+ title="Teachers PDF"
363+ order="50"
364+ />
365+ <navigationViewlet
366+ name="subgroups_timetable.pdf"
367+ for="schooltool.term.interfaces.ITerm"
368+ manager="schooltool.skin.IActionMenuManager"
369+ template="templates/actionsViewlet.pt"
370+ permission="schooltool.edit"
371+ link="subgroups_timetable.pdf"
372+ title="Subgroups PDF"
373+ order="60"
374+ />
375 </configure>
376
377 <page
378@@ -70,5 +100,27 @@
379 permission="schooltool.edit"
380 layer="schooltool.zambia.app.skin.ISchoolToolZambiaLayer"
381 />
382+ <page
383+ name="subgroups_timetable.html"
384+ for="schooltool.term.interfaces.ITerm"
385+ class="schooltool.zambia.app.browser.app.SubgroupsTimetableView"
386+ template="templates/subgroups_timetable.pt"
387+ permission="schooltool.edit"
388+ layer="schooltool.zambia.app.skin.ISchoolToolZambiaLayer"
389+ />
390+ <page
391+ name="teachers_timetable.pdf"
392+ for="schooltool.term.interfaces.ITerm"
393+ class="schooltool.zambia.app.browser.app.TeachersTimetablePDFView"
394+ permission="schooltool.edit"
395+ layer="schooltool.zambia.app.skin.ISchoolToolZambiaLayer"
396+ />
397+ <page
398+ name="subgroups_timetable.pdf"
399+ for="schooltool.term.interfaces.ITerm"
400+ class="schooltool.zambia.app.browser.app.SubgroupsTimetablePDFView"
401+ permission="schooltool.edit"
402+ layer="schooltool.zambia.app.skin.ISchoolToolZambiaLayer"
403+ />
404
405 </configure>
406
407=== modified file 'src/schooltool/zambia/app/browser/resources/zambia.css'
408--- src/schooltool/zambia/app/browser/resources/zambia.css 2010-08-08 18:28:59 +0000
409+++ src/schooltool/zambia/app/browser/resources/zambia.css 2010-09-26 22:01:04 +0000
410@@ -51,6 +51,26 @@
411 text-align: center;
412 }
413
414+.sg_cell {
415+ height: 3.5em;
416+ padding: .2em;
417+ margin: 0em;
418+ border-left: thin solid gray;
419+ border-right: thin solid gray;
420+ color: black;
421+ text-align: center;
422+}
423+
424+.sg_cell_left {
425+ height: 3.5em;
426+ padding: .2em;
427+ margin: 0em;
428+ border-left: 3px solid gray;
429+ border-right: thin solid gray;
430+ color: black;
431+ text-align: center;
432+}
433+
434 .border_top {
435 border-top: thin solid gray;
436 }
437
438=== added file 'src/schooltool/zambia/app/browser/templates/subgroups_timetable.pt'
439--- src/schooltool/zambia/app/browser/templates/subgroups_timetable.pt 1970-01-01 00:00:00 +0000
440+++ src/schooltool/zambia/app/browser/templates/subgroups_timetable.pt 2010-09-26 22:01:04 +0000
441@@ -0,0 +1,55 @@
442+<tal:tag condition="view/update" />
443+<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool.gradebook">
444+<head>
445+ <title metal:fill-slot="title" i18n:translate="">Subgroups Timetable</title>
446+</head>
447+<body>
448+
449+<h1 metal:fill-slot="content-header"
450+ i18n:translate="">Subgroups Timetable</h1>
451+
452+<metal:block metal:fill-slot="body">
453+
454+ <h1 tal:condition="view/error_message"
455+ tal:content="view/error_message" />
456+
457+ <table tal:condition="not: view/error_message" class="teachers_timetable">
458+ <tr>
459+ <th class="heading odd"></th>
460+ <th class="heading odd"></th>
461+ <th tal:repeat="day view/days" class="heading_left odd"
462+ tal:content="day/text"
463+ tal:attributes="colspan day/span" />
464+ </tr>
465+
466+ <tr>
467+ <th class="heading odd" i18n:translate="">Subgroup</th>
468+ <th class="heading odd" i18n:translate="">Teacher</th>
469+ <tal:block repeat="day view/days">
470+ <th tal:repeat="period day/periods"
471+ tal:attributes="class period/class"
472+ tal:content="period/value" />
473+ </tal:block>
474+ </tr>
475+
476+ <tal:block repeat="row view/rows">
477+ <tr>
478+ <td tal:attributes="class row/class">
479+ <span tal:content="row/name" />
480+ </td>
481+ <td tal:attributes="class row/class">
482+ <span tal:content="row/teacher" />
483+ </td>
484+ <tal:block repeat="day row/days">
485+ <td tal:repeat="period day"
486+ tal:attributes="class period/class"
487+ tal:content="period/value" />
488+ </tal:block>
489+ </tr>
490+ </tal:block>
491+
492+ </table>
493+
494+</metal:block>
495+</body>
496+</html>
497
498=== added file 'src/schooltool/zambia/app/browser/templates/subgroups_timetable_pdf.pt'
499--- src/schooltool/zambia/app/browser/templates/subgroups_timetable_pdf.pt 1970-01-01 00:00:00 +0000
500+++ src/schooltool/zambia/app/browser/templates/subgroups_timetable_pdf.pt 2010-09-26 22:01:04 +0000
501@@ -0,0 +1,88 @@
502+<?xml version="1.0" standalone="no" ?>
503+<!DOCTYPE document SYSTEM "rml_1_0.dtd" [
504+ <!ENTITY pound "&#xA3;">
505+ <!ENTITY nbsp "&#160;">
506+]>
507+
508+<document
509+ xmlns:tal="http://xml.zope.org/namespaces/tal"
510+ xmlns:metal="http://xml.zope.org/namespaces/metal"
511+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
512+ metal:use-macro="context/@@rml_macros/report"
513+ i18n:domain="schooltool.zambia">
514+
515+<metal:block fill-slot="page_templates">
516+ <tal:block content="structure view/use_template/default" />
517+</metal:block>
518+
519+<stylesheet>
520+ <metal:block fill-slot="extra_initialize">
521+ </metal:block>
522+ <metal:block fill-slot="stylesheet">
523+
524+ <paraStyle
525+ name="heading"
526+ fontName="Arial_Bold"
527+ fontSize="9"
528+ alignment="center"
529+ leading="12"/>
530+
531+ <paraStyle
532+ name="cell"
533+ fontName="Arial_Normal"
534+ fontSize="6"
535+ alignment="center"
536+ leading="7"/>
537+
538+ <blockTableStyle id="headings_table">
539+ <blockValign value="middle" start="0,0" stop="0,-1"/>
540+ </blockTableStyle>
541+
542+ <blockTableStyle id="grid">
543+ <lineStyle kind="OUTLINE"
544+ colorName="black" thickness="0.25"
545+ start="0,0" stop="-1,-1" />
546+ <lineStyle kind="INNERGRID"
547+ colorName="black" thickness="0.25"
548+ start="0,0" stop="-1,-1" />
549+ <blockValign value="middle" start="0,0" stop="0,-1"/>
550+ </blockTableStyle>
551+ </metal:block>
552+</stylesheet>
553+
554+<story metal:fill-slot="story">
555+
556+ <blockTable style="headings_table"
557+ tal:attributes="colWidths view/heading_widths1"
558+ alignment="left">
559+ <tr>
560+ <td tal:repeat="heading view/headings1">
561+ <para style="heading" tal:content="heading" />
562+ </td>
563+ </tr>
564+ </blockTable>
565+
566+ <blockTable style="grid"
567+ tal:attributes="colWidths view/heading_widths2"
568+ alignment="left">
569+ <tr>
570+ <td tal:repeat="heading view/headings2" vAlign="middle">
571+ <para style="heading" tal:content="heading" />
572+ </td>
573+ </tr>
574+ </blockTable>
575+
576+ <blockTable style="grid"
577+ tal:attributes="colWidths view/heading_widths2;
578+ rowHeights view/row_heights"
579+ alignment="left">
580+ <tr tal:repeat="row view/pdf_rows">
581+ <td tal:repeat="cell row" vAlign="middle">
582+ <para style="cell" tal:content="cell" />
583+ </td>
584+ </tr>
585+ </blockTable>
586+
587+</story>
588+
589+</document>
590
591=== modified file 'src/schooltool/zambia/app/browser/templates/teachers_timetable.pt'
592--- src/schooltool/zambia/app/browser/templates/teachers_timetable.pt 2010-08-08 18:28:59 +0000
593+++ src/schooltool/zambia/app/browser/templates/teachers_timetable.pt 2010-09-26 22:01:04 +0000
594@@ -23,13 +23,13 @@
595 </tr>
596
597 <tr>
598- <th class="heading odd">Teacher</th>
599+ <th class="heading odd" i18n:translate="">Teacher</th>
600 <tal:block repeat="day view/days">
601 <th tal:repeat="period day/periods"
602 tal:attributes="class period/class"
603 tal:content="period/value" />
604 </tal:block>
605- <th class="heading_left odd">Periods</th>
606+ <th class="heading_left odd" i18n:translate="">Periods</th>
607 </tr>
608
609 <tal:block repeat="row view/rows">
610
611=== added file 'src/schooltool/zambia/app/browser/templates/teachers_timetable_pdf.pt'
612--- src/schooltool/zambia/app/browser/templates/teachers_timetable_pdf.pt 1970-01-01 00:00:00 +0000
613+++ src/schooltool/zambia/app/browser/templates/teachers_timetable_pdf.pt 2010-09-26 22:01:04 +0000
614@@ -0,0 +1,88 @@
615+<?xml version="1.0" standalone="no" ?>
616+<!DOCTYPE document SYSTEM "rml_1_0.dtd" [
617+ <!ENTITY pound "&#xA3;">
618+ <!ENTITY nbsp "&#160;">
619+]>
620+
621+<document
622+ xmlns:tal="http://xml.zope.org/namespaces/tal"
623+ xmlns:metal="http://xml.zope.org/namespaces/metal"
624+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
625+ metal:use-macro="context/@@rml_macros/report"
626+ i18n:domain="schooltool.zambia">
627+
628+<metal:block fill-slot="page_templates">
629+ <tal:block content="structure view/use_template/default" />
630+</metal:block>
631+
632+<stylesheet>
633+ <metal:block fill-slot="extra_initialize">
634+ </metal:block>
635+ <metal:block fill-slot="stylesheet">
636+
637+ <paraStyle
638+ name="heading"
639+ fontName="Arial_Bold"
640+ fontSize="9"
641+ alignment="center"
642+ leading="12"/>
643+
644+ <paraStyle
645+ name="cell"
646+ fontName="Arial_Normal"
647+ fontSize="6"
648+ alignment="center"
649+ leading="7"/>
650+
651+ <blockTableStyle id="headings_table">
652+ <blockValign value="top" start="0,0" stop="0,-1"/>
653+ </blockTableStyle>
654+
655+ <blockTableStyle id="grid">
656+ <lineStyle kind="OUTLINE"
657+ colorName="black" thickness="0.25"
658+ start="0,0" stop="-1,-1" />
659+ <lineStyle kind="INNERGRID"
660+ colorName="black" thickness="0.25"
661+ start="0,0" stop="-1,-1" />
662+ <blockValign value="top" start="0,0" stop="0,-1"/>
663+ </blockTableStyle>
664+ </metal:block>
665+</stylesheet>
666+
667+<story metal:fill-slot="story">
668+
669+ <blockTable style="headings_table"
670+ tal:attributes="colWidths view/heading_widths1"
671+ alignment="left">
672+ <tr>
673+ <td tal:repeat="heading view/headings1">
674+ <para style="heading" tal:content="heading" />
675+ </td>
676+ </tr>
677+ </blockTable>
678+
679+ <blockTable style="grid"
680+ tal:attributes="colWidths view/heading_widths2"
681+ alignment="left">
682+ <tr>
683+ <td tal:repeat="heading view/headings2">
684+ <para style="heading" tal:content="heading" />
685+ </td>
686+ </tr>
687+ </blockTable>
688+
689+ <blockTable style="grid"
690+ tal:attributes="colWidths view/heading_widths2;
691+ rowHeights view/row_heights"
692+ alignment="left">
693+ <tr tal:repeat="row view/pdf_rows">
694+ <td tal:repeat="cell row" vAlign="middle">
695+ <para style="cell" tal:content="cell" />
696+ </td>
697+ </tr>
698+ </blockTable>
699+
700+</story>
701+
702+</document>

Subscribers

People subscribed via source and target branches