Outsource set_dot_basics() and apply_dot_tweaks()
This commit is contained in:
parent
2f03dcd1a3
commit
587b359fa0
@ -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] == ">":
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user