Outsource set_dot_basics() and apply_dot_tweaks()

This commit is contained in:
Daniel Rojas 2021-10-18 18:20:19 +02:00 committed by KV
parent 2f03dcd1a3
commit 587b359fa0
2 changed files with 98 additions and 87 deletions

View File

@ -33,10 +33,12 @@ from wireviz.wv_bom import (
)
from wireviz.wv_colors import get_color_hex, translate_color
from wireviz.wv_gv_html import (
apply_dot_tweaks,
gv_connector_loops,
gv_node_component,
html_line_breaks,
remove_links,
set_dot_basics,
)
from wireviz.wv_helper import (
flatten2d,
@ -145,27 +147,7 @@ class Harness:
def create_graph(self) -> Graph:
dot = Graph()
dot.body.append(f"// Graph generated by {APP_NAME} {__version__}\n")
dot.body.append(f"// {APP_URL}\n")
dot.attr(
"graph",
rankdir="LR",
ranksep="2",
bgcolor=wv_colors.translate_color(self.options.bgcolor, "HEX"),
nodesep="0.33",
fontname=self.options.fontname,
)
dot.attr(
"node",
shape="none",
width="0",
height="0",
margin="0", # Actual size of the node is entirely determined by the label.
style="filled",
fillcolor=wv_colors.translate_color(self.options.bgcolor_node, "HEX"),
fontname=self.options.fontname,
)
dot.attr("edge", style="bold", fontname=self.options.fontname)
set_dot_basics(dot, self.options)
for connector in self.connectors.values():
# generate connector node
@ -212,7 +194,6 @@ class Harness:
html = []
wirehtml = []
# conductor table
wirehtml.append('<table border="0" cellspacing="0" cellborder="0">')
@ -405,70 +386,7 @@ class Harness:
fillcolor=translate_color(bgcolor, "HEX"),
)
def typecheck(name: str, value: Any, expect: type) -> None:
if not isinstance(value, expect):
raise Exception(
f"Unexpected value type of {name}: Expected {expect}, got {type(value)}\n{value}"
)
# TODO?: Differ between override attributes and HTML?
if self.tweak.override is not None:
typecheck("tweak.override", self.tweak.override, dict)
for k, d in self.tweak.override.items():
typecheck(f"tweak.override.{k} key", k, str)
typecheck(f"tweak.override.{k} value", d, dict)
for a, v in d.items():
typecheck(f"tweak.override.{k}.{a} key", a, str)
typecheck(f"tweak.override.{k}.{a} value", v, (str, type(None)))
# Override generated attributes of selected entries matching tweak.override.
for i, entry in enumerate(dot.body):
if isinstance(entry, str):
# Find a possibly quoted keyword after leading TAB(s) and followed by [ ].
match = re.match(
r'^\t*(")?((?(1)[^"]|[^ "])+)(?(1)") \[.*\]$', entry, re.S
)
keyword = match and match[2]
if keyword in self.tweak.override.keys():
for attr, value in self.tweak.override[keyword].items():
if value is None:
entry, n_subs = re.subn(
f'( +)?{attr}=("[^"]*"|[^] ]*)(?(1)| *)', "", entry
)
if n_subs < 1:
print(
f"Harness.create_graph() warning: {attr} not found in {keyword}!"
)
elif n_subs > 1:
print(
f"Harness.create_graph() warning: {attr} removed {n_subs} times in {keyword}!"
)
continue
if len(value) == 0 or " " in value:
value = value.replace('"', r"\"")
value = f'"{value}"'
entry, n_subs = re.subn(
f'{attr}=("[^"]*"|[^] ]*)', f"{attr}={value}", entry
)
if n_subs < 1:
# If attr not found, then append it
entry = re.sub(r"\]$", f" {attr}={value}]", entry)
elif n_subs > 1:
print(
f"Harness.create_graph() warning: {attr} overridden {n_subs} times in {keyword}!"
)
dot.body[i] = entry
if self.tweak.append is not None:
if isinstance(self.tweak.append, list):
for i, element in enumerate(self.tweak.append, 1):
typecheck(f"tweak.append[{i}]", element, str)
dot.body.extend(self.tweak.append)
else:
typecheck("tweak.append", self.tweak.append, str)
dot.body.append(self.tweak.append)
apply_dot_tweaks(dot, self.tweak)
for mate in self.mates:
if mate.shape[0] == "<" and mate.shape[-1] == ">":

