Skip to content

Multi File Documents

Brett Terpstra edited this page Jan 4, 2026 · 2 revisions

Multi-file documents with Apex

Apex can assemble larger documents from many smaller Markdown files. There are two primary tools for this:

  • --combine: Apex’s native Markdown combiner, with optional GitBook-style SUMMARY.md support.
  • --mmd-merge: A MultiMarkdown-compatible mode that emulates mmd_merge.pl, reading a plain-text index file to stitch documents together.

Both modes output raw Markdown, which you can then pipe back into apex for full HTML rendering.


Using --combine

Basic usage with multiple files

You can pass multiple Markdown files after --combine. Apex will:

  • Read each file in order
  • Expand any include syntax it supports (Marked, MultiMarkdown, iA Writer)
  • Separate each document with blank lines

Example:

apex --combine intro.md chapter1.md chapter2.md > combined.md

# Then render the combined Markdown:
apex combined.md --standalone --title "My Book" -o book.html

Or in a single pipeline:

apex --combine intro.md chapter1.md chapter2.md \
  | apex --standalone --title "My Book" -o book.html

Using a GitBook-style SUMMARY.md

When one of the inputs to --combine is named SUMMARY.md, Apex treats it as a GitBook index. It scans the file for Markdown links and combines the referenced pages in order:

Example SUMMARY.md:

# My Book

- [Introduction](intro.md)
- [Getting Started](getting-started.md)
- [Advanced Topics](advanced.md)
  - [Performance](performance.md)
  - [Appendix](appendix.md)

To build your book:

apex --combine SUMMARY.md \
  | apex --standalone --title "My Book" -o book.html

--combine will:

  • Follow the link targets (intro.md, getting-started.md, etc.)
  • Expand any file includes inside those documents
  • Output a single Markdown stream to stdout, ready for final processing

Using --mmd-merge (MultiMarkdown-style)

--mmd-merge emulates the original MultiMarkdown mmd_merge.pl script. It reads one or more plain text index files and:

  • Skips blank lines
  • Treats lines whose first non-whitespace character is # as comments
  • Treats all other lines as filenames to include
  • Uses indentation (tabs or groups of four spaces) to increase the header level of the included file

Example mmd_merge index file

metadata.txt
Chapter-1.md
    sub-chapter-1-1.md
    sub-chapter-1-2.md
Chapter-2.md
    sub-chapter-2-1.md
    sub-chapter-2-2.md
FAQ.md
Acknowledgments.md

Behavior:

  • metadata.txt, Chapter-1.md, Chapter-2.md, FAQ.md, Acknowledgments.md are included at their original heading levels.
  • Files indented by one tab or four spaces (sub-chapter-1-1.md, sub-chapter-1-2.md, etc.) have all headings shifted down one level:
    • # Heading## Heading
    • ## Subheading### Subheading, etc.

Comments are supported:

# This is my book index
metadata.txt

# Part 1
Chapter-1.md
    sub-chapter-1-1.md

Lines starting with # after optional whitespace are ignored.

Running --mmd-merge and piping back to Apex

Assuming the index file above is named index.txt:

apex --mmd-merge index.txt \
  | apex --mode mmd --standalone --title "My MMD Book" -o book.html

You can also merge multiple index files:

apex --mmd-merge part1.txt part2.txt \
  | apex --mode mmd --standalone --title "My Two-Part Book" -o book.html

Notes:

  • --mmd-merge does not itself expand includes; it just concatenates files and shifts headings.
  • For full MultiMarkdown semantics, use --mode mmd when piping the merged Markdown back into Apex.

Combining multiple files directly on the command line

You don’t need an index file to combine documents. With --combine, you can just list the files in order:

apex --combine metadata.md intro.md chapter1.md chapter2.md \
  | apex --standalone --title "Direct Combine" -o book.html

This approach works well when:

  • The order is simple and fixed
  • You don’t need header-level shifting based on indentation

If you need finer control over header levels, use:

  • --mmd-merge with an index file (indentation-based)
  • Or explicit headings inside your individual files

Building multi-file documents with include syntax

In addition to --combine and --mmd-merge, Apex supports file includes inside Markdown. This lets you treat one file as the “root” and pull in other files at specific points.

Supported include syntaxes:

  • MultiMarkdown: {{file.md}}
  • Marked: <<[file.md] (Markdown include), <<(file.ext) (code include), <<{file.html} (raw HTML)
  • iA Writer: /file.md at the start of a line

MultiMarkdown include example

book.md:

Title: My Included Book

{{metadata.md}}

{{intro.md}}
{{chapter1.md}}
{{chapter2.md}}
{{appendix.md}}

Build and render:

apex book.md --standalone --title "My Included Book" -o book.html

Marked-style include example

book.md:

# My Marked-Style Book

<<[intro.md]
<<[chapter1.md]
<<[chapter2.md]

Render:

apex book.md --standalone --title "My Marked Book" -o book.html

iA Writer-style include example

book.md:

# My iA Writer-Style Book

/intro.md
/chapter1.md
/chapter2.md

Render:

apex book.md --standalone --title "My iA Book" -o book.html

Combining includes with --combine

You can combine both approaches: use includes inside files and then use --combine on top:

# Each chapter uses includes, and we combine chapters into one big stream:
apex --combine part1.md part2.md part3.md \
  | apex --standalone --title "Big Included Book" -o book.html

This is especially useful when:

  • Each part has its own local includes
  • You want a single final HTML output

Choosing between --combine, --mmd-merge, and includes

  • Use --combine when:

    • You want Apex to expand includes
    • You like GitBook-style SUMMARY.md navigation
    • You just want to pass multiple files and let Apex concatenate them
  • Use --mmd-merge when:

    • You have existing MultiMarkdown workflows or mmd_merge.pl index files
    • You want indentation-based header level shifting
    • You want a very simple, text-only index format
  • Use include syntax when:

    • You want one “master” document that controls where content appears
    • You prefer to keep structure inside Markdown files rather than an external index

All three can be mixed and matched, and all ultimately produce Markdown that you can feed back into apex to generate the final HTML, PDF (via Pandoc), or other formats in your toolchain.

Quick Links

Clone this wiki locally