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)
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
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)
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)