Exemplo n.º 1
0
    def parse_cals_table(self, cals_table):
        """
        Parse a CALS ``table`` element.

        :type  cals_table: ElementType
        :param cals_table: CALS table Element.

        :return: State of the parser (for debug purpose).

        .. versionchanged:: 0.5.1
           Add support for the ``@cals:width`` attribute (table width).
        """
        cals = self.get_cals_qname
        styles = {}
        nature = None

        # -- attribute @cals:frame
        frame = cals_table.attrib.get(cals("frame"))
        styles.update(get_frame_styles(frame))

        # -- attribute @cals:colsep
        colsep = cals_table.attrib.get(cals("colsep"))
        colsep_map = {"0": BORDER_NONE, "1": BORDER_SOLID}
        if colsep in colsep_map:
            styles["x-cell-border-right"] = colsep_map[colsep]

        # -- attribute @cals:rowsep
        rowsep = cals_table.attrib.get(cals("rowsep"))
        rowsep_map = {"0": BORDER_NONE, "1": BORDER_SOLID}
        if rowsep in rowsep_map:
            styles["x-cell-border-bottom"] = rowsep_map[rowsep]

        # -- attribute @cals:orient
        orient = cals_table.attrib.get(cals("orient"))
        orient_map = {"land": "landscape", "port": "portrait"}
        if orient in orient_map:
            styles["x-sect-orient"] = orient_map[orient]

        # -- attribute @cals:pgwide
        pgwide = cals_table.attrib.get(cals("pgwide"))
        pgwide_map = {"0": "2", "1": "1"}
        if pgwide in pgwide_map:
            styles["x-sect-cols"] = pgwide_map[pgwide]

        # -- attribute @cals:bgcolor
        bgcolor = cals_table.attrib.get(cals("bgcolor"))
        if bgcolor:
            styles["background-color"] = bgcolor

        # -- attribute @cals:tabstyle
        tabstyle = cals_table.attrib.get(cals("tabstyle"))
        if tabstyle:
            nature = tabstyle

        # -- attribute @cals:tabstyle
        width = cals_table.attrib.get(cals("width"))
        if width:
            width, unit = parse_width(width)
            value = convert_value(width, unit, self.width_unit)
            styles["width"] = u"{value:0.2f}{unit}".format(value=value, unit=self.width_unit)

        return self.setup_table(styles, nature)
Exemplo n.º 2
0
    def build_table(self, table):
        """
        Build the CALS ``<table>`` element.

        CALS attributes:

        -   ``@frame`` is built from the "border-top", "border-right", "border-bottom", "border-left" styles.
            Default value is "none" (no frame).

        -   ``@colsep`` is built from the "x-cell-border-right" style.
            Default value is "0" (not displayed).

        -   ``@rowsep`` is built from the "x-cell-border-bottom" style.
            Default value is "0" (not displayed).

        -   ``@tabstyle`` is built from the table nature.

        -   ``@orient`` is built from the "x-sect-orient" style (orientation of the current section).
            Possible values are "port" (portrait, the default) or "land" (landscape).

        -   ``@pgwide`` is built from the "x-sect-cols" style (column number of the current section).
            Default value is "0" (width of the current column).

        -   ``@bgcolor`` is built from the "background-color" style (HTML color).

        -   ``@width`` is built from the "width" style (percentage or width with unit).
            This attribute in an extension.

        .. note::

           ``@colsep``, ``@rowsep`` and ``@tabstyle`` attributes are generated only
           if the *table_in_tgroup* options is ``False``.

        .. attention::

           According to the `CALS specification <https://www.oasis-open.org/specs/tm9502.html#c37ab3>`_,
           the default value for ``@colsep`` and ``@rowsep`` should be "1".
           But, having this value as a default is really problematic for conversions:
           most of nowadays formats, like Office Open XML and CSS, consider that the default
           value is "no border" (a.k.a: ``border: none``).
           So, setting "0" as a default value is a better choice.

        :type  table: benker.table.Table
        :param table: Table

        :return: The newly-created ``<table>`` element.

        .. versionchanged:: 0.5.0
           Add support for the ``bgcolor`` attribute (background color).

        .. versionchanged:: 0.5.1
           Add support for the ``@width`` attribute (table width).
        """
        self.setup_table(table)

        # support for CALS namespace
        cals = self.cals_ns.get_qname
        table_styles = table.styles
        attrs = {cals('frame'): get_frame_attr(table_styles)}
        if not self.table_in_tgroup:
            self._table_colsep = attrs[cals(
                "colsep")] = get_colsep_attr(table_styles) or "0"
            self._table_rowsep = attrs[cals(
                "rowsep")] = get_rowsep_attr(table_styles) or "0"
            if table.nature is not None:
                attrs[cals("tabstyle")] = table.nature
        if "x-sect-orient" in table_styles:
            attrs[cals("orient")] = {
                "landscape": "land",
                "portrait": "port"
            }[table_styles["x-sect-orient"]]
        if "x-sect-cols" in table_styles:
            attrs[cals(
                "pgwide")] = "1" if table_styles["x-sect-cols"] == "1" else "0"
        if "background-color" in table_styles:
            attrs[cals("bgcolor")] = table_styles["background-color"]
        if "width" in table_styles:
            width, unit = parse_width(table_styles["width"])
            value = convert_value(width, unit, self.width_unit)
            attrs[cals("width")] = u"{value:0.2f}{unit}".format(
                value=value, unit=self.width_unit)

        table_elem = etree.Element(cals(u"table"),
                                   attrib=attrs,
                                   nsmap=self.ns_map)
        self.build_tgroup(table_elem, table)
        return table_elem