View File

@ -2,8 +2,9 @@
import re
from itertools import zip_longest
from typing import List, Optional, Union
from typing import Any, List, Optional, Union
from wireviz import APP_NAME, APP_URL, __version__
from wireviz.DataClasses import Cable, Color, Component, Connector, Options
from wireviz.wv_colors import get_color_hex, translate_color
from wireviz.wv_helper import pn_info_string, remove_links
@ -356,3 +357,95 @@ def html_size_attr_dict(image):
def html_line_breaks(inp):
return remove_links(inp).replace("\n", "<br />") if isinstance(inp, str) else inp
def set_dot_basics(dot, options):
dot.body.append(f"// Graph generated by {APP_NAME} {__version__}\n")
dot.body.append(f"// {APP_URL}\n")
dot.attr(
"graph",
rankdir="LR",
ranksep="2",
bgcolor=translate_color(options.bgcolor, "HEX"),
nodesep="0.33",
fontname=options.fontname,
)
dot.attr(
"node",
shape="none",
width="0",
height="0",
margin="0", # Actual size of the node is entirely determined by the label.
style="filled",
fillcolor=translate_color(options.bgcolor_node, "HEX"),
fontname=options.fontname,
)
dot.attr("edge", style="bold", fontname=options.fontname)
def apply_dot_tweaks(dot, tweak):
def typecheck(name: str, value: Any, expect: type) -> None:
if not isinstance(value, expect):
raise Exception(
f"Unexpected value type of {name}: Expected {expect}, got {type(value)}\n{value}"
)
# TODO?: Differ between override attributes and HTML?
if tweak.override is not None:
typecheck("tweak.override", tweak.override, dict)
for k, d in tweak.override.items():
typecheck(f"tweak.override.{k} key", k, str)
typecheck(f"tweak.override.{k} value", d, dict)
for a, v in d.items():
typecheck(f"tweak.override.{k}.{a} key", a, str)
typecheck(f"tweak.override.{k}.{a} value", v, (str, type(None)))
# Override generated attributes of selected entries matching tweak.override.
for i, entry in enumerate(dot.body):
if not isinstance(entry, str):
continue
# Find a possibly quoted keyword after leading TAB(s) and followed by [ ].
match = re.match(r'^\t*(")?((?(1)[^"]|[^ "])+)(?(1)") \[.*\]$', entry, re.S)
keyword = match and match[2]
if not keyword in tweak.override.keys():
continue
for attr, value in tweak.override[keyword].items():
if value is None:
entry, n_subs = re.subn(
f'( +)?{attr}=("[^"]*"|[^] ]*)(?(1)| *)', "", entry
)
if n_subs < 1:
print(
f"Harness.create_graph() warning: {attr} not found in {keyword}!"
)
elif n_subs > 1:
print(
f"Harness.create_graph() warning: {attr} removed {n_subs} times in {keyword}!"
)
continue
if len(value) == 0 or " " in value:
value = value.replace('"', r"\"")
value = f'"{value}"'
entry, n_subs = re.subn(
f'{attr}=("[^"]*"|[^] ]*)', f"{attr}={value}", entry
)
if n_subs < 1:
# If attr not found, then append it
entry = re.sub(r"\]$", f" {attr}={value}]", entry)
elif n_subs > 1:
print(
f"Harness.create_graph() warning: {attr} overridden {n_subs} times in {keyword}!"
)
dot.body[i] = entry
if tweak.append is not None:
if isinstance(tweak.append, list):
for i, element in enumerate(tweak.append, 1):
typecheck(f"tweak.append[{i}]", element, str)
dot.body.extend(tweak.append)
else:
typecheck("tweak.append", tweak.append, str)
dot.body.append(tweak.append)