Diagram & Documentation Mastery

Preface

This reference teaches three interconnected skills:

  1. D2 - Declarative diagramming

  2. AsciiDoc - Technical documentation

  3. Unix - Text processing (sed, awk, grep)

Together, they form a complete documentation-as-code workflow.

Part I: D2 Fundamentals

What is D2?

D2 is a declarative diagramming language. You describe what you want, not how to draw it.

# This is a comment
server -> database: SQL
database -> cache: Read

Render:

d2 input.d2 output.svg
d2 --theme 200 input.d2 output.svg  # Dark theme

Basic Shapes

# Default (rectangle)
server: "Web Server"

# Explicit shapes
db: "Database" { shape: cylinder }
user: "User" { shape: person }
cloud: "Cloud" { shape: cloud }
process: "Process" { shape: hexagon }
queue: "Queue" { shape: queue }

Available shapes: rectangle, square, circle, oval, cylinder, queue, person, diamond, hexagon, cloud, text

Connections

# Basic arrow
a -> b

# Bidirectional
a <-> b

# No arrow (line)
a -- b

# With label
a -> b: "sends data"

# Multiple connections
a -> b -> c -> d

Styling

server: {
  label: "Production Server"
  shape: rectangle
  style: {
    fill: "#1a3a1a"           # Background color
    stroke: "#50fa7b"          # Border color
    stroke-width: 3            # Border thickness
    font-color: "#ffffff"      # Text color
    font-size: 14              # Text size
    bold: true                 # Bold text
    border-radius: 8           # Rounded corners
  }
}

Connection Styling

a -> b: "Data Flow" {
  style: {
    stroke: "#50fa7b"      # Line color
    stroke-width: 2        # Line thickness
    stroke-dash: 4         # Dashed line (length)
    animated: true         # Animated "marching ants"
  }
}

Containers (Grouping)

network: "Internal Network" {
  style: {
    fill: "#1a1a2e"
    stroke: "#89b4fa"
    stroke-width: 3
  }

  server1: "Server 1"
  server2: "Server 2"

  server1 -> server2: "sync"
}

external -> network.server1: "HTTPS"

Layout Direction

direction: right    # left-to-right (default)
direction: down     # top-to-bottom
direction: left     # right-to-left
direction: up       # bottom-to-top

Positioning

title: {
  label: "My Diagram"
  near: top-center
  shape: text
}

legend: {
  near: bottom-center
}

sidebar: {
  near: center-right
}

Valid positions: top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right

Part II: D2 Advanced Patterns

Multi-line Labels

server: {
  label: "Web Server\n\n• Nginx\n• Node.js\n• Redis"
}

Key insight: Use \n for newlines in labels.

ASCII Art in Labels (Avoid!)

Problem: ASCII box art overflows shape boundaries.

# BAD - will overflow
server: {
  label: "┌─────────────┐\n│ Web Server  │\n└─────────────┘"
  shape: hexagon
}

# GOOD - clean bullets
server: {
  label: "Web Server\n\n• Nginx\n• Node.js\n• Redis"
  shape: rectangle
}

Animated Connections

# Add animated: true for "marching ants" effect
client -> server: "Request" {
  style: {
    stroke: "#50fa7b"
    stroke-width: 2
    animated: true
  }
}

Themes

# List available themes
d2 --help | grep theme

# Common themes
d2 --theme 0 input.d2 output.svg    # Default (light)
d2 --theme 200 input.d2 output.svg  # Dark (Terminal)
d2 --theme 300 input.d2 output.svg  # Dark Mauve

Complete Example

direction: down

title: {
  label: "KUBERNETES ARCHITECTURE"
  near: top-center
  shape: text
  style: {
    font-size: 28
    bold: true
    font-color: "#50fa7b"
  }
}

control: "Control Plane" {
  style: {
    fill: "#1a3a1a"
    stroke: "#50fa7b"
    stroke-width: 3
  }

  apiserver: {
    label: "API Server\n\n• REST Gateway\n• AuthN/AuthZ\n• Admission"
    shape: rectangle
    style: {
      fill: "#2d3a2d"
      stroke: "#50fa7b"
      stroke-width: 2
      font-color: "#ffffff"
      font-size: 14
    }
  }
}

