diff --git a/src/wireviz/wv_html.py b/src/wireviz/wv_html.py index 94c8d62b..3d931bff 100644 --- a/src/wireviz/wv_html.py +++ b/src/wireviz/wv_html.py @@ -7,47 +7,88 @@ from wireviz import __version__, APP_NAME, APP_URL, wv_colors from wireviz.DataClasses import Metadata, Options -from wireviz.wv_helper import flatten2d, open_file_read, open_file_write +from wireviz.wv_helper import flatten2d, open_file_read, open_file_write, smart_file_resolve +from wireviz.wv_gv_html import html_line_breaks def generate_html_output(filename: Union[str, Path], bom_list: List[List[str]], metadata: Metadata, options: Options): - with open_file_write(f'{filename}.html') as file: - file.write('\n') - file.write('\n') - file.write(' \n') - file.write(f' \n') - file.write(f' {metadata.title}\n') - file.write(f'\n') - - file.write(f'

{metadata.title}

\n') - if metadata.description: - file.write(f'

{metadata.description}

\n') - file.write('

Diagram

\n') - with open_file_read(f'{filename}.svg') as svg: - file.write(re.sub( - '^<[?]xml [^?>]*[?]>[^<]*]*>', - '', - svg.read(1024), 1)) - for svgdata in svg: - file.write(svgdata) - - file.write('

Bill of Materials

\n') - listy = flatten2d(bom_list) - file.write('\n') - file.write(' \n') - for item in listy[0]: - file.write(f' \n') - file.write(' \n') - for row in listy[1:]: - file.write(' \n') - for i, item in enumerate(row): - item_str = item.replace('\u00b2', '²') - align = '; text-align:right' if listy[0][i] == 'Qty' else '' - file.write(f' \n') - file.write(' \n') - file.write('
{item}
{item_str}
\n') - - if metadata.notes: - file.write(f'

Notes

\n

{metadata.notes}

\n') - - file.write('\n') + + # fall back to built-in simple template if necessary + templatename = metadata.get('template',{}).get('name', 'simple') + # if relative path to template was provided, check directory of YAML file first, fall back to built-in template directory + templatefile = smart_file_resolve(f'{templatename}.html', [Path(filename).parent, Path(__file__).parent / 'templates']) + + with open(templatefile, 'r') as file: + html = file.read() + + # embed SVG diagram + with open(f'{filename}.svg') as file: + svgdata = file.read() + svgdata = re.sub( + '^<[?]xml [^?>]*[?]>[^<]*]*>', + '', + svgdata, 1) + html = html.replace('', svgdata) + + # generate BOM table + bom = flatten2d(bom_list) + + # generate BOM header (may be at the top or bottom of the table) + bom_header_html = ' \n' + for item in bom[0]: + th_class = f'bom_col_{item.lower()}' + bom_header_html = f'{bom_header_html} {item}\n' + bom_header_html = f'{bom_header_html} \n' + + # generate BOM contents + bom_contents = [] + for row in bom[1:]: + row_html = ' \n' + for i, item in enumerate(row): + td_class = f'bom_col_{bom[0][i].lower()}' + row_html = f'{row_html} {item}\n' + row_html = f'{row_html} \n' + bom_contents.append(row_html) + + bom_html = '\n' + bom_header_html + ''.join(bom_contents) + '
\n' + bom_html_reversed = '\n' + ''.join(list(reversed(bom_contents))) + bom_header_html + '
\n' + + # insert BOM table + html = html.replace('', bom_html) + html = html.replace('', bom_html_reversed) + + # fill out title block + if metadata: + html = html.replace('', metadata.get('title', '')) + html = html.replace('', metadata.get('pn', '')) + html = html.replace('', metadata.get('company', '')) + html = html.replace('', html_line_breaks(metadata.get('description', ''))) + html = html.replace('', html_line_breaks(metadata.get('notes', ''))) + html = html.replace('', f'{APP_NAME} {__version__} - {APP_URL}') + + # TODO: handle multi-page documents + html = html.replace('', 'Sheet
1') + html = html.replace('', 'of 1') + + for i, (k, v) in enumerate(metadata.get('authors', {}).items(), 1): + title = k + name = v['name'] + date = v['date'].strftime('%Y-%m-%d') + html = html.replace(f'', title) + html = html.replace(f'', name) + html = html.replace(f'', date) + + for i, (k, v) in enumerate(metadata.get('revisions', {}).items(), 1): + # TODO: for more than 8 revisions, keep only the 8 most recent ones + number = k + changelog = v['changelog'] + name = v['name'] + date = v['date'].strftime('%Y-%m-%d') + html = html.replace(f'', '{:02d}'.format(number)) + html = html.replace(f'', changelog) + html = html.replace(f'', name) + html = html.replace(f'', date) + + html = html.replace(f'"sheetsize_default"', '"{}"'.format(metadata.get('template',{}).get('sheetsize', ''))) # include quotes so no replacement happens within