ext/xhtml2fo.py
branchstable
changeset 5425 7c84e3f370de
parent 5421 8167de96c523
parent 5423 e15abfdcce38
child 5426 0d4853a6e5ee
equal deleted inserted replaced
5421:8167de96c523 5425:7c84e3f370de
     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