Exemplo n.º 3
0
    def build_colspec(self, group_elem, col):
        """
        Build the CALS ``<colspec>`` element.

        CALS attributes:

        -   ``@colnum`` is the column number.

        -   ``@colname`` is the column name. Its format is "c{col_pos}".

        -   ``@colwidth`` width of the column (with its unit).
            The unit is defined by the *width_unit* options.

        -   ``@align`` horizontal alignment of table entry content.
            Possible values are: "left", "right", "center", "justify" ("char" is not supported).

        -   ``@colsep`` column separators (vertical ruling).
            Possible values are "0" or "1".

        -   ``@colsep`` row separators (horizontal ruling).
            Possible values are "0" or "1".

        :type  group_elem: ElementType
        :param group_elem: Parent element: ``<tgroup>``.

        :type  col: benker.table.ColView
        :param col: Columns

        .. versionchanged:: 0.5.0
           The ``@colnum`` and ``@align`` attributes are generated.

        .. versionchanged:: 0.5.1
           The ``@colsep`` and ``@rowsep`` attributes are generated.
        """
        # support for CALS namespace
        cals = self.cals_ns.get_qname
        col_styles = col.styles

        # -- @cals:colnum
        # -- @cals:colname
        attrs = {
            cals(u"colnum"): u"{0}".format(col.col_pos),
            cals(u"colname"): u"c{0}".format(col.col_pos)
        }

        # -- @cals:colwidth
        if "width" in col_styles:
            width, unit = parse_width(col_styles["width"])
            value = convert_value(width, unit, self.width_unit)
            attrs[cals("colwidth")] = u"{value:0.2f}{unit}".format(
                value=value, unit=self.width_unit)

        # -- @cals:align
        align = col_styles.get("align")
        align_map = {
            "left": "left",
            "right": "right",
            "center": "center",
            "justify": "justify"
        }
        if align in align_map:
            attrs[cals("align")] = align_map[align]

        cell_colsep = get_colsep_attr(col_styles, "border-right")
        if cell_colsep and cell_colsep != self._table_colsep:
            attrs[cals("colsep")] = cell_colsep

        cell_rowsep = get_rowsep_attr(col_styles, "border-bottom")
        if cell_rowsep and cell_rowsep != self._table_rowsep:
            attrs[cals("rowsep")] = cell_rowsep

        etree.SubElement(group_elem,
                         cals(u"colspec"),
                         attrib=attrs,
                         nsmap=self.ns_map)
Exemplo n.º 4
0
    def build_corpus(self, tbl_elem, table):
        """
        Build the Formex 4 ``<CORPUS>`` element.

        :type  tbl_elem: ElementType
        :param tbl_elem: Parent element: ``<TBL>``.

        :type  table: benker.table.Table
        :param table: Table

        .. versionchanged:: 0.5.1
            If this option *detect_titles* is enable, a title will be generated
            if the first row contains an unique cell with centered text.

        .. versionchanged:: 0.5.1
           Add support for the ``@width`` CALS-like attribute (table width).
        """
        table_styles = table.styles
        attrs = {}  # no attribute
        rows = list(table.rows)

        if self.detect_titles:
            # Does the first row/cell contains a centered title?
            first_cell = table[(1, 1)]
            align = first_cell.styles.get("align")
            if first_cell.width == table.bounding_box.width and align == "center":
                # yes, we can generate the title
                self.build_title(tbl_elem, rows.pop(0))

        # support for CALS-like elements and attributes
        if self.use_cals:
            cals = self.get_cals_qname
            attrs[cals("frame")] = get_frame_attr(table_styles)
            self._table_colsep = attrs[cals(
                "colsep")] = get_colsep_attr(table_styles) or "0"
            self._table_rowsep = attrs[cals(
                "rowsep")] = get_rowsep_attr(table_styles) or "0"
            if table.nature is not None:
                attrs[cals("tabstyle")] = table.nature
            if "x-sect-orient" in table_styles:
                attrs[cals("orient")] = {
                    "landscape": "land",
                    "portrait": "port"
                }[table_styles["x-sect-orient"]]
            if "x-sect-cols" in table_styles:
                attrs[cals(
                    "pgwide"
                )] = "1" if table_styles["x-sect-cols"] == "1" else "0"
            if "background-color" in table_styles:
                attrs[cals("bgcolor")] = table_styles["background-color"]
            if "width" in table_styles:
                width, unit = parse_width(table_styles["width"])
                value = convert_value(width, unit, self.width_unit)
                attrs[cals("width")] = u"{value:0.2f}{unit}".format(
                    value=value, unit=self.width_unit)

        corpus_elem = etree.SubElement(tbl_elem, u"CORPUS", attrib=attrs)

        # support for CALS-like elements and attributes
        if self.use_cals:
            for col in table.cols:
                self.build_colspec(corpus_elem, col)

        for row in rows:
            self.build_row(corpus_elem, row)