.gitmd2pdf.yml — Repository Configuration
A .gitmd2pdf.yml file checked into the root of your repository lets you control how gitmd2pdf compiles your markdown into a PDF — document metadata, which files to exclude, and the exact order in which content is rendered.
Premium feature. Free and Pro conversions ignore
.gitmd2pdf.ymlsilently. Premium conversions with a valid config show a green Config applied ✓ badge below the Convert button; a config with astructure:key also shows a blue Custom structure ✓ badge.
Quick start
Drop this file at the repo root:
schema_version: 1
title: "My Project Docs"
author: "Your Name"
version: "1.0.0"
date: auto
ignore:
- ".github/**"
- "**/DRAFT-*.md"
Convert the repo as a Premium user. Result: the PDF's title page uses your metadata, files matching ignore: are left out, and every other .md file is rendered in filesystem order.
That's the minimum viable config. To go further, keep reading.
Full schema
# ─── Schema version (required in practice) ─────────────────────────
# Pins the config against a known parser. If omitted, the parser
# assumes v1. Future breaking changes will bump this.
schema_version: 1
# ─── Document metadata (all optional) ──────────────────────────────
title: "My Project Docs"
author: "Gene Myers"
version: "1.2.0"
date: "2026-04-18" # or `auto` to use today's date
# ─── Files to exclude ──────────────────────────────────────────────
# Glob patterns matched against repo-root-relative paths.
# Applied BEFORE `structure:` is resolved, so an ignored file is
# gone even if something in `structure:` references it.
ignore:
- "README.md"
- "**/DRAFT-*.md"
- "internal/**"
- "node_modules/**"
# ─── Output hierarchy ──────────────────────────────────────────────
# If omitted entirely → fall back to filesystem hierarchy.
# If present → listed files appear in this order; any remaining
# (non-ignored) .md files are auto-appended afterward, indented
# to match their folder depth.
structure:
# A pure grouping node — has a title but no file of its own
- title: "Getting Started"
children:
- file: docs/intro.md
- file: docs/install.md
title: "Installation Guide" # per-file title override
# A node that IS a file, but also has children underneath it
- title: "Architecture"
file: design/overview.md
children:
- file: design/components.md
- file: design/data-flow.md
shift_headings: false # opt out of auto-demotion
# Glob-include a whole folder as a section
- title: "API Reference"
include: "api/**/*.md" # sorted alphabetically by default
sort: "filename" # or "manual"
# Single-file entry, no children
- title: "Appendix"
file: misc/glossary.md
Node types
| Field | Purpose |
|---|---|
title: |
Display title for this node. Overrides the file's own # H1 or front-matter title. |
file: |
Path to a single .md file, relative to the repo root. |
include: |
Glob that expands to multiple files. Mutually exclusive with file:. |
children: |
Nested list of nodes underneath this one. |
shift_headings: |
true (default) auto-demotes the file's headings to match YAML depth. false keeps them as written. |
sort: |
For include: — filename (default) or manual. frontmatter-order is planned for a future release. |
Behavior rules
- No
structure:key → walk the filesystem, render everything not inignore:, nest by folder depth. structure:present → render listed files in the given order, then auto-append any remaining non-ignored.mdfiles at the end. Each auto-appended file's TOC indent level equals its folder depth: a file at the repo root appears at indent 0,sub/foo.mdat indent 1,a/b/c.mdat indent 2, and so on. No synthetic group header is inserted; the tree shape is conveyed purely by indentation. If you want a named group for auto-appended files, add an explicit group node tostructure:with the files you care about nested under it.- Heading auto-shift — depth in YAML determines heading offset. A file at YAML depth 2 with
# Foo/## Barbecomes## Foo/### Barin the PDF. Opt out per file withshift_headings: false. - Per-file
title:wins over front-mattertitle:, which wins over the file's first# H1. ignore:runs first — if a file matchesignore:it's gone, even ifstructure:references it (a warning is emitted).schema_version:— optional but recommended. Current version is1. An unknown version emits a warning and falls back to the newest supported schema.- Config path is fixed — the file must be named
.gitmd2pdf.ymland sit at the repo root. No override path is supported. - Top-level metadata only —
title/author/version/dateapply to the whole PDF. Per-file metadata overrides are not supported in the current schema.
Expected PDF outline
When the full example above is rendered against a repo containing the referenced files, the PDF outline should look like:
My Project Docs
├── Getting Started
│ ├── intro (← docs/intro.md)
│ └── Installation Guide (← docs/install.md)
├── Architecture (← design/overview.md)
│ ├── components (← design/components.md)
│ └── data-flow (headings NOT shifted)
├── API Reference
│ └── (each file under api/**/*.md, sorted alphabetically)
└── Appendix (← misc/glossary.md)
Any .md file in your repo that isn't in ignore: and isn't referenced by structure: will auto-append at the end, indented by folder depth.
Badges after conversion
After a successful Premium repo conversion, gitmd2pdf shows a small status badge under the Repository URL card:
- green "Config applied ✓" — your
.gitmd2pdf.ymlwas found and parsed successfully. - blue "Custom structure ✓" — in addition to the above, your config includes a
structure:key that resolved to one or more nodes.
No badge means either:
- The repo has no
.gitmd2pdf.ymlat its root. - You are not on a Premium plan (Free / Pro conversions silently skip config loading).
- The YAML failed to parse — check the conversion error message; a parse error returns an error instead of a silent skip.
Ready-made example configs
Copy either example below into the root of your repository as .gitmd2pdf.yml, push, and run a Premium repo conversion.
Example 1 — metadata + ignore only (triggers the green "Config applied" badge)
schema_version: 1
title: "My Document Repository — Basic Config Example"
author: "Mods Software"
version: "1.0.0"
date: auto
# Glob patterns matched against repo-root-relative paths.
ignore:
- ".github/**"
- "**/DRAFT-*.md"
- "Testing/**"
Example 2 — full structure: tree using every node type (triggers both badges)
schema_version: 1
title: "My Document Repository — Custom Structure"
author: "Mods Software"
version: "1.0.0"
date: auto
ignore:
- ".github/**"
- "**/DRAFT-*.md"
# Explicit output hierarchy. Unlisted .md files are auto-appended at the
# end, indented by folder depth.
structure:
# Grouping node — title only, no file of its own
- title: "Introduction"
children:
- file: README.md
title: "About This Repository"
# Simple single-file node with a title override
- title: "Planning"
file: Planning/My Plan.md
# Glob include — pulls every .md file under Projects/ in filename order
- title: "Active Projects"
include: "Projects/*.md"
sort: filename
# Grouping with per-file title overrides and a heading-shift opt-out
- title: "Reference Examples"
children:
- file: Examples/Formatting Showcase.md
- file: Examples/Image Examples.md
title: "Embedding Images"
- file: Examples/Edge Cases.md
shift_headings: false
# File-node that also has children nested underneath
- title: "Quality Assurance"
file: Testing/Test plan.md
children:
- file: Testing/Test Cases.md
# Any .md file not listed above (e.g. Reports/Monthly Status.md) auto-appends
# at the end of the PDF at its folder-depth.
Validation errors you might see
If your config is present but broken, the conversion will fail with a message starting with gitmd2pdf config:. Common ones:
.gitmd2pdf.yml must be a YAML mapping at the top level— the file parsed but the top level isn't a dictionary (e.g. you wrote a list at the root). Wrap everything in a single mapping.`ignore:` must be a list of glob strings—ignore:was a string or mapping instead of a list. Prefix every entry with-and make sure each entry is quoted.unknown top-level key …(warning, conversion continues) — you wrote a key the parser doesn't recognize. Typical causes: typos (structur:instead ofstructure:) or renamed keys from an older draft.schema_version X is not supported by this parser(warning) — falls back to v1 behavior. If you set a future version explicitly, double-check it.
Structure-specific warnings (emitted as [structure] in conversion logs) include missing files, zero-match globs, duplicate entries, and malformed structure: entries. The conversion still runs; warnings surface files you might not have meant to skip.
Non-Premium behavior
Free and Pro conversions ignore .gitmd2pdf.yml entirely. No warning, no error — the PDF is produced from the filesystem as if the file weren't there. The green and blue badges are how you verify Premium config loading actually ran.
If you're on Premium and still see no badge, the file is probably at a subfolder rather than the repo root, or the YAML has a parse error that's being swallowed — try loading the file through any YAML validator first to confirm.