Move image attributes into Image dataclass to fix change requests

@formatc1702 requested changes in his review of #153:
- Lowercase attribute values
- Nested image attributes
- Avoid sending the whole node object as argument to helper functions
- Simplify html_size_attr()
- Move the resources folder
This commit is contained in:
KV 2020-08-15 07:09:37 +02:00
parent 3d7f027a4e
commit 204379a125
6 changed files with 41 additions and 36 deletions

View File

@ -7,7 +7,8 @@ connectors:
pins: [T, R, S]
pinlabels: [Dot, Dash, Ground]
show_pincount: false
image: ../resources/stereo-phone-plug-TRS.png
image:
src: resources/stereo-phone-plug-TRS.png
caption: Tip, Ring, and Sleeve
cables:
@ -18,7 +19,8 @@ cables:
color_code: DIN
wirecount: 3
shield: SN
image: ../resources/cable-WH+BN+GN+shield.png
image:
src: resources/cable-WH+BN+GN+shield.png
caption: Cross-section
connections:

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -7,6 +7,16 @@ from wireviz.wv_helper import int2tuple
from wireviz import wv_colors
@dataclass
class Image:
src: str
scale: str = "false"
width: Optional[int] = None
height: Optional[int] = None
fixedsize: bool = False
caption: Optional[str] = None
@dataclass
class Connector:
name: str
@ -18,10 +28,7 @@ class Connector:
type: Optional[str] = None
subtype: Optional[str] = None
pincount: Optional[int] = None
image: Optional[str] = None
image_scale: Optional[str] = "FALSE"
image_size: List[Any] = field(default_factory=list)
caption: Optional[str] = None
image: Optional[Image] = None
notes: Optional[str] = None
pinlabels: List[Any] = field(default_factory=list)
pins: List[Any] = field(default_factory=list)
@ -33,6 +40,10 @@ class Connector:
loops: List[Any] = field(default_factory=list)
def __post_init__(self):
if isinstance(self.image, dict):
self.image = Image(**self.image)
self.ports_left = False
self.ports_right = False
self.visible_pins = {}
@ -95,10 +106,7 @@ class Cable:
color: Optional[str] = None
wirecount: Optional[int] = None
shield: bool = False
image: Optional[str] = None
image_scale: Optional[str] = "FALSE"
image_size: List[Any] = field(default_factory=list)
caption: Optional[str] = None
image: Optional[Image] = None
notes: Optional[str] = None
colors: List[Any] = field(default_factory=list)
color_code: Optional[str] = None
@ -107,6 +115,9 @@ class Cable:
def __post_init__(self):
if isinstance(self.image, dict):
self.image = Image(**self.image)
if isinstance(self.gauge, str): # gauge and unit specified
try:
g, u = self.gauge.split(' ')

View File

@ -98,8 +98,8 @@ class Harness:
f'{connector.pincount}-pin' if connector.show_pincount else None,
connector.color, '<!-- colorbar -->' if connector.color else None],
'<!-- connector table -->' if connector.style != 'simple' else None,
[html_image(connector)],
[html_caption(connector)],
[html_image(connector.image)],
[html_caption(connector.image)],
[html_line_breaks(connector.notes)]]
html.extend(nested_html_table(rows))
@ -175,8 +175,8 @@ class Harness:
f'{cable.length} m' if cable.length > 0 else None,
cable.color, '<!-- colorbar -->' if cable.color else None],
'<!-- wire table -->',
[html_image(cable)],
[html_caption(cable)],
[html_image(cable.image)],
[html_caption(cable.image)],
[html_line_breaks(cable.notes)]]
html.extend(nested_html_table(rows))

View File

@ -55,13 +55,12 @@ def nested_html_table(rows):
html.append('</table>')
return html
def html_image(node):
if not node.image:
def html_image(image):
if not image:
return None
size = html_size_attr(node.image_size)
# The leading attributes belong to the preceeding tag. See where used below.
html = f'{"".join(size)}><img scale="{node.image_scale}" src="{node.image}"/>'
if size[2]: # fixedsize
html = f'{html_size_attr(image)}><img scale="{image.scale}" src="{image.src}"/>'
if image.fixedsize:
# Close the preceeding tag and enclose the image cell in a table without
# borders to avoid narrow borders when the fixed width < the node width.
html = f'''>
@ -69,23 +68,16 @@ def html_image(node):
<td{html}</td>
</tr></table>
'''
return f'''<tdX{' sides="TLR"' if node.caption else ''}{html}'''
return f'''<tdX{' sides="TLR"' if image.caption else ''}{html}'''
def html_caption(node):
return f'''<tdX{' sides="LRB"' if node.image else ''}>{html_line_breaks(node.caption)}''' if node.caption else None
def html_caption(image):
return f'<tdX sides="BLR">{html_line_breaks(image.caption)}' if image and image.caption else None
def html_size_attr(size):
# Return Graphviz HTML attributes to specify minimum size of a TABLE or TD object
# size: List of values where only these are used:
# - First value is minimum width of object in points, an int value in the range 1-65535. (Default 0 = none)
# - Second value is minimum height of the object in points, an int value in the range 1-65535. (Default 0 = none)
# - Third value is a boolean where TRUE specify that the first two values are the fixed image cell size.
# (Default FALSE) Other string values, e.g. FIXED are also interpreted as TRUE.
if not size or not isinstance(size, list):
return [''] * 3
return [f' width="{size[0]}"' if len(size) > 0 and size[0] else '',
f' height="{size[1]}"' if len(size) > 1 and size[1] else '',
' fixedsize="TRUE"' if len(size) > 2 and size[2] else '']
def html_size_attr(image):
# Return Graphviz HTML attributes to specify minimum or fixed size of a TABLE or TD object
return ((f' width="{image.width}"' if image.width else '')
+ (f' height="{image.height}"' if image.height else '')
+ ( ' fixedsize="true"' if image.fixedsize else '')) if image else ''
def expand(yaml_data):