Rendering Engine
The GitAscii rendering engine lives insrc/engine/ and transforms JSON configuration models and normalized GitHub data into standards-compliant SVG strings.
renderSvg(config, data, options)
The main orchestration function that computes bounds, sorts layers by zIndex, renders individual widget nodes, and produces the root <svg> container.
Parameters
SavedConfiguration
required
The profile configuration containing
globalStyles and the widgets list.NormalizedGitHubData
required
Normalized data containing
user, repos, languages, totalStars, and contributions.RenderOptions
Optional rendering overrides:
theme?: 'dark' | 'light'- Forces dark or light palette.width?: number- Explicit output canvas width (defaults to bounding max or 800px).height?: number- Explicit output canvas height.widgets?: string[]- Target widget instance IDs or widget IDs to isolate with automatic shrink-wrap.
Shrink-Wrap Calculation
Whenoptions.widgets is provided, renderSvg recalculates the coordinate system:
- Finds the bounding box minimum:
minX = Math.min(...widget.position.x),minY = Math.min(...widget.position.y). - Translates each widget position:
x' = x - minX,y' = y - minY. - Sets
<svg viewBox="0 0 maxX maxY">precisely around the selected elements.
renderWidgetSvg(widget, data, globalStyles, includeWrapper, forceStatic)
Renders an individual widget instance, applying frame borders, background rectangles, template decorations, entrance animations, and transforms.
Execution Steps
- Card Frame: If the widget is not self-contained, a background
<rect>is created usingconfig.backgroundColor || globalStyles.backgroundColor,stroke-width, andborderRadius. - Template Decorations: Injects signature template accents (e.g. Dracula dots
🔴🟡🟢, Cyberpunk corner cuts, Terminal+corner marks, Nord header accent lines, Neo-brutalism offset drop shadow). - Animations: Injects
<style>keyframes (fade-in,slide-up,slide-down,slide-left,slide-right,zoom-in,zoom-out,flip-x,flip-y,typewriter,glitch,scan-lines) with staggeredanimation-delayattributes across text and rect nodes. - Transform Wrapper: If
includeWrapperistrue, encapsulates the node in<g transform="translate(x, y)" id="widget-${instanceId}">.
embedExternalImages(svgContent)
External widgets (such as Shields badges, GitHub Readme Stats, and avatars) are initially rendered with boundary markers or remote <image> tags. embedExternalImages fetches, sanitizes, and inlines these external assets to avoid CORS issues and Camo proxy blocks.
Security & Inlining Mechanisms
- SSRF Validator: Every external URL is pre-validated against private IP ranges (e.g.
127.0.0.1,10.0.0.0/8,169.254.169.254) before making network calls. - SVG Inlining (
inlineSvg): Parses remote SVGs, extracts<style>blocks to prevent namespace collisions, normalizes theviewBox, and replaces external image tags with direct<svg x="..." y="...">structures. - Binary Fallback: Non-SVG images (PNG, WebP, GIF) are converted to
data:image/png;base64,...data URIs.