|
1 from cubicweb.utils import can_do_pdf_conversion |
|
2 assert can_do_pdf_conversion() |
|
3 |
|
4 from xml.etree.ElementTree import QName, fromstring |
|
5 from pyxmltrf.standard.xhtml_xslfo.transformer import XHTML2FOTransformer |
|
6 from pyxmltrf.utils.xslfo.standard import cm |
|
7 from pyxmltrf.utils.xslfo import SimplePageMaster |
|
8 from pyxmltrf.standard.xhtml_xslfo.default_styling import default_styles |
|
9 from pyxmltrf.standard.xhtml_xslfo import XHTML_NS |
|
10 |
|
11 |
|
12 class ReportTransformer(XHTML2FOTransformer): |
|
13 """ |
|
14 Class transforming an XHTML input tree into a FO document |
|
15 displaying reports (one report for each <div class="contentmain"> |
|
16 element in the input tree. |
|
17 """ |
|
18 |
|
19 def __init__(self, section, |
|
20 page_width=21.0, page_height=29.7, |
|
21 margin_top=1.0, margin_bottom=1.0, |
|
22 margin_left=1.0, margin_right=1.0, |
|
23 header_footer_height=0.75, |
|
24 standard_font_size=11.0, default_lang=u"fr" ): |
|
25 """ |
|
26 Initializes a transformer turning an XHTML input tree |
|
27 containing <div class="contentmain"> elements representing |
|
28 main content sections into a FO output tree displaying the |
|
29 reports. |
|
30 |
|
31 page_width: float - width of the page (in cm) |
|
32 page_height: float - height of the page (in cm) |
|
33 margin_top: float - top margin of the page (in cm) |
|
34 margin_bottom: float - bottom margin of the page (in cm) |
|
35 margin_left: float - left margin of the page (in cm) |
|
36 margin_right: float - right margin of the page (in cm) |
|
37 header_footer_height: float - height of the header or the footer of the |
|
38 page that the page number (if any) will be |
|
39 inserted in. |
|
40 standard_font_size: float - standard size of the font (in pt) |
|
41 default_lang: u"" - default language (used for hyphenation) |
|
42 """ |
|
43 self.section = section |
|
44 self.page_width = page_width |
|
45 self.page_height = page_height |
|
46 |
|
47 self.page_tmargin = margin_top |
|
48 self.page_bmargin = margin_bottom |
|
49 self.page_lmargin = margin_left |
|
50 self.page_rmargin = margin_right |
|
51 |
|
52 self.hf_height = header_footer_height |
|
53 |
|
54 self.font_size = standard_font_size |
|
55 self.lang = default_lang |
|
56 |
|
57 XHTML2FOTransformer.__init__(self) |
|
58 |
|
59 |
|
60 def define_pagemasters(self): |
|
61 """ |
|
62 Defines the page masters for the FO output document. |
|
63 """ |
|
64 pm = SimplePageMaster(u"page-report") |
|
65 pm.set_page_dims( self.page_width*cm, self.page_height*cm ) |
|
66 pm.set_page_margins({u'top' : self.page_tmargin*cm, |
|
67 u'bottom': self.page_bmargin*cm, |
|
68 u'left' : self.page_lmargin*cm, |
|
69 u'right' : self.page_rmargin*cm }) |
|
70 pm.add_peripheral_region(u"end",self.hf_height) |
|
71 dims = {} |
|
72 dims[u"bottom"] = self.hf_height + 0.25 |
|
73 pm.set_main_region_margins(dims) |
|
74 return [pm] |
|
75 |
|
76 def _visit_report(self, in_elt, _out_elt, params): |
|
77 """ |
|
78 Specific visit function for the input <div> elements whose class is |
|
79 "report". The _root_visit method of this class selects these input |
|
80 elements and asks the process of these elements with this specific |
|
81 visit function. |
|
82 """ |
|
83 |
|
84 ps = self.create_pagesequence(u"page-report") |
|
85 props = { u"force-page-count": u"no-force", |
|
86 u"initial-page-number": u"1", |
|
87 u"format": u"1", } |
|
88 self._output_properties(ps,props) |
|
89 |
|
90 sc = self.create_staticcontent(ps, u"end") |
|
91 sc_bl = self.create_block(sc) |
|
92 attrs = { u"hyphenate": u"false", } |
|
93 attrs[u"font-size"] = u"%.1fpt" %(self.font_size*0.7) |
|
94 attrs[u"language"] = self.lang |
|
95 attrs[u"text-align"] = u"center" |
|
96 self._output_properties(sc_bl,attrs) |
|
97 sc_bl.text = u"Page" + u" " # ### Should be localised! |
|
98 pn = self.create_pagenumber(sc_bl) |
|
99 pn.tail = u"/" |
|
100 lpn = self.create_pagenumbercitation( sc_bl, |
|
101 u"last-block-of-report-%d" % params[u"context_pos"] |
|
102 ) |
|
103 |
|
104 |
|
105 fl = self.create_flow(ps,u"body") |
|
106 bl = self.create_block(fl) |
|
107 |
|
108 # Sets on the highest block element the properties of the XHTML body |
|
109 # element. These properties (at the least the inheritable ones) will |
|
110 # be inherited by all the future FO elements. |
|
111 bodies = list(self.in_tree.getiterator(QName(XHTML_NS,u"body"))) |
|
112 if len(bodies) > 0: |
|
113 attrs = self._extract_properties([bodies[0]]) |
|
114 else: |
|
115 attrs = default_styles[u"body"].copy() |
|
116 attrs[u"font-size"] = u"%.1fpt" %self.font_size |
|
117 attrs[u"language"] = self.lang |
|
118 self._output_properties(bl,attrs) |
|
119 |
|
120 # Processes the report content |
|
121 self._copy_text(in_elt,bl) |
|
122 self._process_nodes(in_elt.getchildren(),bl) |
|
123 |
|
124 # Inserts an empty block at the end of the report in order to be able |
|
125 # to compute the last page number of this report. |
|
126 last_bl = self.create_block(bl) |
|
127 props = { u"keep-with-previous": u"always", } |
|
128 props[u"id"] = u"last-block-of-report-%d" % params[u"context_pos"] |
|
129 self._output_properties(last_bl,props) |
|
130 |
|
131 |
|
132 def _root_visit(self): |
|
133 """ |
|
134 Visit function called when starting the process of the input tree. |
|
135 """ |
|
136 content = [ d for d in self.in_tree.getiterator(QName(XHTML_NS,u"div")) |
|
137 if d.get(u"id") == self.section ] |
|
138 # Asks the process of the report elements with a specific visit |
|
139 # function |
|
140 self._process_nodes(content, self.fo_root, |
|
141 with_function=self._visit_report) |
|
142 |