worker: "Worker Node" {
  style: {
    fill: "#1a2a3a"
    stroke: "#89b4fa"
  }

  kubelet: "kubelet"
  pods: "Pods"

  kubelet -> pods
}

control.apiserver -> worker.kubelet: "Instructions" {
  style: {stroke: "#50fa7b"; stroke-width: 2; animated: true}
}

legend: {
  near: bottom-center
  label: "Green = Control | Blue = Data"
  style: {
    fill: "#ffffff"
    stroke: "#50fa7b"
    border-radius: 8
    font-color: "#1a1a1a"
  }
}

Part III: Unix Text Processing

sed - Stream Editor

Pattern: sed 's/old/new/g' file

# Basic substitution
sed 's/foo/bar/g' file.txt

# In-place edit
sed -i 's/foo/bar/g' file.txt

# Multiple substitutions (order matters!)
sed -i 's/font-size: 28/font-size: 32/g; s/font-size: 14/font-size: 18/g' file.d2

# Specific line
sed -n '10p' file.txt           # Print line 10
sed -i '10s/old/new/' file.txt  # Replace on line 10 only

# Delete lines
sed -i '/pattern/d' file.txt    # Delete lines matching pattern

Critical lesson: When doing multiple replacements with overlapping numbers, go from largest to smallest:

# WRONG - 14 becomes 18, then 18 might match again
sed -i 's/14/18/g; s/28/32/g' file

# RIGHT - largest first
sed -i 's/28/32/g; s/14/18/g' file

awk - Pattern Scanning

Pattern: awk '/pattern/ { action }' file

# Print specific field
awk '{print $1}' file.txt       # First field
awk -F: '{print $1}' /etc/passwd # Custom delimiter

# Filter and print
awk '/error/ {print $0}' log.txt

# Field manipulation
awk '{print $1, $3}' file.txt   # Print fields 1 and 3

# Line numbers
awk 'NR>=10 && NR<=20' file.txt # Lines 10-20

# Counting
awk 'END {print NR}' file.txt   # Count lines

grep - Pattern Matching

# Basic search
grep 'pattern' file.txt

# Recursive
grep -r 'pattern' directory/

# With line numbers
grep -n 'pattern' file.txt

# Invert match
grep -v 'pattern' file.txt      # Lines NOT matching

# Count matches
grep -c 'pattern' file.txt

# Files only
grep -l 'pattern' *.txt         # List files with matches

Combining Tools

# Find all font-size values in D2 files
grep -o 'font-size: [0-9]*' *.d2 | sort | uniq -c

# Before: Check current values
grep -o 'font-size: [0-9]*' file.d2 | sort | uniq -c

# Apply changes
sed -i 's/font-size: 10/font-size: 14/g' file.d2

# After: Verify changes
grep -o 'font-size: [0-9]*' file.d2 | sort | uniq -c

The D2 Workflow

# 1. Create/edit D2 file
vim diagram.d2

# 2. Render to SVG
d2 --theme 200 diagram.d2 diagram.svg

# 3. Preview
firefox diagram.svg

# 4. Batch render
for f in *.d2; do
  d2 --theme 200 "$f" "${f%.d2}.svg"
done

# 5. Batch font update
sed -i 's/font-size: 10/font-size: 14/g' *.d2
for f in *.d2; do d2 --theme 200 "$f" "${f%.d2}.svg"; done

Part IV: AsciiDoc Essentials

Document Structure

= Document Title
:description: SEO description
:navtitle: Navigation Title
:icons: font

== Section 1

Content here.

=== Subsection 1.1

More content.

Code Blocks

[source,bash]
\----
echo "Hello World"
\----

[source,yaml]
\----
key: value
\----

Attributes

// In antora.yml
asciidoc:
  attributes:
    server-ip: 10.50.1.60
    domain: example.com

