Org-Mode Include Patterns for Long Research Pages

Table of Contents

1. Problem

A single index.org with case studies, diagrams, and data tables hits 500+ lines. Editing becomes slow, the narrative is hard to navigate, and adding a new case study means touching the entire file.

2. Solution: #+INCLUDE with subdirectory

Split case studies (or any large section) into separate .org files under an includes/ subdirectory. The parent index.org uses #+INCLUDE to pull them in at publish time.

research/my-topic/
  index.org                   # 80 lines -- thesis, #+INCLUDEs, resources
  includes/
    case-001-first.org        # 45 lines
    case-002-second.org       # 175 lines
    case-003-third.org        # (add later -- one file, one #+INCLUDE line)
  diagram-foo.png
  diagram-bar.png
  data/
    measurements.csv

In index.org:

* Case Study: First

#+INCLUDE: "includes/case-001-first.org"

* Case Study: Second

#+INCLUDE: "includes/case-002-second.org"

3. Image Path Resolution

The critical gotcha: #+INCLUDE changes the base directory for [[file:...]] references. An included file's [[file:diagram.png]] resolves relative to the include file's location, not the parent.

3.1. Rule

Images live in the parent directory (next to index.org). Include files reference them with ../:

;; In includes/case-001-first.org:
[[file:../diagram-foo.png]]          ← resolves to parent dir
[[file:../data/measurements.csv]]    ← resolves to parent/data/

3.2. Why this works for both editing and publishing

  • Editing the include file directly: Emacs resolves ../ from includes/, which points to the parent directory. Inline image display (C-c C-x C-v) works.
  • Publishing via #+INCLUDE: org-publish expands the include into index.org's context. The ../ in the HTML output resolves from the includes subdirectory on the server, pointing back to the parent where the images are deployed.
  • Editing index.org: The includes are opaque until expanded. Use C-c ' on the #+INCLUDE line to open the included file.

4. Heading Levels

#+INCLUDE preserves heading levels from the included file. If your include starts with ** subheadings (because the * heading is in the parent), the structure is correct. If it starts with *, it becomes a peer of the parent's heading.

;; In index.org:
* Case Study: Storm          ← * heading in parent

#+INCLUDE: "includes/case-002-storm.org"

;; In includes/case-002-storm.org:
On May 19, 2026...            ← body text, no * heading

** The Signal                 ← ** subheading (correct level)
** Holding Patterns           ← ** subheading

5. Cross-references Between Includes

Within the published page, an include can link to a heading in another include with [[*Heading]] or [[#custom-id]]. Both resolve, because #+INCLUDE inlines every fragment before export. While editing, each include is still self-contained: Emacs can't follow those links from the fragment alone.

From outside the page, link to the parent, never to the fragment: [[file:../topic/index.org::#custom-id]], not [[file:../topic/includes/x.org]]. Fragments don't publish as pages of their own; see 6.

6. What Gets Published

Only index.org becomes a page. The publish :exclude in publish.el matches \\(^\\|/\\)includes/, which is the same rule the sitemap generator and the pocket-es indexer already used. Fragments therefore never appear as standalone .html or .md pages, in the sitemap, or in search. Until 2026-10-08 the publish rule was ^includes/, which matched only site/includes/, so fragments under research notes leaked out as untitled pages. The experiment and the fix are recorded in Org-Publish at Scale.

Images and data files under includes/ still ship. The wal.sh-research-images attachment project publishes them, and it does not use this exclude.

A separate assembled source file such as source.org is unnecessary: index.org plus its includes already is the source. If you need one flat file, org-org-publish-to-org produces it. Flat NN-x.org siblings next to index.org are the one layout to avoid, because each sibling publishes as a page of its own.

7. When to Split

Split when:

  • A section exceeds ~100 lines
  • The section is a self-contained case study or analysis
  • You expect to add more sections of the same type later
  • Multiple people (or agents) edit different sections concurrently

Don't split:

  • Sections under 50 lines
  • Tightly coupled content that references adjacent sections by line
  • Tables of contents (the parent owns the ToC)

8. Naming Convention

includes/case-NNN-slug.org for numbered case studies. The number controls ordering; the slug is human-readable. Examples:

  • case-001-baw48.org
  • case-002-storm.org
  • case-003-winter-storm.org
  • section-architecture.org
  • section-methodology.org