// Package renderer provides Organization Chart rendering package renderer import ( "fmt" "strings" "mermaid-go/pkg/ast" ) // OrganizationRenderer implements Organization Chart rendering type OrganizationRenderer struct{} // NewOrganizationRenderer creates a new Organization renderer func NewOrganizationRenderer() *OrganizationRenderer { return &OrganizationRenderer{} } // Render renders an Organization Chart to mermaid syntax func (r *OrganizationRenderer) Render(diagram *ast.OrganizationDiagram) (string, error) { var result strings.Builder // Start with organization declaration result.WriteString("organization\n") // Add title if present if diagram.Title != nil { result.WriteString(fmt.Sprintf(" title %s\n", *diagram.Title)) } // Render nodes in hierarchical order if diagram.Root != nil { r.renderNodeHierarchy(&result, diagram.Root, " ") } else { // Render all nodes if no clear hierarchy for _, node := range diagram.Nodes { if node.Parent == nil { // Root nodes r.renderNodeHierarchy(&result, node, " ") } } } return result.String(), nil } // renderNodeHierarchy renders a node and its children recursively func (r *OrganizationRenderer) renderNodeHierarchy(result *strings.Builder, node *ast.OrganizationNode, indent string) { // Render current node result.WriteString(fmt.Sprintf("%s%s", indent, node.ID)) if node.Name != node.ID { result.WriteString(fmt.Sprintf("[%s]", node.Name)) } // Render children if len(node.Children) > 0 { result.WriteString("\n") for _, child := range node.Children { // Render connection result.WriteString(fmt.Sprintf("%s%s --> %s", indent, node.ID, child.ID)) if child.Name != child.ID { result.WriteString(fmt.Sprintf("[%s]", child.Name)) } result.WriteString("\n") } // Recursively render children for _, child := range node.Children { if len(child.Children) > 0 { r.renderNodeHierarchy(result, child, indent) } } } else { result.WriteString("\n") } }