11using System . Text . Json ;
22using DiagramForge . Abstractions ;
3+ using DiagramForge . Icons ;
34using DiagramForge . Layout ;
45using DiagramForge . Models ;
56using DiagramForge . Parsers . Conceptual ;
@@ -29,6 +30,12 @@ public sealed class DiagramRenderer
2930 private readonly ISvgRenderer _svgRenderer ;
3031 private readonly Theme _defaultTheme ;
3132
33+ /// <summary>
34+ /// Icon registry used to resolve <see cref="Node.IconRef"/> references to
35+ /// <see cref="DiagramIcon"/> instances before rendering.
36+ /// </summary>
37+ public IconRegistry IconRegistry { get ; } = new ( ) ;
38+
3239 /// <summary>
3340 /// Creates a <see cref="DiagramRenderer"/> with the default parser set, layout engine, and theme.
3441 /// </summary>
@@ -58,10 +65,24 @@ public DiagramRenderer(
5865 _layoutEngine = layoutEngine ;
5966 _svgRenderer = svgRenderer ;
6067 _defaultTheme = defaultTheme ;
68+
69+ // Register built-in Mermaid architecture icons (cloud, database, disk, internet, server).
70+ IconRegistry . RegisterPack ( "builtin" , new BuiltInArchitectureIconProvider ( ) ) ;
6171 }
6272
6373 // ── Public API ────────────────────────────────────────────────────────────
6474
75+ /// <summary>
76+ /// Registers a named icon pack. Icons can then be referenced in diagrams as
77+ /// <c>packName:icon-name</c>.
78+ /// </summary>
79+ /// <returns>This renderer, for fluent chaining.</returns>
80+ public DiagramRenderer RegisterIconPack ( string packName , IIconProvider provider )
81+ {
82+ IconRegistry . RegisterPack ( packName , provider ) ;
83+ return this ;
84+ }
85+
6586 /// <summary>
6687 /// Converts <paramref name="diagramText"/> to an SVG string using the default theme.
6788 /// The correct parser is selected automatically based on the diagram text.
@@ -161,6 +182,7 @@ public string Render(string diagramText, Theme? theme, string? paletteJson, bool
161182 diagram . LayoutHints . EdgeRouting = frontmatter . EdgeRouting . Value ;
162183 }
163184
185+ ResolveIcons ( diagram ) ;
164186 _layoutEngine . Layout ( diagram , effectiveTheme ) ;
165187 return _svgRenderer . Render ( diagram , effectiveTheme ) ;
166188 }
@@ -183,6 +205,26 @@ public DiagramRenderer RegisterParser(IDiagramParser parser)
183205
184206 // ── Private helpers ───────────────────────────────────────────────────────
185207
208+ private void ResolveIcons ( Diagram diagram )
209+ {
210+ foreach ( var node in diagram . Nodes . Values )
211+ {
212+ if ( node . IconRef is not null )
213+ {
214+ var icon = IconRegistry . Resolve ( node . IconRef ) ;
215+ if ( icon is not null )
216+ {
217+ // Sanitize the SVG content before placing it into the output SVG
218+ // to prevent XSS / injection from untrusted diagram text or icon providers.
219+ string ? sanitized = SvgIconSanitizer . Sanitize ( icon . SvgContent ) ;
220+ node . ResolvedIcon = sanitized is not null
221+ ? icon with { SvgContent = sanitized }
222+ : null ;
223+ }
224+ }
225+ }
226+ }
227+
186228 private IDiagramParser ? FindParser ( string diagramText )
187229 {
188230 foreach ( var parser in _parsers )
0 commit comments