85 lines
3.2 KiB
Python
85 lines
3.2 KiB
Python
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
def generate_architectural_graph(directory, output_file):
|
|
# Setup node definitions and edges
|
|
node_types = {} # entity_name -> type (container/context/task)
|
|
edges = []
|
|
|
|
# Regex to extract Gen blocks
|
|
block_re = re.compile(r"```Gen\s*(.*?)\s*```", re.DOTALL)
|
|
|
|
for md_file in Path(directory).rglob("*.md"):
|
|
content = md_file.read_text()
|
|
blocks = block_re.findall(content)
|
|
|
|
for block in blocks:
|
|
lines = [l.strip() for l in block.split('\n') if l.strip()]
|
|
props = {}
|
|
current_entity = None
|
|
current_type = None
|
|
|
|
# Parse lines for entity definition and properties
|
|
for line in lines:
|
|
if ':' in line:
|
|
key, val = line.split(':', 1)
|
|
key, val = key.strip(), val.strip()
|
|
props[key] = val
|
|
|
|
if key in ['comprehension', 'modulator', 'container', 'context', 'task']:
|
|
current_entity = val
|
|
current_type = key
|
|
node_types[current_entity] = current_type
|
|
|
|
if not current_entity: continue
|
|
|
|
# Morphism Logic: Contained By (Parent <- Child)
|
|
if 'contained_by' in props:
|
|
parent = props['contained_by']
|
|
edges.append((parent, current_entity, "contains"))
|
|
|
|
# Morphism Logic: Expands (Parent -> Child)
|
|
if 'expands' in props:
|
|
contains_val = props['expands']
|
|
match = re.match(r"(\d+x)?\s*(.*)", contains_val)
|
|
label = match.group(1) if match.group(1) else "expands"
|
|
child = match.group(2)
|
|
edges.append((current_entity, child, label))
|
|
|
|
# Build Mermaid syntax
|
|
mermaid_lines = ["graph TD"]
|
|
|
|
# Define Nodes with Types (Styling)
|
|
# Containers = Rectangles [], Contexts = Hexagons {{}}, Tasks = Ovals (())
|
|
for name, n_type in node_types.items():
|
|
if n_type == 'comprehension':
|
|
mermaid_lines.append(f' {name}["comprehension: {name}"]')
|
|
elif n_type == 'modulator':
|
|
mermaid_lines.append(f' {name}["modulator: {name}"]')
|
|
elif n_type == 'container':
|
|
mermaid_lines.append(f' {name}["container: {name}"]')
|
|
elif n_type == 'context':
|
|
mermaid_lines.append(f' {name}{{{{"context: {name}"}}}}')
|
|
elif n_type == 'task':
|
|
mermaid_lines.append(f' {name}(("task: {name}"))')
|
|
|
|
|
|
# Add Edges
|
|
for source, target, label in edges:
|
|
# Determine relationship type string for the arrow
|
|
s_type = node_types.get(source, "unknown")
|
|
t_type = node_types.get(target, "unknown")
|
|
# Example: container tre -- contains --> task bbgg
|
|
mermaid_lines.append(f' {source} -- "{label}" --> {target}')
|
|
|
|
# Save to file
|
|
with open(output_file, "w") as f:
|
|
f.write("# Architectural Hierarchy Graph\n\n")
|
|
f.write("```mermaid\n")
|
|
f.write("\n".join(mermaid_lines))
|
|
f.write("\n```")
|
|
|
|
if __name__ == "__main__":
|
|
generate_architectural_graph("..", "architecture_graph.mmd")
|
|
print("Success: architecture_graph.md has been generated.") |