From d4ac4da6511e1dc97af74ab04628e4c5f01c91ce Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 5 Jul 2020 17:41:18 +0200 Subject: [PATCH 1/5] Implement line break parsing for some fields Implemented in `type`, `subtype`, `notes` fields --- src/wireviz/Harness.py | 17 ++++++++++------- src/wireviz/wv_helper.py | 9 +++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index c92053e3..9f841d31 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -4,7 +4,7 @@ from wireviz.DataClasses import Connector, Cable from graphviz import Graph from wireviz import wv_colors -from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, flatten2d, index_if_list +from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, flatten2d, index_if_list, html_line_breaks, graphviz_line_breaks from collections import Counter from typing import List @@ -74,6 +74,8 @@ def create_graph(self): infostring = f'{infostring}{attrib}, ' infostring = infostring[:-2] # remove trainling comma and space + infostring = html_line_breaks(infostring) + infostring_l = infostring if connector.ports_right else '' infostring_r = infostring if connector.ports_left else '' @@ -99,8 +101,8 @@ def create_graph(self): f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else '', f'IPN: {connector.internal_part_number}' if connector.internal_part_number else ''] - attributes = [connector.type, - connector.subtype, + attributes = [graphviz_line_breaks(connector.type), + graphviz_line_breaks(connector.subtype), f'{connector.pincount}-pin' if connector.show_pincount else''] pinouts = [[], [], []] for pinnumber, pinname in zip(connector.pinnumbers, connector.pinout): @@ -111,7 +113,8 @@ def create_graph(self): pinouts[0].append(f'{pinnumber}') if connector.ports_right: pinouts[2].append(f'{pinnumber}') - label = [connector.name if connector.show_name else '', identification, attributes, pinouts, connector.notes] + print(attributes) + label = [connector.name if connector.show_name else '', identification, attributes, pinouts, graphviz_line_breaks(connector.notes)] dot.node(key, label=nested(label)) if len(connector.loops) > 0: @@ -145,7 +148,7 @@ def create_graph(self): f'IPN: {cable.internal_part_number}' if (cable.internal_part_number and not isinstance(cable.internal_part_number, list)) else ''] identification = list(filter(None, identification)) - attributes = [f'{cable.type}' if cable.type else '', + attributes = [html_line_breaks(cable.type) if cable.type else '', f'{len(cable.colors)}x' if cable.show_wirecount else '', f'{cable.gauge} {cable.gauge_unit}{awg_fmt}' if cable.gauge else '', '+ S' if cable.shield else '', @@ -166,7 +169,7 @@ def create_graph(self): html = f'{html}' # end identification row html = f'{html}' # attribute row for attrib in attributes: - html = f'{html}{attrib}' + html = f'{html}{attrib}' html = f'{html}' # attribute row html = f'{html}' # name+attributes table @@ -217,7 +220,7 @@ def create_graph(self): html = f'{html}' # main table if cable.notes: - html = f'{html}{cable.notes}' # notes table + html = f'{html}{html_line_breaks(cable.notes)}' # notes table html = f'{html} ' # spacer at the end html = f'{html}' # main table diff --git a/src/wireviz/wv_helper.py b/src/wireviz/wv_helper.py index 69d65507..387e38c2 100644 --- a/src/wireviz/wv_helper.py +++ b/src/wireviz/wv_helper.py @@ -69,3 +69,12 @@ def tuplelist2tsv(inp, header=None): # Return the value indexed if it is a list, or simply the value otherwise. def index_if_list(value, index): return value[index] if isinstance(value, list) else value + +def html_line_breaks(inp): + return inp.replace('\n', '
') if isinstance(inp, str) else inp + +def graphviz_line_breaks(inp): + return inp.replace('\n', '\\l') if isinstance(inp, str) else inp # \l generates left-aligned new lines. http://www.graphviz.org/doc/info/attrs.html#k:escString + +def remove_line_breaks(inp): + return inp.replace('\n', ' ') From 46ed2418b4ca274e6cd253479336c2ecfe5bf1fd Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 5 Jul 2020 18:00:26 +0200 Subject: [PATCH 2/5] Remove any newlines in fields for BOM generation --- src/wireviz/Harness.py | 11 +++++------ src/wireviz/wv_helper.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 9f841d31..e68b7957 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -4,7 +4,7 @@ from wireviz.DataClasses import Connector, Cable from graphviz import Graph from wireviz import wv_colors -from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, flatten2d, index_if_list, html_line_breaks, graphviz_line_breaks +from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, flatten2d, index_if_list, html_line_breaks, graphviz_line_breaks, remove_line_breaks from collections import Counter from typing import List @@ -113,7 +113,6 @@ def create_graph(self): pinouts[0].append(f'{pinnumber}') if connector.ports_right: pinouts[2].append(f'{pinnumber}') - print(attributes) label = [connector.name if connector.show_name else '', identification, attributes, pinouts, graphviz_line_breaks(connector.notes)] dot.node(key, label=nested(label)) @@ -324,8 +323,8 @@ def bom(self): shared = next(iter(items.values())) designators = list(items.keys()) designators.sort() - conn_type = f', {shared.type}' if shared.type else '' - conn_subtype = f', {shared.subtype}' if shared.subtype else '' + conn_type = f', {remove_line_breaks(shared.type)}' if shared.type else '' + conn_subtype = f', {remove_line_breaks(shared.subtype)}' if shared.subtype else '' conn_pincount = f', {shared.pincount} pins' if shared.category != 'ferrule' else '' conn_color = f', {shared.color}' if shared.color else '' name = f'Connector{conn_type}{conn_subtype}{conn_pincount}{conn_color}' @@ -344,7 +343,7 @@ def bom(self): designators = list(items.keys()) designators.sort() total_length = sum(i.length for i in items.values()) - cable_type = f', {shared.type}' if shared.type else '' + cable_type = f', {remove_line_breaks(shared.type)}' if shared.type else '' gauge_name = f' x {shared.gauge} {shared.gauge_unit}' if shared.gauge else ' wires' shield_name = ' shielded' if shared.shield else '' name = f'Cable{cable_type}, {shared.wirecount}{gauge_name}{shield_name}' @@ -371,7 +370,7 @@ def bom(self): designators = list(dict.fromkeys(designators)) # remove duplicates designators.sort() total_length = sum(i['length'] for i in items) - wire_type = f', {shared["type"]}' if 'type' in shared else '' + wire_type = f', {remove_line_breaks(shared["type"])}' if 'type' in shared else '' gauge_name = f', {shared["gauge"]} {shared["gauge_unit"]}' if 'gauge' in shared else '' gauge_color = f', {shared["color"]}' if 'color' in shared != '' else '' name = f'Wire{wire_type}{gauge_name}{gauge_color}' diff --git a/src/wireviz/wv_helper.py b/src/wireviz/wv_helper.py index 387e38c2..f5293ecc 100644 --- a/src/wireviz/wv_helper.py +++ b/src/wireviz/wv_helper.py @@ -77,4 +77,4 @@ def graphviz_line_breaks(inp): return inp.replace('\n', '\\l') if isinstance(inp, str) else inp # \l generates left-aligned new lines. http://www.graphviz.org/doc/info/attrs.html#k:escString def remove_line_breaks(inp): - return inp.replace('\n', ' ') + return inp.replace('\n', ' ').rstrip() if isinstance(inp, str) else inp From 501303cbee1e617fc07ba60e0f8c2bdec55f2058 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 5 Jul 2020 19:54:14 +0200 Subject: [PATCH 3/5] Implement line break parsing for ferrules --- src/wireviz/Harness.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 1d5a79cb..37a80435 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -60,10 +60,11 @@ def create_graph(self): for key, connector in self.connectors.items(): if connector.category == 'ferrule': - rows = [[connector.type, connector.subtype, connector.color, '' if connector.color else None], + rows = [[html_line_breaks(connector.type), html_line_breaks(connector.subtype), connector.color, '' if connector.color else None], [connector.manufacturer, f'MPN: {connector.manufacturer_part_number}' if connector.manufacturer_part_number else None, - f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None]] + f'IPN: {connector.internal_part_number}' if connector.internal_part_number else None], + [html_line_breaks(connector.notes)]] rows = [list(filter(None, row)) for row in rows] # remove missing attributes html = '' @@ -71,13 +72,13 @@ def create_graph(self): if len(row) > 0: html = f'{html}' html = f'{html}
' for cell in row: - html = f'{html}' + html = f'{html}' html = f'{html}
{cell}{cell}
' if connector.color: # add color bar next to color info, if present - colorbar = f'' - html = html.replace('', colorbar) + colorbar = f' bgcolor="{wv_colors.translate_color(connector.color, "HEX")}" width="4">' # leave out ' tag + html = html.replace('>', colorbar) dot.node(key, label=f'<{html}>', shape='none', margin='0', style='filled', fillcolor='white') From 0252476248d28035b121c00a0da8ce29dd9f9dfd Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 5 Jul 2020 20:07:46 +0200 Subject: [PATCH 4/5] Fix bug in bundle wire BOM generation --- src/wireviz/Harness.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index 37a80435..bbd1034b 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -343,7 +343,7 @@ def bom(self): if bundle.category == 'bundle': # add each wire from each bundle to the wirelist for index, color in enumerate(bundle.colors, 0): - wirelist.append({'gauge': bundle.gauge, 'gauge_unit': bundle.gauge_unit, 'length': bundle.length, 'color': color, 'designator': bundle.name, + wirelist.append({'type': bundle.type, 'gauge': bundle.gauge, 'gauge_unit': bundle.gauge_unit, 'length': bundle.length, 'color': color, 'designator': bundle.name, 'manufacturer': index_if_list(bundle.manufacturer, index), 'manufacturer part number': index_if_list(bundle.manufacturer_part_number, index), 'internal part number': index_if_list(bundle.internal_part_number, index)}) @@ -356,8 +356,8 @@ def bom(self): designators = list(dict.fromkeys(designators)) # remove duplicates designators.sort() total_length = sum(i['length'] for i in items) - wire_type = f', {remove_line_breaks(shared["type"])}' if 'type' in shared else '' - gauge_name = f', {shared["gauge"]} {shared["gauge_unit"]}' if 'gauge' in shared else '' + wire_type = f', {remove_line_breaks(shared["type"])}' if shared.get('type', None) else '' + gauge_name = f', {shared["gauge"]} {shared["gauge_unit"]}' if shared.get('gauge', None) else '' gauge_color = f', {shared["color"]}' if 'color' in shared != '' else '' name = f'Wire{wire_type}{gauge_name}{gauge_color}' item = {'item': name, 'qty': round(total_length, 3), 'unit': 'm', 'designators': designators, From e1e665583f3c8378df995e7e351b1fb13946cd59 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Sun, 5 Jul 2020 20:36:02 +0200 Subject: [PATCH 5/5] Outsource nested HTML table creation to helper function --- src/wireviz/Harness.py | 11 ++--------- src/wireviz/wv_helper.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/wireviz/Harness.py b/src/wireviz/Harness.py index bbd1034b..394640ac 100644 --- a/src/wireviz/Harness.py +++ b/src/wireviz/Harness.py @@ -4,7 +4,7 @@ from wireviz.DataClasses import Connector, Cable from graphviz import Graph from wireviz import wv_colors -from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, flatten2d, index_if_list, html_line_breaks, graphviz_line_breaks, remove_line_breaks +from wireviz.wv_helper import awg_equiv, mm2_equiv, tuplelist2tsv, nested, nested_html_table, flatten2d, index_if_list, html_line_breaks, graphviz_line_breaks, remove_line_breaks from collections import Counter from typing import List @@ -67,14 +67,7 @@ def create_graph(self): [html_line_breaks(connector.notes)]] rows = [list(filter(None, row)) for row in rows] # remove missing attributes - html = '' - for row in rows: - if len(row) > 0: - html = f'{html}' - html = f'{html}
' - for cell in row: - html = f'{html}' - html = f'{html}
{cell}
' + html = nested_html_table(rows) if connector.color: # add color bar next to color info, if present colorbar = f' bgcolor="{wv_colors.translate_color(connector.color, "HEX")}" width="4">' # leave out ' tag diff --git a/src/wireviz/wv_helper.py b/src/wireviz/wv_helper.py index f5293ecc..83ee46ee 100644 --- a/src/wireviz/wv_helper.py +++ b/src/wireviz/wv_helper.py @@ -44,6 +44,20 @@ def nested(inp): l.append(str(x)) return '|'.join(l) +def nested_html_table(rows): + # input: list of lists + # output: a parent table with one child table per parent list item + # purpose: create the appearance of one table, where cell widths are independent between rows + html = '' + for row in rows: + if len(row) > 0: + html = f'{html}' + html = f'{html}
' + for cell in row: + html = f'{html}' + html = f'{html}
{cell}
' + return html + def int2tuple(inp): if isinstance(inp, tuple):