[{"data":1,"prerenderedAt":63},["Reactive",2],{"blog-post-markdown-diagram-workflows-integration-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":37,"related":38},"markdown-diagram-workflows-integration-complete-guide","Markdown Diagram Workflows and Integration: Complete Guide for Visual Documentation and Automated Diagram Generation","Master advanced Markdown diagram workflows with Mermaid, PlantUML, and D2. Learn automated diagram generation, version control integration, CI/CD pipelines, and cross-platform compatibility for professional visual documentation.","Advanced Markdown diagram workflows and integration techniques enable sophisticated visual documentation that combines the simplicity of text-based markup with powerful automated diagram…","2025-11-03","Tutorial","Matthew Rathbone","markdown diagrams, mermaid diagrams, plantuml markdown, d2 diagrams, diagram automation, visual documentation, markdown workflows, diagram version control, automated diagrams",16,"\u003Cp>Advanced Markdown diagram workflows and integration techniques enable sophisticated visual documentation that combines the simplicity of text-based markup with powerful automated diagram generation, version control compatibility, and cross-platform rendering capabilities. By mastering diagram-as-code principles, automated workflow integration, and multi-format export strategies, technical teams can create comprehensive visual documentation systems that maintain consistency, enable collaboration, and scale effectively across complex project architectures.\u003C/p>\n\u003Ch2 id=\"why-master-diagram-workflows-and-integration\">Why Master Diagram Workflows and Integration?\u003C/h2>\n\u003Cp>Professional diagram workflow integration provides essential benefits for modern documentation systems:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Version Control Compatibility\u003C/strong>: Text-based diagrams integrate seamlessly with Git workflows and collaborative editing\u003C/li>\n\u003Cli>\u003Cstrong>Automated Generation\u003C/strong>: CI/CD pipelines can automatically generate and update diagrams from code changes\u003C/li>\n\u003Cli>\u003Cstrong>Platform Consistency\u003C/strong>: Single source diagrams render consistently across documentation platforms and export formats\u003C/li>\n\u003Cli>\u003Cstrong>Collaborative Editing\u003C/strong>: Team members can review, modify, and improve diagrams using familiar code review processes\u003C/li>\n\u003Cli>\u003Cstrong>Maintenance Efficiency\u003C/strong>: Automated diagram updates reduce manual maintenance overhead and improve accuracy\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-diagram-technologies\">Foundation Diagram Technologies\u003C/h2>\n\u003Ch3 id=\"mermaid-integration-strategies\">Mermaid Integration Strategies\u003C/h3>\n\u003Cp>Comprehensive Mermaid diagram implementation for modern documentation workflows:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Mermaid Diagram Integration Examples\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Basic Flowchart Syntax\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```mermaid\ngraph TD\n    A[Start] --&gt; B{Decision Point}\n    B --&gt;|Yes| C[Process A]\n    B --&gt;|No| D[Process B]\n    C --&gt; E[End]\n    D --&gt; E\n    \n    classDef startEnd fill:#e1f5fe,stroke:#01579b,stroke-width:2px\n    classDef process fill:#f3e5f5,stroke:#4a148c,stroke-width:2px\n    classDef decision fill:#fff3e0,stroke:#e65100,stroke-width:2px\n    \n    class A,E startEnd\n    class C,D process\n    class B decision\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Sequence Diagrams for API Documentation\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```mermaid\nsequenceDiagram\n    participant Client\n    participant Gateway as API Gateway\n    participant Auth as Auth Service\n    participant DB as Database\n    \n    Client-&gt;&gt;Gateway: POST /api/users\n    Gateway-&gt;&gt;Auth: Validate Token\n    Auth--&gt;&gt;Gateway: Token Valid\n    Gateway-&gt;&gt;DB: Create User\n    DB--&gt;&gt;Gateway: User Created\n    Gateway--&gt;&gt;Client: 201 Created\n    \n    Note over Client,DB: User creation flow with authentication\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Git Workflow Diagrams\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```mermaid\ngitgraph\n    commit id: &quot;Initial commit&quot;\n    branch develop\n    checkout develop\n    commit id: &quot;Add feature A&quot;\n    commit id: &quot;Add feature B&quot;\n    checkout main\n    merge develop\n    commit id: &quot;Release v1.0&quot;\n    branch hotfix\n    checkout hotfix\n    commit id: &quot;Fix critical bug&quot;\n    checkout main\n    merge hotfix\n    commit id: &quot;Release v1.0.1&quot;\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Architecture Diagrams\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```mermaid\ngraph TB\n    subgraph &quot;Frontend&quot;\n        Web[Web App]\n        Mobile[Mobile App]\n    end\n    \n    subgraph &quot;API Layer&quot;\n        Gateway[API Gateway]\n        Auth[Auth Service]\n        Users[User Service]\n        Orders[Order Service]\n    end\n    \n    subgraph &quot;Data Layer&quot;\n        UserDB[(User DB)]\n        OrderDB[(Order DB)]\n        Cache[(Redis Cache)]\n    end\n    \n    Web --&gt; Gateway\n    Mobile --&gt; Gateway\n    Gateway --&gt; Auth\n    Gateway --&gt; Users\n    Gateway --&gt; Orders\n    \n    Users --&gt; UserDB\n    Orders --&gt; OrderDB\n    Auth --&gt; Cache\n    Users --&gt; Cache\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"plantuml-advanced-integration\">PlantUML Advanced Integration\u003C/h3>\n\u003Cp>Professional PlantUML workflows for complex system documentation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># PlantUML Advanced Diagram Patterns\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Component Architecture Diagrams\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```plantuml\n@startuml\n!define RECTANGLE class\n\npackage &quot;Frontend Layer&quot; {\n    [React App] as react\n    [Vue Admin] as vue\n    [Mobile App] as mobile\n}\n\npackage &quot;API Gateway&quot; {\n    [Kong Gateway] as gateway\n    [Rate Limiter] as limiter\n    [Load Balancer] as lb\n}\n\npackage &quot;Microservices&quot; {\n    [User Service] as user\n    [Order Service] as order\n    [Payment Service] as payment\n    [Notification Service] as notify\n}\n\npackage &quot;Data Stores&quot; {\n    database &quot;PostgreSQL&quot; as postgres\n    database &quot;MongoDB&quot; as mongo\n    database &quot;Redis&quot; as redis\n}\n\nreact --&gt; gateway\nvue --&gt; gateway\nmobile --&gt; gateway\n\ngateway --&gt; limiter\nlimiter --&gt; lb\nlb --&gt; user\nlb --&gt; order\nlb --&gt; payment\n\nuser --&gt; postgres\norder --&gt; mongo\npayment --&gt; postgres\nnotify --&gt; redis\n\nnote right of gateway : All API traffic flows\\nthrough the gateway\nnote bottom of postgres : Primary relational\\ndata storage\n@enduml\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Class Diagram with Relationships\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```plantuml\n@startuml\nclass User {\n    -id: UUID\n    -email: String\n    -passwordHash: String\n    -createdAt: Date\n    +authenticate(password: String): Boolean\n    +updateProfile(data: UserData): void\n    +getOrders(): List&lt;Order&gt;\n}\n\nclass Order {\n    -id: UUID\n    -userId: UUID\n    -status: OrderStatus\n    -items: List&lt;OrderItem&gt;\n    -total: BigDecimal\n    +addItem(item: OrderItem): void\n    +calculateTotal(): BigDecimal\n    +updateStatus(status: OrderStatus): void\n}\n\nclass OrderItem {\n    -productId: UUID\n    -quantity: Integer\n    -unitPrice: BigDecimal\n    +getSubtotal(): BigDecimal\n}\n\nenum OrderStatus {\n    PENDING\n    CONFIRMED\n    SHIPPED\n    DELIVERED\n    CANCELLED\n}\n\nUser ||--o{ Order : places\nOrder ||--o{ OrderItem : contains\nOrder ||--|| OrderStatus : has\n@enduml\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Deployment Diagram\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```plantuml\n@startuml\n!define AWSPUML https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist\n!include AWSPUML/AWSCommon.puml\n!include AWSPUML/ApplicationIntegration/APIGateway.puml\n!include AWSPUML/Compute/ECS.puml\n!include AWSPUML/Database/RDS.puml\n!include AWSPUML/Storage/S3.puml\n\nnode &quot;AWS Cloud&quot; {\n    APIGateway(gateway, &quot;API Gateway&quot;, &quot;&quot;)\n    ECS(ecs, &quot;ECS Cluster&quot;, &quot;&quot;)\n    RDS(database, &quot;RDS PostgreSQL&quot;, &quot;&quot;)\n    S3(storage, &quot;S3 Bucket&quot;, &quot;&quot;)\n    \n    gateway --&gt; ecs : Routes requests\n    ecs --&gt; database : Queries data\n    ecs --&gt; storage : Stores files\n}\n\nactor User\nUser --&gt; gateway : HTTPS requests\n@enduml\n```\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"d2-modern-diagram-integration\">D2 Modern Diagram Integration\u003C/h3>\n\u003Cp>Next-generation diagram syntax with D2 for modern documentation systems:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># D2 Advanced Diagram Examples\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## System Architecture with D2\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```d2\n# Modern system architecture diagram\ndirection: right\n\nusers: Users {\n  shape: person\n  style.fill: &quot;#e1f5fe&quot;\n}\n\nfrontend: Frontend {\n  web: Web App {\n    shape: rectangle\n    style.fill: &quot;#f3e5f5&quot;\n  }\n  mobile: Mobile App {\n    shape: rectangle  \n    style.fill: &quot;#f3e5f5&quot;\n  }\n}\n\napi: API Layer {\n  gateway: API Gateway {\n    style.fill: &quot;#fff3e0&quot;\n  }\n  auth: Auth Service {\n    style.fill: &quot;#fff3e0&quot;\n  }\n  services: Microservices {\n    user: User Service\n    order: Order Service\n    payment: Payment Service\n  }\n}\n\ndata: Data Layer {\n  postgres: PostgreSQL {\n    shape: cylinder\n    style.fill: &quot;#e8f5e8&quot;\n  }\n  redis: Redis Cache {\n    shape: cylinder\n    style.fill: &quot;#e8f5e8&quot;\n  }\n}\n\n# Connections\nusers -&gt; frontend.web\nusers -&gt; frontend.mobile\nfrontend.web -&gt; api.gateway\nfrontend.mobile -&gt; api.gateway\napi.gateway -&gt; api.auth\napi.gateway -&gt; api.services.user\napi.gateway -&gt; api.services.order\napi.gateway -&gt; api.services.payment\napi.services.user -&gt; data.postgres\napi.services.order -&gt; data.postgres\napi.services.payment -&gt; data.postgres\napi.auth -&gt; data.redis\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Data Flow Diagrams\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```d2\n# Data processing pipeline\ndirection: down\n\nsource: Data Sources {\n  api: REST APIs\n  files: CSV Files\n  streams: Event Streams\n}\n\ningestion: Data Ingestion {\n  collector: Data Collector {\n    style.fill: &quot;#e3f2fd&quot;\n  }\n  validator: Data Validator {\n    style.fill: &quot;#e3f2fd&quot;\n  }\n  queue: Message Queue {\n    shape: queue\n    style.fill: &quot;#fff3e0&quot;\n  }\n}\n\nprocessing: Data Processing {\n  etl: ETL Pipeline {\n    style.fill: &quot;#f3e5f5&quot;\n  }\n  ml: ML Pipeline {\n    style.fill: &quot;#f3e5f5&quot;\n  }\n}\n\nstorage: Data Storage {\n  warehouse: Data Warehouse {\n    shape: cylinder\n    style.fill: &quot;#e8f5e8&quot;\n  }\n  lake: Data Lake {\n    shape: cylinder\n    style.fill: &quot;#e8f5e8&quot;\n  }\n}\n\n# Data flow connections\nsource.api -&gt; ingestion.collector: HTTP\nsource.files -&gt; ingestion.collector: File upload\nsource.streams -&gt; ingestion.collector: Kafka\n\ningestion.collector -&gt; ingestion.validator\ningestion.validator -&gt; ingestion.queue: Valid data\ningestion.queue -&gt; processing.etl\ningestion.queue -&gt; processing.ml\n\nprocessing.etl -&gt; storage.warehouse: Structured data\nprocessing.ml -&gt; storage.lake: Training data\n```\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"automated-workflow-integration\">Automated Workflow Integration\u003C/h2>\n\u003Ch3 id=\"cicd-pipeline-diagram-generation\">CI/CD Pipeline Diagram Generation\u003C/h3>\n\u003Cp>Implementing automated diagram generation in continuous integration workflows:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># diagram_generator.py - Automated diagram generation system\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> subprocess\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> hashlib\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Optional\u003C/span>, \u003Cspan class=\"hljs-type\">Tuple\u003C/span>\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> logging\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> dataclasses \u003Cspan class=\"hljs-keyword\">import\u003C/span> dataclass\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> enum \u003Cspan class=\"hljs-keyword\">import\u003C/span> Enum\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DiagramFormat\u003C/span>(\u003Cspan class=\"hljs-title class_ inherited__\">Enum\u003C/span>):\n    MERMAID = \u003Cspan class=\"hljs-string\">&quot;mermaid&quot;\u003C/span>\n    PLANTUML = \u003Cspan class=\"hljs-string\">&quot;plantuml&quot;\u003C/span>\n    D2 = \u003Cspan class=\"hljs-string\">&quot;d2&quot;\u003C/span>\n    GRAPHVIZ = \u003Cspan class=\"hljs-string\">&quot;dot&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-meta\">@dataclass\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DiagramConfig\u003C/span>:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Configuration for diagram generation&quot;&quot;&quot;\u003C/span>\n    source_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    output_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">format\u003C/span>: DiagramFormat\n    export_formats: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>  \u003Cspan class=\"hljs-comment\"># svg, png, pdf\u003C/span>\n    theme: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    width: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    height: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__post_init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.export_formats \u003Cspan class=\"hljs-keyword\">is\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>:\n            self.export_formats = [\u003Cspan class=\"hljs-string\">&quot;svg&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;png&quot;\u003C/span>]\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DiagramGenerator\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, config_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&quot;diagram-config.json&quot;\u003C/span>\u003C/span>):\n        self.config_path = config_path\n        self.logger = logging.getLogger(__name__)\n        self.diagram_cache = {}\n        self.load_configuration()\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">load_configuration\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Load diagram generation configuration&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(self.config_path, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                config_data = json.load(f)\n                \n            self.base_config = {\n                \u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>: config_data.get(\u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;docs/diagrams&#x27;\u003C/span>),\n                \u003Cspan class=\"hljs-string\">&#x27;cache_dir&#x27;\u003C/span>: config_data.get(\u003Cspan class=\"hljs-string\">&#x27;cache_dir&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;.diagram-cache&#x27;\u003C/span>),\n                \u003Cspan class=\"hljs-string\">&#x27;themes&#x27;\u003C/span>: config_data.get(\u003Cspan class=\"hljs-string\">&#x27;themes&#x27;\u003C/span>, {}),\n                \u003Cspan class=\"hljs-string\">&#x27;quality&#x27;\u003C/span>: config_data.get(\u003Cspan class=\"hljs-string\">&#x27;quality&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>),\n                \u003Cspan class=\"hljs-string\">&#x27;parallel_generation&#x27;\u003C/span>: config_data.get(\u003Cspan class=\"hljs-string\">&#x27;parallel_generation&#x27;\u003C/span>, \u003Cspan class=\"hljs-literal\">True\u003C/span>)\n            }\n            \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> FileNotFoundError:\n            self.logger.warning(\u003Cspan class=\"hljs-string\">f&quot;Config file \u003Cspan class=\"hljs-subst\">{self.config_path}\u003C/span> not found, using defaults&quot;\u003C/span>)\n            self.base_config = {\n                \u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;docs/diagrams&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;cache_dir&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;.diagram-cache&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;themes&#x27;\u003C/span>: {},\n                \u003Cspan class=\"hljs-string\">&#x27;quality&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;parallel_generation&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>\n            }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">discover_diagrams\u003C/span>(\u003Cspan class=\"hljs-params\">self, source_dir: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[DiagramConfig]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Discover diagram files in source directory&quot;&quot;&quot;\u003C/span>\n        diagram_configs = []\n        \n        \u003Cspan class=\"hljs-comment\"># Define file patterns for different diagram types\u003C/span>\n        patterns = {\n            DiagramFormat.MERMAID: [\u003Cspan class=\"hljs-string\">&#x27;*.mmd&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;*.mermaid&#x27;\u003C/span>],\n            DiagramFormat.PLANTUML: [\u003Cspan class=\"hljs-string\">&#x27;*.puml&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;*.plantuml&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;*.pu&#x27;\u003C/span>],\n            DiagramFormat.D2: [\u003Cspan class=\"hljs-string\">&#x27;*.d2&#x27;\u003C/span>],\n            DiagramFormat.GRAPHVIZ: [\u003Cspan class=\"hljs-string\">&#x27;*.dot&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;*.gv&#x27;\u003C/span>]\n        }\n        \n        source_path = Path(source_dir)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram_format, file_patterns \u003Cspan class=\"hljs-keyword\">in\u003C/span> patterns.items():\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> file_patterns:\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> source_path.rglob(pattern):\n                    \u003Cspan class=\"hljs-comment\"># Generate output path\u003C/span>\n                    relative_path = file_path.relative_to(source_path)\n                    output_dir = Path(self.base_config[\u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>]) / relative_path.parent\n                    \n                    config = DiagramConfig(\n                        source_path=\u003Cspan class=\"hljs-built_in\">str\u003C/span>(file_path),\n                        output_path=\u003Cspan class=\"hljs-built_in\">str\u003C/span>(output_dir / file_path.stem),\n                        \u003Cspan class=\"hljs-built_in\">format\u003C/span>=diagram_format,\n                        export_formats=[\u003Cspan class=\"hljs-string\">&quot;svg&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;png&quot;\u003C/span>, \u003Cspan class=\"hljs-string\">&quot;pdf&quot;\u003C/span>]\n                    )\n                    \n                    diagram_configs.append(config)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> diagram_configs\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">calculate_diagram_hash\u003C/span>(\u003Cspan class=\"hljs-params\">self, source_file: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Calculate hash of diagram source for caching&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(source_file, \u003Cspan class=\"hljs-string\">&#x27;rb&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            content = f.read()\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> hashlib.md5(content).hexdigest()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">is_diagram_cached\u003C/span>(\u003Cspan class=\"hljs-params\">self, config: DiagramConfig\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">bool\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if diagram output is up to date&quot;&quot;&quot;\u003C/span>\n        cache_dir = Path(self.base_config[\u003Cspan class=\"hljs-string\">&#x27;cache_dir&#x27;\u003C/span>])\n        cache_file = cache_dir / \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{Path(config.source_path).stem}\u003C/span>.json&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> cache_file.exists():\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">False\u003C/span>\n            \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(cache_file, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                cache_data = json.load(f)\n            \n            current_hash = self.calculate_diagram_hash(config.source_path)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> cache_data.get(\u003Cspan class=\"hljs-string\">&#x27;source_hash&#x27;\u003C/span>) == current_hash\n            \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> (json.JSONDecodeError, KeyError):\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">False\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">update_diagram_cache\u003C/span>(\u003Cspan class=\"hljs-params\">self, config: DiagramConfig, output_files: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Update cache with diagram generation information&quot;&quot;&quot;\u003C/span>\n        cache_dir = Path(self.base_config[\u003Cspan class=\"hljs-string\">&#x27;cache_dir&#x27;\u003C/span>])\n        cache_dir.mkdir(exist_ok=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n        cache_file = cache_dir / \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{Path(config.source_path).stem}\u003C/span>.json&quot;\u003C/span>\n        cache_data = {\n            \u003Cspan class=\"hljs-string\">&#x27;source_path&#x27;\u003C/span>: config.source_path,\n            \u003Cspan class=\"hljs-string\">&#x27;source_hash&#x27;\u003C/span>: self.calculate_diagram_hash(config.source_path),\n            \u003Cspan class=\"hljs-string\">&#x27;output_files&#x27;\u003C/span>: output_files,\n            \u003Cspan class=\"hljs-string\">&#x27;generated_at&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">str\u003C/span>(subprocess.check_output([\u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>], text=\u003Cspan class=\"hljs-literal\">True\u003C/span>).strip()),\n            \u003Cspan class=\"hljs-string\">&#x27;format&#x27;\u003C/span>: config.\u003Cspan class=\"hljs-built_in\">format\u003C/span>.value\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(cache_file, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            json.dump(cache_data, f, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_mermaid_diagram\u003C/span>(\u003Cspan class=\"hljs-params\">self, config: DiagramConfig\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate Mermaid diagram using mermaid-cli&quot;&quot;&quot;\u003C/span>\n        output_files = []\n        \n        \u003Cspan class=\"hljs-comment\"># Ensure output directory exists\u003C/span>\n        Path(config.output_path).parent.mkdir(parents=\u003Cspan class=\"hljs-literal\">True\u003C/span>, exist_ok=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> export_format \u003Cspan class=\"hljs-keyword\">in\u003C/span> config.export_formats:\n            output_file = \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{config.output_path}\u003C/span>.\u003Cspan class=\"hljs-subst\">{export_format}\u003C/span>&quot;\u003C/span>\n            \n            cmd = [\n                \u003Cspan class=\"hljs-string\">&#x27;mmdc&#x27;\u003C/span>,  \u003Cspan class=\"hljs-comment\"># mermaid-cli command\u003C/span>\n                \u003Cspan class=\"hljs-string\">&#x27;-i&#x27;\u003C/span>, config.source_path,\n                \u003Cspan class=\"hljs-string\">&#x27;-o&#x27;\u003C/span>, output_file,\n                \u003Cspan class=\"hljs-string\">&#x27;-t&#x27;\u003C/span>, config.theme \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;default&#x27;\u003C/span>\n            ]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> config.width:\n                cmd.extend([\u003Cspan class=\"hljs-string\">&#x27;-w&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">str\u003C/span>(config.width)])\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> config.height:\n                cmd.extend([\u003Cspan class=\"hljs-string\">&#x27;-H&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">str\u003C/span>(config.height)])\n                \n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                subprocess.run(cmd, check=\u003Cspan class=\"hljs-literal\">True\u003C/span>, capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>, text=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n                output_files.append(output_file)\n                self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Generated Mermaid diagram: \u003Cspan class=\"hljs-subst\">{output_file}\u003C/span>&quot;\u003C/span>)\n                \n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> subprocess.CalledProcessError \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n                self.logger.error(\u003Cspan class=\"hljs-string\">f&quot;Failed to generate Mermaid diagram: \u003Cspan class=\"hljs-subst\">{e.stderr}\u003C/span>&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> output_files\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_plantuml_diagram\u003C/span>(\u003Cspan class=\"hljs-params\">self, config: DiagramConfig\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate PlantUML diagram&quot;&quot;&quot;\u003C/span>\n        output_files = []\n        \n        \u003Cspan class=\"hljs-comment\"># Ensure output directory exists\u003C/span>\n        Path(config.output_path).parent.mkdir(parents=\u003Cspan class=\"hljs-literal\">True\u003C/span>, exist_ok=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> export_format \u003Cspan class=\"hljs-keyword\">in\u003C/span> config.export_formats:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> export_format == \u003Cspan class=\"hljs-string\">&#x27;pdf&#x27;\u003C/span>:\n                format_flag = \u003Cspan class=\"hljs-string\">&#x27;-tpdf&#x27;\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> export_format == \u003Cspan class=\"hljs-string\">&#x27;png&#x27;\u003C/span>:\n                format_flag = \u003Cspan class=\"hljs-string\">&#x27;-tpng&#x27;\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:  \u003Cspan class=\"hljs-comment\"># svg\u003C/span>\n                format_flag = \u003Cspan class=\"hljs-string\">&#x27;-tsvg&#x27;\u003C/span>\n            \n            output_file = \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{config.output_path}\u003C/span>.\u003Cspan class=\"hljs-subst\">{export_format}\u003C/span>&quot;\u003C/span>\n            \n            cmd = [\n                \u003Cspan class=\"hljs-string\">&#x27;plantuml&#x27;\u003C/span>,\n                format_flag,\n                \u003Cspan class=\"hljs-string\">&#x27;-o&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">str\u003C/span>(Path(config.output_path).parent),\n                config.source_path\n            ]\n            \n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                subprocess.run(cmd, check=\u003Cspan class=\"hljs-literal\">True\u003C/span>, capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>, text=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n                output_files.append(output_file)\n                self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Generated PlantUML diagram: \u003Cspan class=\"hljs-subst\">{output_file}\u003C/span>&quot;\u003C/span>)\n                \n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> subprocess.CalledProcessError \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n                self.logger.error(\u003Cspan class=\"hljs-string\">f&quot;Failed to generate PlantUML diagram: \u003Cspan class=\"hljs-subst\">{e.stderr}\u003C/span>&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> output_files\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_d2_diagram\u003C/span>(\u003Cspan class=\"hljs-params\">self, config: DiagramConfig\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate D2 diagram&quot;&quot;&quot;\u003C/span>\n        output_files = []\n        \n        \u003Cspan class=\"hljs-comment\"># Ensure output directory exists\u003C/span>\n        Path(config.output_path).parent.mkdir(parents=\u003Cspan class=\"hljs-literal\">True\u003C/span>, exist_ok=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> export_format \u003Cspan class=\"hljs-keyword\">in\u003C/span> config.export_formats:\n            output_file = \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{config.output_path}\u003C/span>.\u003Cspan class=\"hljs-subst\">{export_format}\u003C/span>&quot;\u003C/span>\n            \n            cmd = [\n                \u003Cspan class=\"hljs-string\">&#x27;d2&#x27;\u003C/span>,\n                config.source_path,\n                output_file\n            ]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> config.theme:\n                cmd.extend([\u003Cspan class=\"hljs-string\">&#x27;--theme&#x27;\u003C/span>, config.theme])\n                \n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                subprocess.run(cmd, check=\u003Cspan class=\"hljs-literal\">True\u003C/span>, capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>, text=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n                output_files.append(output_file)\n                self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Generated D2 diagram: \u003Cspan class=\"hljs-subst\">{output_file}\u003C/span>&quot;\u003C/span>)\n                \n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> subprocess.CalledProcessError \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n                self.logger.error(\u003Cspan class=\"hljs-string\">f&quot;Failed to generate D2 diagram: \u003Cspan class=\"hljs-subst\">{e.stderr}\u003C/span>&quot;\u003C/span>)\n                \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> output_files\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_diagram\u003C/span>(\u003Cspan class=\"hljs-params\">self, config: DiagramConfig, force: \u003Cspan class=\"hljs-built_in\">bool\u003C/span> = \u003Cspan class=\"hljs-literal\">False\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate diagram based on configuration&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Check cache unless force regeneration\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> force \u003Cspan class=\"hljs-keyword\">and\u003C/span> self.is_diagram_cached(config):\n            self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Diagram \u003Cspan class=\"hljs-subst\">{config.source_path}\u003C/span> is up to date, skipping&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> []\n        \n        \u003Cspan class=\"hljs-comment\"># Generate based on format\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> config.\u003Cspan class=\"hljs-built_in\">format\u003C/span> == DiagramFormat.MERMAID:\n            output_files = self.generate_mermaid_diagram(config)\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> config.\u003Cspan class=\"hljs-built_in\">format\u003C/span> == DiagramFormat.PLANTUML:\n            output_files = self.generate_plantuml_diagram(config)\n        \u003Cspan class=\"hljs-keyword\">elif\u003C/span> config.\u003Cspan class=\"hljs-built_in\">format\u003C/span> == DiagramFormat.D2:\n            output_files = self.generate_d2_diagram(config)\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            self.logger.error(\u003Cspan class=\"hljs-string\">f&quot;Unsupported diagram format: \u003Cspan class=\"hljs-subst\">{config.\u003Cspan class=\"hljs-built_in\">format\u003C/span>}\u003C/span>&quot;\u003C/span>)\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> []\n        \n        \u003Cspan class=\"hljs-comment\"># Update cache\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> output_files:\n            self.update_diagram_cache(config, output_files)\n            \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> output_files\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_all_diagrams\u003C/span>(\u003Cspan class=\"hljs-params\">self, source_dir: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, force: \u003Cspan class=\"hljs-built_in\">bool\u003C/span> = \u003Cspan class=\"hljs-literal\">False\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate all diagrams in source directory&quot;&quot;&quot;\u003C/span>\n        diagram_configs = self.discover_diagrams(source_dir)\n        results = {}\n        \n        self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Found \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(diagram_configs)}\u003C/span> diagrams to process&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> config \u003Cspan class=\"hljs-keyword\">in\u003C/span> diagram_configs:\n            self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Processing diagram: \u003Cspan class=\"hljs-subst\">{config.source_path}\u003C/span>&quot;\u003C/span>)\n            output_files = self.generate_diagram(config, force)\n            results[config.source_path] = output_files\n            \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">cleanup_old_diagrams\u003C/span>(\u003Cspan class=\"hljs-params\">self, source_dir: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Remove generated diagrams that no longer have source files&quot;&quot;&quot;\u003C/span>\n        output_dir = Path(self.base_config[\u003Cspan class=\"hljs-string\">&#x27;output_dir&#x27;\u003C/span>])\n        cache_dir = Path(self.base_config[\u003Cspan class=\"hljs-string\">&#x27;cache_dir&#x27;\u003C/span>])\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> cache_dir.exists():\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span>\n            \n        \u003Cspan class=\"hljs-comment\"># Get current source files\u003C/span>\n        current_configs = self.discover_diagrams(source_dir)\n        current_sources = {config.source_path \u003Cspan class=\"hljs-keyword\">for\u003C/span> config \u003Cspan class=\"hljs-keyword\">in\u003C/span> current_configs}\n        \n        \u003Cspan class=\"hljs-comment\"># Check cached diagrams\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> cache_file \u003Cspan class=\"hljs-keyword\">in\u003C/span> cache_dir.glob(\u003Cspan class=\"hljs-string\">&#x27;*.json&#x27;\u003C/span>):\n            \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(cache_file, \u003Cspan class=\"hljs-string\">&#x27;r&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                    cache_data = json.load(f)\n                \n                source_path = cache_data.get(\u003Cspan class=\"hljs-string\">&#x27;source_path&#x27;\u003C/span>)\n                \n                \u003Cspan class=\"hljs-comment\"># If source no longer exists, clean up outputs\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> source_path \u003Cspan class=\"hljs-keyword\">and\u003C/span> source_path \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> current_sources:\n                    output_files = cache_data.get(\u003Cspan class=\"hljs-string\">&#x27;output_files&#x27;\u003C/span>, [])\n                    \n                    \u003Cspan class=\"hljs-keyword\">for\u003C/span> output_file \u003Cspan class=\"hljs-keyword\">in\u003C/span> output_files:\n                        output_path = Path(output_file)\n                        \u003Cspan class=\"hljs-keyword\">if\u003C/span> output_path.exists():\n                            output_path.unlink()\n                            self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Removed orphaned diagram: \u003Cspan class=\"hljs-subst\">{output_file}\u003C/span>&quot;\u003C/span>)\n                    \n                    \u003Cspan class=\"hljs-comment\"># Remove cache file\u003C/span>\n                    cache_file.unlink()\n                    self.logger.info(\u003Cspan class=\"hljs-string\">f&quot;Removed cache file: \u003Cspan class=\"hljs-subst\">{cache_file}\u003C/span>&quot;\u003C/span>)\n                    \n            \u003Cspan class=\"hljs-keyword\">except\u003C/span> (json.JSONDecodeError, KeyError) \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n                self.logger.error(\u003Cspan class=\"hljs-string\">f&quot;Error reading cache file \u003Cspan class=\"hljs-subst\">{cache_file}\u003C/span>: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>)\n\n\u003Cspan class=\"hljs-comment\"># CLI interface for CI/CD integration\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">main\u003C/span>():\n    \u003Cspan class=\"hljs-keyword\">import\u003C/span> argparse\n    \n    parser = argparse.ArgumentParser(description=\u003Cspan class=\"hljs-string\">&#x27;Generate diagrams from source files&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;source_dir&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Source directory containing diagram files&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--force&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-f&#x27;\u003C/span>, action=\u003Cspan class=\"hljs-string\">&#x27;store_true&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Force regeneration of all diagrams&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--cleanup&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-c&#x27;\u003C/span>, action=\u003Cspan class=\"hljs-string\">&#x27;store_true&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Clean up orphaned diagram files&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--config&#x27;\u003C/span>, default=\u003Cspan class=\"hljs-string\">&#x27;diagram-config.json&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Configuration file path&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--verbose&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-v&#x27;\u003C/span>, action=\u003Cspan class=\"hljs-string\">&#x27;store_true&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Verbose logging&#x27;\u003C/span>)\n    \n    args = parser.parse_args()\n    \n    \u003Cspan class=\"hljs-comment\"># Setup logging\u003C/span>\n    logging.basicConfig(\n        level=logging.INFO \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.verbose \u003Cspan class=\"hljs-keyword\">else\u003C/span> logging.WARNING,\n        \u003Cspan class=\"hljs-built_in\">format\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;%(asctime)s - %(name)s - %(levelname)s - %(message)s&#x27;\u003C/span>\n    )\n    \n    \u003Cspan class=\"hljs-comment\"># Generate diagrams\u003C/span>\n    generator = DiagramGenerator(args.config)\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.cleanup:\n        generator.cleanup_old_diagrams(args.source_dir)\n    \n    results = generator.generate_all_diagrams(args.source_dir, args.force)\n    \n    \u003Cspan class=\"hljs-comment\"># Print summary\u003C/span>\n    total_generated = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(\u003Cspan class=\"hljs-built_in\">len\u003C/span>(files) \u003Cspan class=\"hljs-keyword\">for\u003C/span> files \u003Cspan class=\"hljs-keyword\">in\u003C/span> results.values() \u003Cspan class=\"hljs-keyword\">if\u003C/span> files)\n    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Generated \u003Cspan class=\"hljs-subst\">{total_generated}\u003C/span> diagram files&quot;\u003C/span>)\n    \n    \u003Cspan class=\"hljs-comment\"># Exit with error code if any diagrams failed\u003C/span>\n    failed_count = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(\u003Cspan class=\"hljs-number\">1\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> files \u003Cspan class=\"hljs-keyword\">in\u003C/span> results.values() \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> files)\n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> failed_count &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Warning: \u003Cspan class=\"hljs-subst\">{failed_count}\u003C/span> diagrams failed to generate&quot;\u003C/span>)\n        exit(\u003Cspan class=\"hljs-number\">1\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    main()\n\u003C/code>\u003C/pre>\u003Ch3 id=\"github-actions-integration\">GitHub Actions Integration\u003C/h3>\n\u003Cp>Complete GitHub Actions workflow for automated diagram generation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># .github/workflows/diagram-generation.yml\u003C/span>\n\u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">and\u003C/span> \u003Cspan class=\"hljs-string\">Update\u003C/span> \u003Cspan class=\"hljs-string\">Diagrams\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">on:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">push:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;docs/diagrams/**&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;src/**/*.puml&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;src/**/*.mmd&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;src/**/*.d2&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;.github/workflows/diagram-generation.yml&#x27;\u003C/span>\n  \u003Cspan class=\"hljs-attr\">pull_request:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">paths:\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;docs/diagrams/**&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;src/**/*.puml&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;src/**/*.mmd&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;src/**/*.d2&#x27;\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">generate-diagrams:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">token:\u003C/span> \u003Cspan class=\"hljs-string\">${{\u003C/span> \u003Cspan class=\"hljs-string\">secrets.GITHUB_TOKEN\u003C/span> \u003Cspan class=\"hljs-string\">}}\u003C/span>\n        \u003Cspan class=\"hljs-attr\">fetch-depth:\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\n\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Node.js\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">Mermaid\u003C/span> \u003Cspan class=\"hljs-string\">CLI\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-node@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">node-version:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;18&#x27;\u003C/span>\n        \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">Mermaid\u003C/span> \u003Cspan class=\"hljs-string\">CLI\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">npm\u003C/span> \u003Cspan class=\"hljs-string\">install\u003C/span> \u003Cspan class=\"hljs-string\">-g\u003C/span> \u003Cspan class=\"hljs-string\">@mermaid-js/mermaid-cli\u003C/span>\n\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Java\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">PlantUML\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-java@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">distribution:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;temurin&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">java-version:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;11&#x27;\u003C/span>\n\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">PlantUML\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        wget https://github.com/plantuml/plantuml/releases/latest/download/plantuml.jar\n        sudo mv plantuml.jar /opt/plantuml.jar\n        echo &#x27;#!/bin/bash&#x27; | sudo tee /usr/local/bin/plantuml\n        echo &#x27;java -jar /opt/plantuml.jar &quot;$@&quot;&#x27; | sudo tee -a /usr/local/bin/plantuml\n        sudo chmod +x /usr/local/bin/plantuml\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">D2\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        curl -fsSL https://d2lang.com/install.sh | sh -s --\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Setup\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">generator\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/setup-python@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">python-version:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;3.11&#x27;\u003C/span>\n        \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">Python\u003C/span> \u003Cspan class=\"hljs-string\">dependencies\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        pip install -r requirements-diagrams.txt\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">diagrams\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        python scripts/diagram_generator.py docs/diagrams --verbose\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">for\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">changes\u003C/span>\n      \u003Cspan class=\"hljs-attr\">id:\u003C/span> \u003Cspan class=\"hljs-string\">diagram-changes\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        if git diff --quiet; then\n          echo &quot;changes=false&quot; &gt;&gt; $GITHUB_OUTPUT\n        else\n          echo &quot;changes=true&quot; &gt;&gt; $GITHUB_OUTPUT\n        fi\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Commit\u003C/span> \u003Cspan class=\"hljs-string\">updated\u003C/span> \u003Cspan class=\"hljs-string\">diagrams\u003C/span>\n      \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.diagram-changes.outputs.changes\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">&amp;&amp;\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;push&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        git config --local user.email &quot;action@github.com&quot;\n        git config --local user.name &quot;GitHub Action&quot;\n        git add docs/diagrams/\n        git commit -m &quot;Auto-update diagrams from source changes\n\u003C/span>\n        \u003Cspan class=\"hljs-string\">🤖\u003C/span> \u003Cspan class=\"hljs-string\">Generated\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> [\u003Cspan class=\"hljs-string\">Claude\u003C/span> \u003Cspan class=\"hljs-string\">Code\u003C/span>]\u003Cspan class=\"hljs-string\">(https://claude.ai/code)\u003C/span>\n\n        \u003Cspan class=\"hljs-attr\">Co-Authored-By:\u003C/span> \u003Cspan class=\"hljs-string\">Claude\u003C/span> \u003Cspan class=\"hljs-string\">&lt;noreply@anthropic.com&gt;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-string\">git\u003C/span> \u003Cspan class=\"hljs-string\">push\u003C/span>\n\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Upload\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n      \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">steps.diagram-changes.outputs.changes\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;true&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/upload-artifact@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">generated-diagrams\u003C/span>\n        \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">docs/diagrams/\u003C/span>\n        \u003Cspan class=\"hljs-attr\">retention-days:\u003C/span> \u003Cspan class=\"hljs-number\">30\u003C/span>\n\n  \u003Cspan class=\"hljs-attr\">validate-diagrams:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">needs:\u003C/span> \u003Cspan class=\"hljs-string\">generate-diagrams\u003C/span>\n    \n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Checkout\u003C/span> \u003Cspan class=\"hljs-string\">repository\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/checkout@v4\u003C/span>\n\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Download\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">artifacts\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/download-artifact@v4\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">generated-diagrams\u003C/span>\n        \u003Cspan class=\"hljs-attr\">path:\u003C/span> \u003Cspan class=\"hljs-string\">docs/diagrams/\u003C/span>\n\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Validate\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">quality\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        python scripts/validate_diagrams.py docs/diagrams/\n\u003C/span>        \n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">file\u003C/span> \u003Cspan class=\"hljs-string\">sizes\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        find docs/diagrams/ -name &quot;*.svg&quot; -size +1M -exec echo &quot;Warning: Large SVG file {}&quot; \\;\n        find docs/diagrams/ -name &quot;*.png&quot; -size +5M -exec echo &quot;Warning: Large PNG file {}&quot; \\;\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Generate\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">index\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        python scripts/generate_diagram_index.py docs/diagrams/ &gt; DIAGRAMS.md\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Comment\u003C/span> \u003Cspan class=\"hljs-string\">on\u003C/span> \u003Cspan class=\"hljs-string\">PR\u003C/span> \u003Cspan class=\"hljs-string\">with\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">changes\u003C/span>\n      \u003Cspan class=\"hljs-attr\">if:\u003C/span> \u003Cspan class=\"hljs-string\">github.event_name\u003C/span> \u003Cspan class=\"hljs-string\">==\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;pull_request&#x27;\u003C/span>\n      \u003Cspan class=\"hljs-attr\">uses:\u003C/span> \u003Cspan class=\"hljs-string\">actions/github-script@v7\u003C/span>\n      \u003Cspan class=\"hljs-attr\">with:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">script:\u003C/span> \u003Cspan class=\"hljs-string\">|\n          const fs = require(&#x27;fs&#x27;);\n          const path = require(&#x27;path&#x27;);\n\u003C/span>          \n          \u003Cspan class=\"hljs-string\">//\u003C/span> \u003Cspan class=\"hljs-string\">Read\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">index\u003C/span>\n          \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">diagramIndex\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">fs.readFileSync(&#x27;DIAGRAMS.md&#x27;,\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;utf8&#x27;\u003C/span>\u003Cspan class=\"hljs-string\">);\u003C/span>\n          \n          \u003Cspan class=\"hljs-string\">//\u003C/span> \u003Cspan class=\"hljs-string\">Create\u003C/span> \u003Cspan class=\"hljs-string\">comment\u003C/span> \u003Cspan class=\"hljs-string\">body\u003C/span>\n          \u003Cspan class=\"hljs-string\">const\u003C/span> \u003Cspan class=\"hljs-string\">body\u003C/span> \u003Cspan class=\"hljs-string\">=\u003C/span> \u003Cspan class=\"hljs-string\">`##\u003C/span> \u003Cspan class=\"hljs-string\">📊\u003C/span> \u003Cspan class=\"hljs-string\">Diagram\u003C/span> \u003Cspan class=\"hljs-string\">Changes\u003C/span>\n          \n          \u003Cspan class=\"hljs-string\">This\u003C/span> \u003Cspan class=\"hljs-string\">PR\u003C/span> \u003Cspan class=\"hljs-string\">includes\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">updates.\u003C/span> \u003Cspan class=\"hljs-string\">Here&#x27;s\u003C/span> \u003Cspan class=\"hljs-attr\">a summary of the generated diagrams:\u003C/span>\n          \n          \u003Cspan class=\"hljs-string\">${diagramIndex}\u003C/span>\n          \n          \u003Cspan class=\"hljs-string\">🤖\u003C/span> \u003Cspan class=\"hljs-string\">Auto-generated\u003C/span> \u003Cspan class=\"hljs-string\">by\u003C/span> \u003Cspan class=\"hljs-string\">diagram\u003C/span> \u003Cspan class=\"hljs-string\">workflow`;\u003C/span>\n          \n          \u003Cspan class=\"hljs-string\">github.rest.issues.createComment({\u003C/span>\n            \u003Cspan class=\"hljs-attr\">issue_number:\u003C/span> \u003Cspan class=\"hljs-string\">context.issue.number,\u003C/span>\n            \u003Cspan class=\"hljs-attr\">owner:\u003C/span> \u003Cspan class=\"hljs-string\">context.repo.owner,\u003C/span>\n            \u003Cspan class=\"hljs-attr\">repo:\u003C/span> \u003Cspan class=\"hljs-string\">context.repo.repo,\u003C/span>\n            \u003Cspan class=\"hljs-attr\">body:\u003C/span> \u003Cspan class=\"hljs-string\">body\u003C/span>\n          \u003Cspan class=\"hljs-string\">});\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"version-control-integration-strategies\">Version Control Integration Strategies\u003C/h2>\n\u003Ch3 id=\"git-hooks-for-diagram-synchronization\">Git Hooks for Diagram Synchronization\u003C/h3>\n\u003Cp>Implementing Git hooks to maintain diagram consistency:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-meta\">#!/bin/bash\u003C/span>\n\u003Cspan class=\"hljs-comment\"># .git/hooks/pre-commit - Ensure diagrams are up to date before commit\u003C/span>\n\n\u003Cspan class=\"hljs-built_in\">set\u003C/span> -e\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Checking diagram consistency...&quot;\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Find all diagram source files that have been modified\u003C/span>\nMODIFIED_DIAGRAMS=$(git diff --cached --name-only | grep -E \u003Cspan class=\"hljs-string\">&#x27;\\.(mmd|puml|d2)$&#x27;\u003C/span> || \u003Cspan class=\"hljs-literal\">true\u003C/span>)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> [ -n \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$MODIFIED_DIAGRAMS\u003C/span>&quot;\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Found modified diagram sources:&quot;\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$MODIFIED_DIAGRAMS\u003C/span>&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-comment\"># Generate diagrams for modified sources\u003C/span>\n    python scripts/diagram_generator.py docs/diagrams --force\n    \n    \u003Cspan class=\"hljs-comment\"># Check if any output files were generated/updated\u003C/span>\n    GENERATED_FILES=$(git status --porcelain | grep -E \u003Cspan class=\"hljs-string\">&#x27;\\.(svg|png|pdf)$&#x27;\u003C/span> | awk \u003Cspan class=\"hljs-string\">&#x27;{print $2}&#x27;\u003C/span> || \u003Cspan class=\"hljs-literal\">true\u003C/span>)\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> [ -n \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$GENERATED_FILES\u003C/span>&quot;\u003C/span> ]; \u003Cspan class=\"hljs-keyword\">then\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Generated diagram outputs:&quot;\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$GENERATED_FILES\u003C/span>&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Stage the generated files\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$GENERATED_FILES\u003C/span>&quot;\u003C/span> | xargs git add\n        \n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Diagrams updated and staged for commit&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">else\u003C/span>\n        \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ No diagram updates needed&quot;\u003C/span>\n    \u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\u003Cspan class=\"hljs-keyword\">else\u003C/span>\n    \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ No diagram sources modified&quot;\u003C/span>\n\u003Cspan class=\"hljs-keyword\">fi\u003C/span>\n\n\u003Cspan class=\"hljs-comment\"># Validate all diagrams still compile correctly\u003C/span>\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;Validating diagram compilation...&quot;\u003C/span>\npython scripts/validate_diagrams.py docs/diagrams/\n\n\u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;✅ Pre-commit diagram checks passed&quot;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"branch-specific-diagram-management\">Branch-Specific Diagram Management\u003C/h3>\n\u003Cp>Advanced Git workflow integration for diagram management across branches:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># diagram_branch_manager.py - Manage diagrams across Git branches\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> subprocess\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> os\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> pathlib \u003Cspan class=\"hljs-keyword\">import\u003C/span> Path\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Set\u003C/span>\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> logging\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DiagramBranchManager\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, repo_path: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&quot;.&quot;\u003C/span>\u003C/span>):\n        self.repo_path = Path(repo_path)\n        self.logger = logging.getLogger(__name__)\n        \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_current_branch\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Get the current Git branch name&quot;&quot;&quot;\u003C/span>\n        result = subprocess.run(\n            [\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;rev-parse&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;--abbrev-ref&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;HEAD&#x27;\u003C/span>],\n            cwd=self.repo_path,\n            capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            text=\u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            check=\u003Cspan class=\"hljs-literal\">True\u003C/span>\n        )\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> result.stdout.strip()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_modified_diagrams\u003C/span>(\u003Cspan class=\"hljs-params\">self, base_branch: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&quot;main&quot;\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Set\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Get diagram source files modified compared to base branch&quot;&quot;&quot;\u003C/span>\n        result = subprocess.run(\n            [\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;diff&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">f&#x27;\u003Cspan class=\"hljs-subst\">{base_branch}\u003C/span>...HEAD&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;--name-only&#x27;\u003C/span>],\n            cwd=self.repo_path,\n            capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            text=\u003Cspan class=\"hljs-literal\">True\u003C/span>,\n            check=\u003Cspan class=\"hljs-literal\">True\u003C/span>\n        )\n        \n        modified_files = result.stdout.strip().split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>)\n        diagram_files = \u003Cspan class=\"hljs-built_in\">set\u003C/span>()\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> file_path \u003Cspan class=\"hljs-keyword\">in\u003C/span> modified_files:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">any\u003C/span>(file_path.endswith(ext) \u003Cspan class=\"hljs-keyword\">for\u003C/span> ext \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;.mmd&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;.puml&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;.d2&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;.dot&#x27;\u003C/span>]):\n                diagram_files.add(file_path)\n                \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> diagram_files\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_diagram_dependencies\u003C/span>(\u003Cspan class=\"hljs-params\">self, diagram_file: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Get files that depend on a specific diagram&quot;&quot;&quot;\u003C/span>\n        dependencies = []\n        \n        \u003Cspan class=\"hljs-comment\"># Search for references to the diagram in markdown files\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            result = subprocess.run(\n                [\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;grep&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-l&#x27;\u003C/span>, Path(diagram_file).stem],\n                cwd=self.repo_path,\n                capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                text=\u003Cspan class=\"hljs-literal\">True\u003C/span>\n            )\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> result.returncode == \u003Cspan class=\"hljs-number\">0\u003C/span>:\n                dependencies = [f.strip() \u003Cspan class=\"hljs-keyword\">for\u003C/span> f \u003Cspan class=\"hljs-keyword\">in\u003C/span> result.stdout.split(\u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">if\u003C/span> f.strip()]\n                \n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> subprocess.CalledProcessError:\n            \u003Cspan class=\"hljs-keyword\">pass\u003C/span>  \u003Cspan class=\"hljs-comment\"># No references found\u003C/span>\n            \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> dependencies\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">create_diagram_manifest\u003C/span>(\u003Cspan class=\"hljs-params\">self, branch_name: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Create a manifest of diagrams for the current branch&quot;&quot;&quot;\u003C/span>\n        manifest = {\n            \u003Cspan class=\"hljs-string\">&#x27;branch&#x27;\u003C/span>: branch_name,\n            \u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>: subprocess.check_output([\u003Cspan class=\"hljs-string\">&#x27;date&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-Iseconds&#x27;\u003C/span>], text=\u003Cspan class=\"hljs-literal\">True\u003C/span>).strip(),\n            \u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>: {},\n            \u003Cspan class=\"hljs-string\">&#x27;dependencies&#x27;\u003C/span>: {}\n        }\n        \n        \u003Cspan class=\"hljs-comment\"># Find all diagram source files\u003C/span>\n        diagram_patterns = [\u003Cspan class=\"hljs-string\">&#x27;**/*.mmd&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.puml&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.d2&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;**/*.dot&#x27;\u003C/span>]\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> pattern \u003Cspan class=\"hljs-keyword\">in\u003C/span> diagram_patterns:\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram_file \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.repo_path.glob(pattern):\n                rel_path = \u003Cspan class=\"hljs-built_in\">str\u003C/span>(diagram_file.relative_to(self.repo_path))\n                \n                \u003Cspan class=\"hljs-comment\"># Calculate file hash\u003C/span>\n                \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(diagram_file, \u003Cspan class=\"hljs-string\">&#x27;rb&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n                    \u003Cspan class=\"hljs-keyword\">import\u003C/span> hashlib\n                    file_hash = hashlib.md5(f.read()).hexdigest()\n                \n                manifest[\u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>][rel_path] = {\n                    \u003Cspan class=\"hljs-string\">&#x27;hash&#x27;\u003C/span>: file_hash,\n                    \u003Cspan class=\"hljs-string\">&#x27;size&#x27;\u003C/span>: diagram_file.stat().st_size,\n                    \u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>: diagram_file.stat().st_mtime\n                }\n                \n                \u003Cspan class=\"hljs-comment\"># Get dependencies\u003C/span>\n                dependencies = self.get_diagram_dependencies(rel_path)\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> dependencies:\n                    manifest[\u003Cspan class=\"hljs-string\">&#x27;dependencies&#x27;\u003C/span>][rel_path] = dependencies\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> manifest\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">compare_diagram_manifests\u003C/span>(\u003Cspan class=\"hljs-params\">self, manifest1: \u003Cspan class=\"hljs-type\">Dict\u003C/span>, manifest2: \u003Cspan class=\"hljs-type\">Dict\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Compare two diagram manifests and identify changes&quot;&quot;&quot;\u003C/span>\n        changes = {\n            \u003Cspan class=\"hljs-string\">&#x27;added&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;removed&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>: [],\n            \u003Cspan class=\"hljs-string\">&#x27;unchanged&#x27;\u003C/span>: []\n        }\n        \n        diagrams1 = \u003Cspan class=\"hljs-built_in\">set\u003C/span>(manifest1.get(\u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>, {}).keys())\n        diagrams2 = \u003Cspan class=\"hljs-built_in\">set\u003C/span>(manifest2.get(\u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>, {}).keys())\n        \n        changes[\u003Cspan class=\"hljs-string\">&#x27;added&#x27;\u003C/span>] = \u003Cspan class=\"hljs-built_in\">list\u003C/span>(diagrams2 - diagrams1)\n        changes[\u003Cspan class=\"hljs-string\">&#x27;removed&#x27;\u003C/span>] = \u003Cspan class=\"hljs-built_in\">list\u003C/span>(diagrams1 - diagrams2)\n        \n        \u003Cspan class=\"hljs-comment\"># Check for modifications in common files\u003C/span>\n        common_diagrams = diagrams1 &amp; diagrams2\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram \u003Cspan class=\"hljs-keyword\">in\u003C/span> common_diagrams:\n            hash1 = manifest1[\u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>][diagram][\u003Cspan class=\"hljs-string\">&#x27;hash&#x27;\u003C/span>]\n            hash2 = manifest2[\u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>][diagram][\u003Cspan class=\"hljs-string\">&#x27;hash&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> hash1 != hash2:\n                changes[\u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>].append(diagram)\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                changes[\u003Cspan class=\"hljs-string\">&#x27;unchanged&#x27;\u003C/span>].append(diagram)\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> changes\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">generate_branch_comparison_report\u003C/span>(\u003Cspan class=\"hljs-params\">self, base_branch: \u003Cspan class=\"hljs-built_in\">str\u003C/span> = \u003Cspan class=\"hljs-string\">&quot;main&quot;\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">str\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate a report comparing diagrams between branches&quot;&quot;&quot;\u003C/span>\n        current_branch = self.get_current_branch()\n        \n        \u003Cspan class=\"hljs-comment\"># Get manifests for both branches\u003C/span>\n        current_manifest = self.create_diagram_manifest(current_branch)\n        \n        \u003Cspan class=\"hljs-comment\"># Switch to base branch temporarily to get its manifest\u003C/span>\n        subprocess.run([\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;stash&#x27;\u003C/span>], cwd=self.repo_path, capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        subprocess.run([\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;checkout&#x27;\u003C/span>, base_branch], cwd=self.repo_path, check=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            base_manifest = self.create_diagram_manifest(base_branch)\n        \u003Cspan class=\"hljs-keyword\">finally\u003C/span>:\n            subprocess.run([\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;checkout&#x27;\u003C/span>, current_branch], cwd=self.repo_path, check=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n            subprocess.run([\u003Cspan class=\"hljs-string\">&#x27;git&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;stash&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;pop&#x27;\u003C/span>], cwd=self.repo_path, capture_output=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        \n        \u003Cspan class=\"hljs-comment\"># Compare manifests\u003C/span>\n        changes = self.compare_diagram_manifests(base_manifest, current_manifest)\n        \n        \u003Cspan class=\"hljs-comment\"># Generate report\u003C/span>\n        report_lines = [\n            \u003Cspan class=\"hljs-string\">f&quot;# Diagram Changes Report&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;**Base Branch:** `\u003Cspan class=\"hljs-subst\">{base_branch}\u003C/span>`&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;**Current Branch:** `\u003Cspan class=\"hljs-subst\">{current_branch}\u003C/span>`&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;**Generated:** \u003Cspan class=\"hljs-subst\">{current_manifest[\u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>]}\u003C/span>&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>,\n        ]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;added&#x27;\u003C/span>]:\n            report_lines.extend([\n                \u003Cspan class=\"hljs-string\">f&quot;## ➕ Added Diagrams (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;added&#x27;\u003C/span>])}\u003C/span>)&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>\n            ])\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram \u003Cspan class=\"hljs-keyword\">in\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;added&#x27;\u003C/span>]:\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- `\u003Cspan class=\"hljs-subst\">{diagram}\u003C/span>`&quot;\u003C/span>)\n                deps = current_manifest.get(\u003Cspan class=\"hljs-string\">&#x27;dependencies&#x27;\u003C/span>, {}).get(diagram, [])\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> deps:\n                    report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;  - Used in: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>.join(\u003Cspan class=\"hljs-string\">f&#x27;`\u003Cspan class=\"hljs-subst\">{d}\u003C/span>`&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> d \u003Cspan class=\"hljs-keyword\">in\u003C/span> deps)}\u003C/span>&quot;\u003C/span>)\n            report_lines.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;removed&#x27;\u003C/span>]:\n            report_lines.extend([\n                \u003Cspan class=\"hljs-string\">f&quot;## ➖ Removed Diagrams (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;removed&#x27;\u003C/span>])}\u003C/span>)&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>\n            ])\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram \u003Cspan class=\"hljs-keyword\">in\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;removed&#x27;\u003C/span>]:\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- `\u003Cspan class=\"hljs-subst\">{diagram}\u003C/span>`&quot;\u003C/span>)\n            report_lines.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>]:\n            report_lines.extend([\n                \u003Cspan class=\"hljs-string\">f&quot;## ✏️ Modified Diagrams (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>])}\u003C/span>)&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>\n            ])\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram \u003Cspan class=\"hljs-keyword\">in\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>]:\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- `\u003Cspan class=\"hljs-subst\">{diagram}\u003C/span>`&quot;\u003C/span>)\n                deps = current_manifest.get(\u003Cspan class=\"hljs-string\">&#x27;dependencies&#x27;\u003C/span>, {}).get(diagram, [])\n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> deps:\n                    report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;  - Used in: \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-string\">&#x27;, &#x27;\u003C/span>.join(\u003Cspan class=\"hljs-string\">f&#x27;`\u003Cspan class=\"hljs-subst\">{d}\u003C/span>`&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> d \u003Cspan class=\"hljs-keyword\">in\u003C/span> deps)}\u003C/span>&quot;\u003C/span>)\n            report_lines.append(\u003Cspan class=\"hljs-string\">&quot;&quot;\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;unchanged&#x27;\u003C/span>]:\n            report_lines.extend([\n                \u003Cspan class=\"hljs-string\">f&quot;## ✅ Unchanged Diagrams (\u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;unchanged&#x27;\u003C/span>])}\u003C/span>)&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&lt;details&gt;&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&lt;summary&gt;Click to expand&lt;/summary&gt;&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>\n            ])\n            \u003Cspan class=\"hljs-keyword\">for\u003C/span> diagram \u003Cspan class=\"hljs-keyword\">in\u003C/span> changes[\u003Cspan class=\"hljs-string\">&#x27;unchanged&#x27;\u003C/span>]:\n                report_lines.append(\u003Cspan class=\"hljs-string\">f&quot;- `\u003Cspan class=\"hljs-subst\">{diagram}\u003C/span>`&quot;\u003C/span>)\n            report_lines.extend([\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&lt;/details&gt;&quot;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>\n            ])\n        \n        \u003Cspan class=\"hljs-comment\"># Add summary statistics\u003C/span>\n        total_diagrams = \u003Cspan class=\"hljs-built_in\">len\u003C/span>(current_manifest.get(\u003Cspan class=\"hljs-string\">&#x27;diagrams&#x27;\u003C/span>, {}))\n        report_lines.extend([\n            \u003Cspan class=\"hljs-string\">f&quot;## 📊 Summary&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;- **Total Diagrams:** \u003Cspan class=\"hljs-subst\">{total_diagrams}\u003C/span>&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;- **Added:** \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;added&#x27;\u003C/span>])}\u003C/span>&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;- **Modified:** \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;modified&#x27;\u003C/span>])}\u003C/span>&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;- **Removed:** \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;removed&#x27;\u003C/span>])}\u003C/span>&quot;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">f&quot;- **Unchanged:** \u003Cspan class=\"hljs-subst\">{\u003Cspan class=\"hljs-built_in\">len\u003C/span>(changes[\u003Cspan class=\"hljs-string\">&#x27;unchanged&#x27;\u003C/span>])}\u003C/span>&quot;\u003C/span>,\n        ])\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(report_lines)\n\n\u003Cspan class=\"hljs-comment\"># Command line interface\u003C/span>\n\u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">main\u003C/span>():\n    \u003Cspan class=\"hljs-keyword\">import\u003C/span> argparse\n    \n    parser = argparse.ArgumentParser(description=\u003Cspan class=\"hljs-string\">&#x27;Manage diagrams across Git branches&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;action&#x27;\u003C/span>, choices=[\u003Cspan class=\"hljs-string\">&#x27;manifest&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;compare&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;report&#x27;\u003C/span>],\n                       \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Action to perform&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--base-branch&#x27;\u003C/span>, default=\u003Cspan class=\"hljs-string\">&#x27;main&#x27;\u003C/span>,\n                       \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Base branch for comparison&#x27;\u003C/span>)\n    parser.add_argument(\u003Cspan class=\"hljs-string\">&#x27;--output&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;-o&#x27;\u003C/span>, \u003Cspan class=\"hljs-built_in\">help\u003C/span>=\u003Cspan class=\"hljs-string\">&#x27;Output file path&#x27;\u003C/span>)\n    \n    args = parser.parse_args()\n    \n    manager = DiagramBranchManager()\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.action == \u003Cspan class=\"hljs-string\">&#x27;manifest&#x27;\u003C/span>:\n        branch = manager.get_current_branch()\n        manifest = manager.create_diagram_manifest(branch)\n        output = json.dumps(manifest, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>)\n        \n    \u003Cspan class=\"hljs-keyword\">elif\u003C/span> args.action == \u003Cspan class=\"hljs-string\">&#x27;compare&#x27;\u003C/span>:\n        modified = manager.get_modified_diagrams(args.base_branch)\n        output = \u003Cspan class=\"hljs-string\">&#x27;\\n&#x27;\u003C/span>.join(\u003Cspan class=\"hljs-built_in\">sorted\u003C/span>(modified))\n        \n    \u003Cspan class=\"hljs-keyword\">elif\u003C/span> args.action == \u003Cspan class=\"hljs-string\">&#x27;report&#x27;\u003C/span>:\n        output = manager.generate_branch_comparison_report(args.base_branch)\n    \n    \u003Cspan class=\"hljs-keyword\">if\u003C/span> args.output:\n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(args.output, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            f.write(output)\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;Output written to \u003Cspan class=\"hljs-subst\">{args.output}\u003C/span>&quot;\u003C/span>)\n    \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n        \u003Cspan class=\"hljs-built_in\">print\u003C/span>(output)\n\n\u003Cspan class=\"hljs-keyword\">if\u003C/span> __name__ == \u003Cspan class=\"hljs-string\">&quot;__main__&quot;\u003C/span>:\n    main()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"cross-platform-compatibility-and-export\">Cross-Platform Compatibility and Export\u003C/h2>\n\u003Cp>Diagram workflow integration works effectively with comprehensive content management systems. When combined with \u003Ca href=\"/blog/markdown-automation-workflows-complete-guide\">automation workflows and CI/CD pipelines\u003C/a>, diagram generation ensures consistent visual documentation across all deployment environments while maintaining proper version control integration and collaborative editing capabilities.\u003C/p>\n\u003Cp>For advanced documentation architectures, diagram workflows complement \u003Ca href=\"/blog/markdown-progressive-web-app-documentation-complete-guide\">Progressive Web App documentation systems\u003C/a> by providing offline-capable visual content that enhances user understanding of complex systems while maintaining performance and accessibility standards across different devices and platforms.\u003C/p>\n\u003Cp>When building sophisticated content systems, diagram integration aligns with \u003Ca href=\"/blog/markdown-version-control-git-integration-complete-guide\">version control and Git workflows\u003C/a> to ensure that visual documentation maintains consistency through collaborative editing processes, automated content validation, and systematic change tracking that preserves the integrity of complex technical documentation.\u003C/p>\n\u003Ch2 id=\"troubleshooting-common-integration-issues\">Troubleshooting Common Integration Issues\u003C/h2>\n\u003Ch3 id=\"rendering-compatibility-problems\">Rendering Compatibility Problems\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Diagrams render differently across platforms\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\"># diagram_compatibility_checker.py - Cross-platform compatibility testing\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">DiagramCompatibilityChecker\u003C/span>:\n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        self.platforms = {\n            \u003Cspan class=\"hljs-string\">&#x27;github&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;mermaid&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;plantuml&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;d2&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;max_file_size&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;25MB&#x27;\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;gitlab&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;mermaid&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;plantuml&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;d2&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;max_file_size&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;10MB&#x27;\u003C/span>\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;notion&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;mermaid&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;plantuml&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;d2&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;image_formats&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;png&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;jpg&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;svg&#x27;\u003C/span>]\n            },\n            \u003Cspan class=\"hljs-string\">&#x27;confluence&#x27;\u003C/span>: {\n                \u003Cspan class=\"hljs-string\">&#x27;mermaid&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;plantuml&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">True\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;d2&#x27;\u003C/span>: \u003Cspan class=\"hljs-literal\">False\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;image_formats&#x27;\u003C/span>: [\u003Cspan class=\"hljs-string\">&#x27;png&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;svg&#x27;\u003C/span>]\n            }\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">check_platform_support\u003C/span>(\u003Cspan class=\"hljs-params\">self, diagram_type: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, target_platforms: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>]\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Check if diagram type is supported across platforms&quot;&quot;&quot;\u003C/span>\n        results = {}\n        \n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> platform \u003Cspan class=\"hljs-keyword\">in\u003C/span> target_platforms:\n            platform_config = self.platforms.get(platform, {})\n            supported = platform_config.get(diagram_type, \u003Cspan class=\"hljs-literal\">False\u003C/span>)\n            \n            results[platform] = {\n                \u003Cspan class=\"hljs-string\">&#x27;supported&#x27;\u003C/span>: supported,\n                \u003Cspan class=\"hljs-string\">&#x27;alternative&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;export_as_image&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> supported \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;native&#x27;\u003C/span>\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> results\n\u003C/code>\u003C/pre>\u003Ch3 id=\"performance-optimization\">Performance Optimization\u003C/h3>\n\u003Cp>\u003Cstrong>Problem\u003C/strong>: Large diagram files slow down documentation sites\u003C/p>\n\u003Cp>\u003Cstrong>Solutions\u003C/strong>:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-yaml\">\u003Cspan class=\"hljs-comment\"># diagram-optimization.yml - Optimize diagram output\u003C/span>\n\u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Optimize\u003C/span> \u003Cspan class=\"hljs-string\">Diagrams\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">on:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">workflow_call:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">inputs:\u003C/span>\n      \u003Cspan class=\"hljs-attr\">max_svg_size:\u003C/span>\n        \u003Cspan class=\"hljs-attr\">description:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;Maximum SVG file size in KB&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">required:\u003C/span> \u003Cspan class=\"hljs-literal\">false\u003C/span>\n        \u003Cspan class=\"hljs-attr\">default:\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;500&#x27;\u003C/span>\n        \u003Cspan class=\"hljs-attr\">type:\u003C/span> \u003Cspan class=\"hljs-string\">string\u003C/span>\n\n\u003Cspan class=\"hljs-attr\">jobs:\u003C/span>\n  \u003Cspan class=\"hljs-attr\">optimize-diagrams:\u003C/span>\n    \u003Cspan class=\"hljs-attr\">runs-on:\u003C/span> \u003Cspan class=\"hljs-string\">ubuntu-latest\u003C/span>\n    \u003Cspan class=\"hljs-attr\">steps:\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Install\u003C/span> \u003Cspan class=\"hljs-string\">optimization\u003C/span> \u003Cspan class=\"hljs-string\">tools\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        npm install -g svgo\n        sudo apt-get install optipng\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Optimize\u003C/span> \u003Cspan class=\"hljs-string\">SVG\u003C/span> \u003Cspan class=\"hljs-string\">files\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        find docs/diagrams -name &quot;*.svg&quot; -exec svgo {} \\;\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Optimize\u003C/span> \u003Cspan class=\"hljs-string\">PNG\u003C/span> \u003Cspan class=\"hljs-string\">files\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        find docs/diagrams -name &quot;*.png&quot; -exec optipng -o7 {} \\;\n\u003C/span>\n    \u003Cspan class=\"hljs-bullet\">-\u003C/span> \u003Cspan class=\"hljs-attr\">name:\u003C/span> \u003Cspan class=\"hljs-string\">Check\u003C/span> \u003Cspan class=\"hljs-string\">file\u003C/span> \u003Cspan class=\"hljs-string\">sizes\u003C/span>\n      \u003Cspan class=\"hljs-attr\">run:\u003C/span> \u003Cspan class=\"hljs-string\">|\n        find docs/diagrams -name &quot;*.svg&quot; -size +${{ inputs.max_svg_size }}k \\\n          -exec echo &quot;Warning: {} exceeds size limit&quot; \\;\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Advanced Markdown diagram workflows and integration techniques transform static documentation into dynamic, maintainable visual communication systems that scale effectively across complex development environments. By implementing automated generation pipelines, version control integration, and cross-platform compatibility strategies, teams can create comprehensive documentation systems that maintain accuracy, enable collaboration, and provide consistent user experiences across all deployment contexts.\u003C/p>\n\u003Cp>The key to successful diagram workflow integration lies in establishing systematic generation processes, implementing proper caching and optimization strategies, and maintaining clear standards for diagram creation and maintenance. Whether you&#39;re building API documentation, system architecture guides, or comprehensive technical specifications, these workflow techniques provide the foundation for creating sustainable, automated visual documentation systems.\u003C/p>\n\u003Cp>Remember to test diagram generation across all target platforms, implement proper error handling and fallback strategies, and establish clear contribution guidelines that help team members effectively create and maintain diagram content. With careful attention to workflow automation and integration patterns, your visual documentation can become a powerful asset that enhances understanding while minimizing maintenance overhead and ensuring long-term sustainability.\u003C/p>\n",[15,19,22,25,28,31,34],{"id":16,"text":17,"level":18},"why-master-diagram-workflows-and-integration","Why Master Diagram Workflows and Integration?",2,{"id":20,"text":21,"level":18},"foundation-diagram-technologies","Foundation Diagram Technologies",{"id":23,"text":24,"level":18},"automated-workflow-integration","Automated Workflow Integration",{"id":26,"text":27,"level":18},"version-control-integration-strategies","Version Control Integration Strategies",{"id":29,"text":30,"level":18},"cross-platform-compatibility-and-export","Cross-Platform Compatibility and Export",{"id":32,"text":33,"level":18},"troubleshooting-common-integration-issues","Troubleshooting Common Integration Issues",{"id":35,"text":36,"level":18},"conclusion","Conclusion",[],[39,47,55],{"slug":40,"title":41,"description":42,"excerpt":43,"date":44,"category":9,"author":10,"keywords":45,"readingMinutes":46},"markdown-automation-workflows-complete-guide","Markdown Automation Workflows: Complete Guide for CI/CD, Publishing, and Documentation Generation","Master automated Markdown workflows for continuous documentation, publishing pipelines, and content generation. Learn GitHub Actions, automated testing, deployment strategies, and integration with modern development tools.","Automated Markdown workflows enable seamless integration of documentation and content creation into modern development processes, providing continuous integration capabilities for technical…","2025-09-25","markdown automation, markdown ci cd, automated documentation, markdown workflows, markdown publishing automation, documentation generation, markdown testing, automated content publishing",29,{"slug":48,"title":49,"description":50,"excerpt":51,"date":52,"category":9,"author":10,"keywords":53,"readingMinutes":54},"markdown-dynamic-content-generation-automation-workflows-complete-guide","Markdown Dynamic Content Generation and Automation Workflows: Complete Guide for Automated Documentation, Template Systems, and Content Pipeline Management","Master dynamic content generation in Markdown with comprehensive automation workflows, template engines, data-driven documentation systems, and intelligent content pipeline management for scalable technical writing.","Advanced Markdown dynamic content generation and automation workflows enable systematic creation of data-driven documentation, template-based content systems, and intelligent content pipelines…","2025-12-22","markdown automation, dynamic content generation markdown, markdown templates, automated documentation markdown, content pipeline markdown, markdown workflows, data driven documentation, template engines markdown",37,{"slug":56,"title":57,"description":58,"excerpt":59,"date":60,"category":9,"author":10,"keywords":61,"readingMinutes":62},"markdown-documentation-site-generators-complete-guide","Markdown Documentation Site Generators: Complete Guide for Modern Documentation Workflows and Static Site Generation","Master advanced Markdown documentation site generators including Jekyll, Hugo, MkDocs, and Docusaurus. Learn site generation workflows, theme customization, plugin systems, and deployment strategies for professional documentation platforms.","Advanced Markdown documentation site generators enable sophisticated content management workflows that transform simple Markdown files into comprehensive documentation platforms with professional…","2025-12-02","markdown documentation generators, jekyll markdown, hugo markdown, mkdocs, docusaurus markdown, static site generators, documentation workflows, markdown site themes, documentation deployment",27,1792184944258]