Implement HTML indentation

This commit is contained in:
Daniel Rojas 2021-10-18 12:20:40 +02:00 committed by KV
parent d348ebe4ce
commit 1f8dd49eb9
3 changed files with 40 additions and 52 deletions

View File

@ -34,8 +34,8 @@ from wireviz.wv_bom import (
from wireviz.wv_colors import get_color_hex, translate_color from wireviz.wv_colors import get_color_hex, translate_color
from wireviz.wv_gv_html import ( from wireviz.wv_gv_html import (
gv_connector_loops, gv_connector_loops,
gv_node_connector,
gv_node_cable, gv_node_cable,
gv_node_connector,
html_bgcolor, html_bgcolor,
html_bgcolor_attr, html_bgcolor_attr,
html_caption, html_caption,

View File

@ -5,7 +5,7 @@ from itertools import zip_longest
from typing import List, Optional, Union from typing import List, Optional, Union
from wireviz.DataClasses import Cable, Color, Connector, Options from wireviz.DataClasses import Cable, Color, Connector, Options
from wireviz.wv_colors import translate_color, get_color_hex from wireviz.wv_colors import get_color_hex, translate_color
from wireviz.wv_helper import pn_info_string, remove_links from wireviz.wv_helper import pn_info_string, remove_links
from wireviz.wv_table_util import * # TODO: explicitly import each needed tag later from wireviz.wv_table_util import * # TODO: explicitly import each needed tag later
@ -90,9 +90,9 @@ def gv_node_connector(connector: Connector, harness_options: Options) -> Table:
def gv_pin_row(pin_index, pin_name, pin_label, pin_color, connector): def gv_pin_row(pin_index, pin_name, pin_label, pin_color, connector):
cell_pin_left = Td(pin_name, attribs={"port": f"p{pin_index+1}l"}, flat=True) cell_pin_left = Td(pin_name, attribs={"port": f"p{pin_index+1}l"})
cell_pin_label = Td(pin_label, flat=True, empty_is_none=True) cell_pin_label = Td(pin_label, empty_is_none=True)
cell_pin_right = Td(pin_name, attribs={"port": f"p{pin_index+1}r"}, flat=True) cell_pin_right = Td(pin_name, attribs={"port": f"p{pin_index+1}r"})
cells = [ cells = [
cell_pin_left if connector.ports_left else None, cell_pin_left if connector.ports_left else None,
@ -203,8 +203,9 @@ def gv_conductor_table(cable, harness_options, pad) -> Table:
return tbl return tbl
def gv_wire_cell(index, color, pad) -> Td: def gv_wire_cell(index, color, pad) -> Td:
bgcolors = ['#000000'] + get_color_hex(color, pad=pad) + ['#000000'] bgcolors = ["#000000"] + get_color_hex(color, pad=pad) + ["#000000"]
wire_inner_rows = [] wire_inner_rows = []
for j, bgcolor in enumerate(bgcolors[::-1]): for j, bgcolor in enumerate(bgcolors[::-1]):
wire_inner_cell_attribs = { wire_inner_cell_attribs = {
@ -229,7 +230,6 @@ def gv_wire_cell(index, color, pad) -> Td:
return wire_outer_cell return wire_outer_cell
def colored_cell(contents, bgcolor) -> Td: def colored_cell(contents, bgcolor) -> Td:
if bgcolor: if bgcolor:
attribs = {"bgcolor": translate_color(bgcolor, "HEX")} attribs = {"bgcolor": translate_color(bgcolor, "HEX")}
@ -267,7 +267,6 @@ def image_and_caption_cells(component):
Td( Td(
html_caption_new(component.image), html_caption_new(component.image),
attribs=row_caption_attribs, attribs=row_caption_attribs,
flat=True,
) )
] ]
else: else:
@ -301,7 +300,7 @@ def nested_table(rows_in: List[Tr]):
inner_cells.append(cell) inner_cells.append(cell)
else: else:
inner_cell_attribs = {"balign": "left"} inner_cell_attribs = {"balign": "left"}
inner_cells.append(Td(cell, attribs=inner_cell_attribs, flat=True)) inner_cells.append(Td(cell, attribs=inner_cell_attribs))
inner_table_attribs = { inner_table_attribs = {
"border": 0, "border": 0,

View File

@ -4,6 +4,8 @@ from collections.abc import Iterable
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, List, Optional from typing import Dict, List, Optional
indent_count = 1
class Attribs(Dict): class Attribs(Dict):
def __repr__(self): def __repr__(self):
@ -42,23 +44,40 @@ class Tag:
def tagname(self): def tagname(self):
return type(self).__name__.lower() return type(self).__name__.lower()
@property
def auto_flat(self):
if self.flat: # force flat
return True
if not _is_iterable_not_str(self.contents): # catch str, int, float, ...
if not isinstance(self.contents, Tag): # avoid recursion
return not "\n" in str(self.contents) # flatten if single line
def indent_lines(self, lines):
if self.auto_flat:
return lines
else:
indenter = " " * indent_count
return "\n".join(f"{indenter}{line}" for line in lines.split("\n"))
def get_contents(self): def get_contents(self):
separator = "" if self.flat else "\n" separator = "" if self.auto_flat else "\n"
if isinstance(self.contents, Iterable) and not isinstance(self.contents, str): if _is_iterable_not_str(self.contents):
return separator.join([str(c) for c in self.contents if c is not None]) return separator.join(
[self.indent_lines(str(c)) for c in self.contents if c is not None]
)
elif self.contents is None: elif self.contents is None:
return "" return ""
else: else: # str, int, float, etc.
return str(self.contents) return self.indent_lines(str(self.contents))
def __repr__(self): def __repr__(self):
separator = "" if self.flat else "\n" separator = "" if self.auto_flat else "\n"
if self.contents is None and self.empty_is_none: if self.contents is None and self.empty_is_none:
return "" return ""
else: else:
html = [ html = [
f"<{self.tagname}{str(self.attribs)}>", f"<{self.tagname}{str(self.attribs)}>",
self.get_contents(), f"{self.get_contents()}",
f"</{self.tagname}>", f"</{self.tagname}>",
] ]
return separator.join(html) return separator.join(html)
@ -70,6 +89,11 @@ class TagSingleton(Tag):
return f"<{self.tagname}{str(self.attribs)} />" return f"<{self.tagname}{str(self.attribs)} />"
def _is_iterable_not_str(inp):
# str is iterable, but should be treated as not iterable
return isinstance(inp, Iterable) and not isinstance(inp, str)
@dataclass @dataclass
class Br(TagSingleton): class Br(TagSingleton):
pass pass
@ -77,46 +101,11 @@ class Br(TagSingleton):
class Td(Tag): class Td(Tag):
pass pass
# contents: str = ""
#
# def __init__(self, contents, *args, **kwargs):
# self.contents = contents
# super().__init__(*args, **kwargs)
#
# def __repr__(self):
# html = [
# f"<td{self.attribs}>",
# self.contents,
# f"</td>",
# ]
# return "\n".join(html)
class Tr(Tag): class Tr(Tag):
pass pass
# cells: List[Cell] = field(default_factory=list)
#
# def __init__(self, cells, *args, **kwargs):
# self.cells = cells
# super().__init__(*args, **kwargs)
#
# def __repr__(self):
# html = [
# f"<tr{self.attribs}>",
# "\n".join([str(c) for c in self.cells]),
# f"</tr>",
# ]
# return "\n".join(html)
class Table(Tag): class Table(Tag):
pass pass
# rows: List[Row] = field(default_factory=list)
#
# def __repr__(self):
# html = [
# f"<table{self.attribs}>",
# "\n".join([str(r) for r in self.rows]),
# "</table>",
# ]
# return "\n".join(html)