Source code for pytablewriter.writer.text._css

import copy
from typing import Any, List, cast

from dataproperty import NOT_QUOTING_FLAGS, DataProperty
from pathvalidate import replace_symbol

from ...error import EmptyTableDataError
from ...style import Align, DecorationLine, FontStyle, FontWeight, Style, VerticalAlign
from .._common import HEADER_ROW
from ._text_writer import IndentationTextTableWriter


[docs] class CssTableWriter(IndentationTextTableWriter): """ A CSS writer class. """ FORMAT_NAME = "css" MARGIN_PIXEL = 6 @property def format_name(self) -> str: return self.FORMAT_NAME @property def support_split_write(self) -> bool: return False def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) self.is_padding = False self.indent_string = kwargs.get("indent_string", " ") self._dp_extractor.preprocessor.is_escape_html_tag = False self._quoting_flags = copy.deepcopy(NOT_QUOTING_FLAGS)
[docs] def write_table(self, **kwargs: Any) -> None: """ |write_table| with CSS. """ with self._logger: try: self._verify_property() except EmptyTableDataError: self._logger.logger.debug("no tabular data found") return self._preprocess() self.__write_css( css_class=replace_symbol(self.table_name, replacement_text="-"), write_style_tag=kwargs.get("write_style_tag", False), )
def __extract_css_tags(self, value_dp: DataProperty, style: Style) -> List[str]: css_tags: List[str] = [] if self._styler.get_font_size(style): css_tags.append(cast(str, self._styler.get_font_size(style))) if style.font_weight == FontWeight.BOLD: css_tags.append("font-weight:bold") if style.font_style == FontStyle.ITALIC: css_tags.append("font-style:italic") if style.color: css_tags.append(f"color: {style.color.color_code}") if style.bg_color: css_tags.append(f"background-color: {style.bg_color.color_code}") css_tag = self.__extract_align_tag(value_dp, style) if css_tag: css_tags.append(css_tag) if style.vertical_align != VerticalAlign.BASELINE: css_tags.append(f"vertical-align: {style.vertical_align.align_str}") if style.decoration_line in (DecorationLine.LINE_THROUGH, DecorationLine.STRIKE): css_tags.append("text-decoration-line: line-through") elif style.decoration_line == DecorationLine.UNDERLINE: css_tags.append("text-decoration-line: underline") if self.margin > 0: css_tags.append(f"padding: {self.margin * self.MARGIN_PIXEL}px") return css_tags def __extract_align_tag(self, value_dp: DataProperty, style: Style) -> str: if style.align == Align.AUTO: value = value_dp.align.align_string else: value = style.align.align_string return f"text-align: {value}" def __write_css_thead(self, css_class: str, base_indent_level: int) -> None: for col_dp, header_dp in zip(self._column_dp_list, self._dp_extractor.to_header_dp_list()): style = self._fetch_style(HEADER_ROW, col_dp, header_dp) css_tags = self.__extract_css_tags(header_dp, style) if not css_tags: continue self.set_indent_level(base_indent_level) self._write_line( ".{css_class} thead th:nth-child({col}) {{".format( css_class=css_class, col=col_dp.column_index + 1 ) ) self.set_indent_level(base_indent_level + 1) for css_tag in css_tags: self._write_line(f"{css_tag};") self.set_indent_level(base_indent_level) self._write_line("}") def __write_css_tbody(self, css_class: str, base_indent_level: int) -> None: for row_idx, (values, value_dp_list) in enumerate( zip(self._table_value_matrix, self._table_value_dp_matrix) ): for value, value_dp, col_dp in zip(values, value_dp_list, self._column_dp_list): style = self._fetch_style(row_idx, col_dp, value_dp) css_tags = self.__extract_css_tags(value_dp, style) if not css_tags: continue self.set_indent_level(base_indent_level) self._write_line( ".{css_class} tbody tr:nth-child({row}) td:nth-child({col}) {{".format( css_class=css_class, row=row_idx + 1, col=col_dp.column_index + 1 ) ) self.set_indent_level(base_indent_level + 1) for css_tag in css_tags: self._write_line(f"{css_tag};") self.set_indent_level(base_indent_level) self._write_line("}") def __write_css(self, css_class: str, write_style_tag: bool = False) -> None: base_indent_level = 0 if write_style_tag: self._write_line('<style type="text/css">') base_indent_level = 1 self.__write_css_thead(css_class, base_indent_level) self.__write_css_tbody(css_class, base_indent_level) if write_style_tag: self.set_indent_level(0) self._write_line("</style>")