Source code for nsaph.dictionary.element

#  Copyright (c) 2024.  Harvard University
#
#   Developed by Research Software Engineering,
#   Harvard University Research Computing and Data (RCD) Services.
#
#   Author: Michael A Bouzinier
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#
#
import math
from typing import Dict, Optional, List

HTML = """
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title}</title>
</head>
<body>
{body}
</body>
<html>
"""


[docs]class DataModelElement: def __init__(self, block: Optional[Dict]): self.block = block self.reference: Optional[str] = None self.description: Optional[Dict] = None if self.block is None: return if "description" in self.block: descr = self.block["description"] if isinstance(descr, dict): self.description = descr else: self.description = {"text": descr} if "reference" in self.block: self.reference = self.block["reference"] else: self.reference = None
[docs]def tab_indent(indent: int) -> str: return ''.join('\t' for _ in range(indent))
[docs]class Graph: def __init__(self): self.nodes: Dict[str,str] = dict() self.edges = [] self.outer_group = [] self.groups:Dict[str,List] = dict()
[docs] def add_edge(self, edge): self.edges.append(edge)
[docs] def add_node(self, node_id, node_repr, group = None): if node_id in self.nodes: if group is None and node_id in self.outer_group: return if group and node_id in self.groups[group]: return raise ValueError("Duplicate node: " + node_id) self.nodes[node_id] = node_repr if group is None: self.outer_group.append(node_id) else: if group not in self.groups: self.groups[group] = [] self.groups[group].append(node_id)
[docs] def print(self, file, indent: int): space = tab_indent(indent) print("digraph {", file=file) for node in self.outer_group: print(f"{space}\t{self.nodes[node]}", file=file) for group in self.groups: self.print_group(group, indent=indent, file=file) print(file=file) for edge in self.edges: print(repr(edge), file=file) print("}", file=file) return
[docs] def print_group(self, group_id, file, indent: int, max_h = 4): print(f"// Group: {group_id}", file=file) space = tab_indent(indent) group = self.groups[group_id] nn = len(group) if nn < max_h: for node in group: print(f"{space}\t{self.nodes[node]}", file=file) print(file=file) return n = max(round(math.sqrt(nn)), max_h) i = 0 m = None while i < nn: print(f"{space}{{ rank = same; ", file=file) nodes = [] for j in range(i, i + n): if j >= nn: break node_id = group[j] node_string = self.nodes[node_id] nodes.append(node_id) print(f"{space}\t{node_string}", file = file) print(f"{space}}}", file=file) if m: s = " ".join(nodes) print(f"\t{m} -> {{ {s} }} [ style = invis ];", file=file) idx = min((int(i + n / 2)), nn - 1) m = group[idx] i += n print(f"// End Group: {group_id}", file=file) print(file=file)
[docs]def fqn(schema: str, name: str) -> str: return schema + '.' + name
[docs]def qstr(s): return f'"{str(s)}"'
[docs]def hstr(s): s = s.replace("\n", "<br/>") return f'<{str(s)}>'
[docs]def attrs2string(attrs: Dict[str,str]) -> str: alist = [f'{key}={attrs[key]}' for key in attrs] return ','.join(alist)
[docs]def add_html_row(cols: List[str], border: int = 1, align: str = None, tag = "td") -> str: if len(cols) == 1: value = cols[0] if not align: align = "center" return f'<tr><{tag} align = "{align}" border = "{border}">{value}</{tag}></tr>\n' if not align: align = "left" text = '<tr align = "{align}" border = "{border}">' for c in cols: text += f'<{tag}>{c}</{tag}>' text += '</tr>\n' return text
[docs]def add_row(cols: List[str]) -> str: return add_html_row(cols)
[docs]def start_invisible_row() -> str: return '<tr border = "0"><td>'
[docs]def end_invisible_row() -> str: return '</td></tr>'
[docs]def add_header_row(cols: List[str]) -> str: return add_html_row(cols, tag="th")
[docs]def start_table(border: int = 1, align: str = "left"): return f'\n<br/><TABLE border = "{border}" align = "{align}">\n'
[docs]def end_table(): return '\n</TABLE><br/>\n'
[docs]def hr(): return "<hr/>"