Diagram & Documentation Mastery
Preface
This reference teaches three interconnected skills:
-
D2 - Declarative diagramming
-
AsciiDoc - Technical documentation
-
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"
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.
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]
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
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 |