// In document
The server at {server-ip} serves {domain}.

Code Blocks with Attributes

[source,bash,subs=attributes+]
\----
ssh admin@{server-ip}
\----

Critical: Without subs=attributes+, curly braces render literally.

Images

image::diagrams/architecture.svg[Architecture Diagram]

// With size
image::diagrams/architecture.svg[Architecture,width=800]

Tables

[cols="1,2,1"]
|===
| Header 1 | Header 2 | Header 3

| Cell 1
| Cell 2
| Cell 3

| Cell 4
| Cell 5
| Cell 6
|===

Admonitions

NOTE: This is a note.

TIP: This is a tip.

IMPORTANT: This is important.

WARNING: This is a warning.

CAUTION: This is a caution.

Part V: Complete Workflow

Creating a New Diagram

# 1. Create D2 file
cat > new-diagram.d2 << 'EOF'
direction: down

title: {
  label: "MY DIAGRAM"
  near: top-center
  shape: text
  style: { font-size: 28; bold: true; font-color: "#50fa7b" }
}

component1 -> component2: "flow" {
  style: { stroke: "#50fa7b"; animated: true }
}
EOF

# 2. Render
d2 --theme 200 new-diagram.d2 new-diagram.svg

# 3. Preview
firefox new-diagram.svg

# 4. Iterate until satisfied
vim new-diagram.d2
d2 --theme 200 new-diagram.d2 new-diagram.svg

Batch Operations

# Increase all font sizes
for f in k8s-*.d2; do
  echo "Processing $f..."
  sed -i 's/font-size: 10/font-size: 14/g' "$f"
  sed -i 's/font-size: 11/font-size: 15/g' "$f"
  sed -i 's/font-size: 12/font-size: 16/g' "$f"
  d2 --theme 200 "$f" "${f%.d2}.svg"
done

# Open all for review
firefox k8s-*.svg

Cleaning ASCII Art

# Remove box characters from labels
sed -i 's/┌[─]*┐//g' file.d2
sed -i 's/└[─]*┘//g' file.d2
sed -i 's/│ /• /g' file.d2
sed -i 's/ │//g' file.d2
sed -i 's/│//g' file.d2
sed -i 's/━[━]*//g' file.d2

# Re-render
d2 --theme 200 file.d2 file.svg

Git Workflow

# After changes
git add -A
git commit -m "fix(diagrams): Update font sizes and clean labels"
git push origin main

# Trigger docs rebuild
cd ../domus-docs
git commit --allow-empty -m "chore: Trigger rebuild"
git push origin main

Part VI: Reference Tables

D2 Shapes

Shape Use Case

rectangle

Default, general purpose

cylinder

Databases, storage

hexagon

Processes, services (avoid for detailed labels)

person

Users, actors

cloud

External services

queue

Message queues

diamond

Decisions

D2 Colors (Dark Theme)

Color Hex Use

Green

#50fa7b

Success, active, primary

Blue

#89b4fa

Information, secondary

Purple

#cba6f7

Special, tertiary

Yellow

#f9e2af

Warning, attention

Red

#f38ba8

Error, danger

Teal

#94e2d5

Storage, data

Orange

#f5a623

Highlight, accent

Gray

#6c7086

Disabled, optional

Font Size Guide

Element Size Purpose

Title

28-32

Main diagram title

Section Header

18-20

Container labels

Content

14-16

Shape content

Legend

12-14

Footnotes, legends

sed Quick Reference

Command Action

s/old/new/

Replace first occurrence

s/old/new/g

Replace all occurrences

s/old/new/i

Case-insensitive

-i

Edit in-place

-n 'Xp'

Print line X only

/pattern/d

Delete matching lines

Xs/old/new/

Replace on line X only

awk Quick Reference

Command Action

{print $1}

Print first field

-F:

Set delimiter to :

NR

Current line number

NF

Number of fields

/pattern/

Match pattern

END {print NR}

Print total lines

Document Information

Author

Evan Modestus

Version

1.0

Last Updated

2026-02-22

Purpose

Teaching reference