mdmap generates beautiful knowledge graph visualizations from markdown files with cross-links. It analyzes your markdown files, extracts front matter metadata (titles and tags), and creates interactive graph visualizations showing how documents connect.
- Python 3.7+
- Graphviz (system package)
Ubuntu/Debian:
sudo apt-get install graphvizmacOS (Homebrew):
brew install graphvizArch Linux:
sudo pacman -S graphvizWindows (Chocolatey):
choco install graphviz# Create virtual environment
python3 -m venv venv
# Activate it
# On Linux/macOS:
source venv/bin/activate
# On Windows:
# venv\Scripts\activate
# Install Python dependencies
pip install -r requirements.txtThat's it! You're ready to use mdmap.
This repository includes an example knowledge base in the example/ directory. It contains 6 markdown files demonstrating cross-linking and tagging:
# Make sure your venv is activated (see Installation above)
python mdmap.py example/This generates mdmap.svg showing the complete knowledge graph.
After installation, your first command should look like:
source venv/bin/activate # Activate virtual environment
python mdmap.py example/ # Generate the graph
open mdmap.svg # View the result (macOS)
# or: xdg-open mdmap.svg # on Linux
# or: start mdmap.svg # on WindowsGenerate a default graph visualization:
python mdmap.py example/
# Output: mdmap.svgThis creates an undirected graph where node size represents "importance" (based on how many other documents link to it).
Add arrow heads to edges to show which document links to which:
python mdmap.py example/ --directedThis makes it clear which documents are referencing others, helping you understand information flow and dependencies.
Extract only documents with a specific tag:
python mdmap.py example/ --tag programming
python mdmap.py example/ --tag diaryThis is useful for:
- Focusing on specific topics or projects
- Creating sub-graphs for presentations
- Isolating knowledge domains
Remove documents that have no links:
python mdmap.py example/ --no-isolatedWithout this flag, the "Isolated Note" appears disconnected. With it, only the 5 connected documents are shown.
View link statistics without generating a visualization:
python mdmap.py example/ --statsOutput shows:
- Document filename and title
- Number of incoming links (how many documents reference it)
- Number of outgoing links (how many documents it references)
- Tags
Example output:
=== Link Statistics ===
File Title In Out Tags
------------------------
async-guide.md Async Programming 2 3 programming,advanced
devops.md DevOps Notes 1 2 infrastructure,operations
diary-2025-01-15.md Daily Log 2025-01-15 0 3 diary,personal
index.md Home 0 4 core
isolated.md Isolated Note 0 0 draft
python-guide.md Python Guide 2 2 programming,tutorial
web-dev.md Web Development 2 2 programming,tutorial
Show only documents within N hops of a starting point:
python mdmap.py example/ --depth 2
python mdmap.py example/ --depth 1 python-guide.mdThis creates focused subgraphs:
--depth 1: Direct connections only--depth 2: Direct + indirect connections (2 hops away)--depth 3: Further out, etc.
Great for:
- Exploring neighborhoods around specific topics
- Creating simplified views
- Understanding connection paths
When using the circo engine (or other engines) with many markdown files, the graph can have large spacing between nodes. Use these options to create more compact visualizations:
# Compact layout optimized for circo engine
python mdmap.py example/ --engine circo --compact
# Fine-tune spacing with custom separation value
python mdmap.py example/ --engine circo --sep 0.5
# Combine both for maximum control
python mdmap.py example/ --engine circo --compact --sep 0.3Options:
--compact: Automatically applies tight spacing settings optimized for your chosen engine--sep VALUE: Manually control node separation in inches (lower values = tighter layout)
This is particularly useful for:
- Large knowledge bases with many documents
- Creating denser, more readable graphs
- Reducing whitespace in circular layouts
Documents should have front matter with optional title and tags:
---
title: My Document Title
tags: #topic1 #topic2
---
# Content
[Link to other](other-file.md) document with more info.title: Display name in the graph (falls back to filename if omitted)tags: Space or comma-separated tags (with or without#prefix)
All these markdown link formats work:
[Link text](file.md)
[Link text](path/to/file.md)
[Link text](file.md#section)
[Link text](file.md?param=value)Links to non-existent files or URLs are ignored.
python mdmap.py [ROOT] [OPTIONS]| Option | Default | Description |
|---|---|---|
ROOT |
. |
Directory to scan for markdown files |
-o, --out |
mdmap |
Output filename (without extension) |
-f, --format |
svg |
Output format: svg, png, or pdf |
-e, --engine |
neato |
Graphviz engine: neato, dot, circo, twopi, fdp |
| Option | Default | Description |
|---|---|---|
--min-size |
0.1 |
Minimum node size (in inches) |
--max-size |
4.0 |
Maximum node size |
--scale-power |
2 |
Size scaling: 1=linear, 2=quadratic, 3=cubic |
--compact |
disabled | Enable compact layout mode (reduces spacing) |
--sep |
auto | Node separation in inches (lower = tighter) |
| Option | Description |
|---|---|
--directed |
Show arrows indicating link direction |
--tag TAG |
Filter to documents with specific tag |
--no-isolated |
Hide documents with no connections |
--depth N |
Show only nodes N hops from start |
--stats |
Print statistics and exit (no visualization) |
# 1. First, get an overview of all connections and stats
python mdmap.py example/ --stats
# 2. See the full graph with directions
python mdmap.py example/ --directed -o knowledge-graph
# 3. Filter to just one topic
python mdmap.py example/ --tag programming -o programming-topic
# 4. Find what connects to a specific document
python mdmap.py example/ --depth 2 python-guide.md -o python-ecosystem
# 5. Clean view without isolated notes
python mdmap.py example/ --no-isolated --directed -o connected-onlyTry different graphviz engines for different layouts:
# Force-directed layout (organic, spreads out well)
python mdmap.py example/ --engine neato
# Hierarchical layout
python mdmap.py example/ --engine dot
# Circular layout
python mdmap.py example/ --engine circo
# Circular layout with compact spacing (better for many files)
python mdmap.py example/ --engine circo --compact
# Radial layout
python mdmap.py example/ --engine twopi
# Organic spring-model
python mdmap.py example/ --engine fdpNodes are colored based on their primary tag:
- Each unique tag gets a distinct color from the palette
- If a node has multiple tags, it uses the color of the first tag
- Untagged nodes appear in grey
- Larger nodes (higher in-degree) use bold font
-
Find important nodes: Nodes are sized by in-degree (how many documents link to them). Large nodes are "hubs" that many documents reference.
-
Use tags effectively: Create tags for topics, projects, or types. Then use
--tagto create focused sub-graphs. -
Combine filters:
# Programming topic without isolated notes python mdmap.py example/ --tag programming --no-isolated --directed -
Explore neighborhoods: Use
--depth 2 file.mdto see what connects around a specific document. -
Check connectivity: Use
--statsto quickly identify which documents have no connections. -
Export formats: Use
-f pngor-f pdffor presentations or printing. -
Compact large graphs: When visualizing directories with many markdown files, use
--compactwith the circo engine to reduce excessive spacing:python mdmap.py large-docs/ --engine circo --compact
You can fine-tune spacing further with
--septo adjust node separation.
The example/ directory contains:
example/
├── index.md # Home hub (core tag)
├── python-guide.md # Programming tutorial
├── web-dev.md # Programming tutorial
├── async-guide.md # Programming advanced
├── devops.md # Infrastructure operations
├── diary-2025-01-15.md # Personal diary entry
└── isolated.md # Unconnected note (for testing --no-isolated)
Graph structure:
index.mdis the central hubpython-guide.mdandweb-dev.mdreference each otherasync-guide.mdextends the programming topicdevops.mdconnects to deploymentdiary-2025-01-15.mdhas multiple referencesisolated.mdhas no connections (perfect for testing filters)
- Typical usage (50-500 files): Instant
- Large graphs (1000+ files): May take a few seconds
- For very large graphs, use
--tagor--depthto create focused views
Error: "Install python-graphviz"
pip install graphviz
# AND install the graphviz binary (not just the Python package)Error: "No markdown files found"
- Check directory path and that files end with
.md - Files in subdirectories are automatically included
Missing links in output:
- Links must be to
.mdfiles (case-sensitive on Linux) - External URLs are ignored by design
- Check file paths match actual filenames
Graph layout looks bad:
- Try different engines:
--engine dot,--engine fdp, etc. - For circo with many files, use
--compactor--septo reduce spacing - Adjust
--max-sizefor better spacing
#!/bin/bash
# Create a suite of views for your documentation
python mdmap.py . --stats > stats.txt
python mdmap.py . --directed -o full-graph
python mdmap.py . --tag programming -o programming
python mdmap.py . --no-isolated -o connected
python mdmap.py . --depth 2 -o neighborhoodsAutomatically generate graphs when your documentation changes:
# In your CI pipeline
python mdmap.py docs/ --directed -f png -o docs-graph
# Commit the graph to your repositoryThis tool is provided as-is for educational and professional use.