1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 from xml.etree.ElementTree import QName |
|
19 from pysixt.standard.xhtml_xslfo.transformer import XHTML2FOTransformer |
|
20 from pysixt.utils.xslfo.standard import cm |
|
21 from pysixt.utils.xslfo import SimplePageMaster |
|
22 from pysixt.standard.xhtml_xslfo.default_styling import default_styles |
|
23 from pysixt.standard.xhtml_xslfo import XHTML_NS |
|
24 |
|
25 |
|
26 class ReportTransformer(XHTML2FOTransformer): |
|
27 """ |
|
28 Class transforming an XHTML input tree into a FO document |
|
29 displaying reports (one report for each <div class="contentmain"> |
|
30 element in the input tree. |
|
31 """ |
|
32 |
|
33 def __init__(self, section, |
|
34 page_width=21.0, page_height=29.7, |
|
35 margin_top=1.0, margin_bottom=1.0, |
|
36 margin_left=1.0, margin_right=1.0, |
|
37 header_footer_height=0.75, |
|
38 standard_font_size=11.0, default_lang=u"fr" ): |
|
39 """ |
|
40 Initializes a transformer turning an XHTML input tree |
|
41 containing <div class="contentmain"> elements representing |
|
42 main content sections into a FO output tree displaying the |
|
43 reports. |
|
44 |
|
45 page_width: float - width of the page (in cm) |
|
46 page_height: float - height of the page (in cm) |
|
47 margin_top: float - top margin of the page (in cm) |
|
48 margin_bottom: float - bottom margin of the page (in cm) |
|
49 margin_left: float - left margin of the page (in cm) |
|
50 margin_right: float - right margin of the page (in cm) |
|
51 header_footer_height: float - height of the header or the footer of the |
|
52 page that the page number (if any) will be |
|
53 inserted in. |
|
54 standard_font_size: float - standard size of the font (in pt) |
|
55 default_lang: u"" - default language (used for hyphenation) |
|
56 """ |
|
57 self.section = section |
|
58 self.page_width = page_width |
|
59 self.page_height = page_height |
|
60 |
|
61 self.page_tmargin = margin_top |
|
62 self.page_bmargin = margin_bottom |
|
63 self.page_lmargin = margin_left |
|
64 self.page_rmargin = margin_right |
|
65 |
|
66 self.hf_height = header_footer_height |
|
67 |
|
68 self.font_size = standard_font_size |
|
69 self.lang = default_lang |
|
70 |
|
71 XHTML2FOTransformer.__init__(self) |
|
72 |
|
73 |
|
74 def define_pagemasters(self): |
|
75 """ |
|
76 Defines the page masters for the FO output document. |
|
77 """ |
|
78 pm = SimplePageMaster(u"page-report") |
|
79 pm.set_page_dims( self.page_width*cm, self.page_height*cm ) |
|
80 pm.set_page_margins({u'top' : self.page_tmargin*cm, |
|
81 u'bottom': self.page_bmargin*cm, |
|
82 u'left' : self.page_lmargin*cm, |
|
83 u'right' : self.page_rmargin*cm }) |
|
84 pm.add_peripheral_region(u"end", self.hf_height) |
|
85 dims = {} |
|
86 dims[u"bottom"] = self.hf_height + 0.25 |
|
87 pm.set_main_region_margins(dims) |
|
88 return [pm] |
|
89 |
|
90 def _visit_report(self, in_elt, _out_elt, params): |
|
91 """ |
|
92 Specific visit function for the input <div> elements whose class is |
|
93 "report". The _root_visit method of this class selects these input |
|
94 elements and asks the process of these elements with this specific |
|
95 visit function. |
|
96 """ |
|
97 |
|
98 ps = self.create_pagesequence(u"page-report") |
|
99 props = { u"force-page-count": u"no-force", |
|
100 u"initial-page-number": u"1", |
|
101 u"format": u"1", } |
|
102 self._output_properties(ps, props) |
|
103 |
|
104 sc = self.create_staticcontent(ps, u"end") |
|
105 sc_bl = self.create_block(sc) |
|
106 attrs = { u"hyphenate": u"false", } |
|
107 attrs[u"font-size"] = u"%.1fpt" % (self.font_size * 0.7) |
|
108 attrs[u"language"] = self.lang |
|
109 attrs[u"text-align"] = u"center" |
|
110 self._output_properties(sc_bl, attrs) |
|
111 sc_bl.text = u"Page" + u" " # ### Should be localised! |
|
112 pn = self.create_pagenumber(sc_bl) |
|
113 pn.tail = u"/" |
|
114 self.create_pagenumbercitation( |
|
115 sc_bl, u"last-block-of-report-%d" % params[u"context_pos"]) |
|
116 |
|
117 fl = self.create_flow(ps, u"body") |
|
118 bl = self.create_block(fl) |
|
119 |
|
120 # Sets on the highest block element the properties of the XHTML body |
|
121 # element. These properties (at the least the inheritable ones) will |
|
122 # be inherited by all the future FO elements. |
|
123 bodies = list(self.in_tree.getiterator(QName(XHTML_NS, u"body"))) |
|
124 if len(bodies) > 0: |
|
125 attrs = self._extract_properties([bodies[0]]) |
|
126 else: |
|
127 attrs = default_styles[u"body"].copy() |
|
128 attrs[u"font-size"] = u"%.1fpt" % self.font_size |
|
129 attrs[u"language"] = self.lang |
|
130 self._output_properties(bl,attrs) |
|
131 |
|
132 # Processes the report content |
|
133 self._copy_text(in_elt, bl) |
|
134 self._process_nodes(in_elt.getchildren(), bl) |
|
135 |
|
136 # Inserts an empty block at the end of the report in order to be able |
|
137 # to compute the last page number of this report. |
|
138 last_bl = self.create_block(bl) |
|
139 props = { u"keep-with-previous": u"always", } |
|
140 props[u"id"] = u"last-block-of-report-%d" % params[u"context_pos"] |
|
141 self._output_properties(last_bl,props) |
|
142 |
|
143 |
|
144 def _root_visit(self): |
|
145 """ |
|
146 Visit function called when starting the process of the input tree. |
|
147 """ |
|
148 content = [ d for d in self.in_tree.getiterator(QName(XHTML_NS, u"div")) |
|
149 if d.get(u"id") == self.section ] |
|
150 # Asks the process of the report elements with a specific visit |
|
151 # function |
|
152 self._process_nodes(content, self.fo_root, |
|
153 with_function=self._visit_report) |
|
154 |
|