A Python tool for combining Markdown files from a folder hierarchy into a single compiled document. This tool is perfect for creating documentation, books, or reports from multiple Markdown files while preserving structure and formatting.
- Hierarchical compilation: Combines Markdown files from nested folders
- Configurable ordering: Use YAML files to specify the order of files and folders
- Title management: Automatically handles titles and heading levels
- Frontmatter support: Preserves YAML frontmatter as metadata sections
- Flexible output: Control what gets included and how it's formatted
- Recursive processing: Optionally compile subdirectories recursively into separate files
- Title substitutions: Replace titles using configuration files
- Clone this repository:
git clone <repository-url>
cd compile-markdown- Install dependencies:
pip install -r requirements.txtpython compile_markdown.pyThis will compile all Markdown files in the current directory into a compiled folder.
python compile_markdown.py [OPTIONS]-a, --all: Include all markdown files, even those not specified in YAML configuration-c, --config PATH: Path to the YAML config file (default:compile.yamlin source directory)-k, --keep-numbers: Keep leading numbers in titles (e.g., "01 Introduction" stays as is)-o, --output PATH: Output directory or file path (default:./compiledin source directory)- If PATH is a directory: Creates a
.mdfile named after the source folder inside the directory - If PATH is a file: Uses the specified filename directly
- If PATH is a directory: Creates a
-p, --propagate: Propagate compilation up to parent directories-r, --recursive: Compile files recursively - creates separate compiled files for each subdirectory-s, --source PATH: Path to the source directory (default: current working directory)-t, --target PATH: Path to the target directory relative to source directory-y, --yaml PATH: Path to the YAML order file (default:order.yamlin directory to compile)-m, --mod PATH: Path to the YAML modification file for title substitutions
Define the order and structure of your compilation:
root:
- introduction.md
- getting-started:
- title: "Getting Started Guide"
- order:
- installation.md
- configuration.md
- advanced-topics
- conclusion.mdSet default options for compilation:
include_all: true
keep_numbers: false
output: "./docs"
recursive: true
source: "./content"
yaml_path: "./config/order.yaml"
propagate: false
target: ""
modification_path: "./config/modifications.yaml"Replace or modify titles during compilation:
substitutions:
"01 Getting Started": "Quick Start Guide"
"API Reference": "Complete API Documentation"The tool's output behavior depends on whether you specify a directory or a file path:
When the output path is a directory (or doesn't exist and will be created as a directory):
python compile_markdown.py -s ./my-docs -o ./output/- Creates the directory
./output/if it doesn't exist - Generates a file named
my-docs.mdinside the output directory - The filename is derived from the source folder name (with leading numbers removed)
When the output path includes a filename:
python compile_markdown.py -s ./my-docs -o ./output/documentation.md- Creates the directory
./output/if it doesn't exist - Generates a file named
documentation.mdwith the compiled content - Uses the exact filename you specify
When using the --recursive flag, the tool creates separate compiled files for each subdirectory:
python compile_markdown.py -r -s ./my-docs -o ./output/- Creates a compiled file for the root directory:
./output/my-docs.md - Creates a compiled file for each subdirectory:
./output/subdir1/subdir1.md,./output/subdir2/subdir2.md, etc. - Maintains the directory structure in the output, with each folder getting its own compiled Markdown file
- Each subdirectory's compiled file contains only the Markdown files from that specific directory
Without specifying an output:
python compile_markdown.py- Creates a
compileddirectory in the source folder - Generates a file named after the source directory (e.g.,
my-project.md)
- File Discovery: The tool scans the source directory for Markdown files
- Order Resolution: If an
order.yamlfile exists, it uses that to determine file order; otherwise, it processes files alphabetically - Content Processing:
- Extracts and preserves YAML frontmatter
- Adjusts heading levels based on folder depth
- Removes or modifies leading numbers from titles
- Applies title substitutions
- Compilation: Combines all content into a single Markdown file with proper hierarchy
# Compile current directory to default location (./compiled/)
python compile_markdown.py
# Output to a specific directory (creates "docs.md" inside ./output/)
python compile_markdown.py -s ./docs -o ./output/
# Output to a specific file
python compile_markdown.py -s ./docs -o ./output/combined.md
# Output to current directory with custom filename
python compile_markdown.py -o ./my-documentation.md# Recursively compile each subdirectory into separate files
python compile_markdown.py -r -s ./docs -o ./output/
# Recursive with custom order file and all options
python compile_markdown.py -r -y ./config/book-order.yaml -o ./published/ --all# Use all options
python compile_markdown.py \
--source ./content \
--output ./dist/documentation.md \
--yaml ./config/order.yaml \
--mod ./config/titles.yaml \
--recursive \
--all \
--keep-numbersproject/
├── compile_markdown.py
├── content/
│ ├── order.yaml
│ ├── 01-introduction.md
│ ├── 02-getting-started/
│ │ ├── installation.md
│ │ └── configuration.md
│ ├── 03-advanced/
│ │ ├── .no-headings
│ │ ├── api.md
│ │ └── plugins.md
│ └── conclusion.md
└── compiled/
└── content.md # Auto-generated filename from source folder
project/
├── compile_markdown.py
├── docs/
│ ├── introduction.md
│ ├── getting-started/
│ │ ├── installation.md
│ │ └── configuration.md
│ └── advanced/
│ ├── api.md
│ └── plugins.md
└── output/
├── docs.md # Root compilation
├── getting-started/
│ └── getting-started.md # Subdirectory compilation
└── advanced/
└── advanced.md # Subdirectory compilation
.no-headings: Place this file in a directory to replace section headings with horizontal rules (* * *).end_compile: Place this file in a directory to prevent recursive compilation beyond this pointorder.yaml: Defines the compilation order for the directory- Frontmatter: YAML frontmatter in Markdown files is preserved as "Metadata" sections
- Python 3.6+
- PyYAML 6.0.2
- Fork the repository
- Create a feature branch
- Add your changes with tests
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.