Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Heading Maps

Heading maps are the mechanism that allows action-translation to reliably match sections across languages. They live in the YAML frontmatter of each translated document and map English heading text to translated heading text.

The problem

When translating ## Introduction to Chinese, the heading becomes ## 介绍. But the system needs to know that these are the same section — so that when the English “Introduction” changes, the correct Chinese section gets updated.

Position-based matching (section 1 maps to section 1, etc.) works as a fallback, but breaks when sections are added, removed, or reordered.

How heading maps work

Each translated document contains a translation block in its YAML frontmatter:

---
title: 蛛网模型
translation:
  title: 蛛网模型
  headings:
    Overview: "概述"
    Equilibrium: "均衡"
    Exercises: "练习"
---

The translation.title field stores the translated document title. The translation.headings is a flat map where keys are the English heading text — # markers and MyST roles stripped, otherwise untouched (no lowercasing, no hyphenation) — and values are the translated heading text as it appears in the target document. Nested headings use :: path keys (see the example below).

When the action needs to match sections, it:

  1. Parses the English document to find section headings and cleans each one (strips the # markers and any MyST roles)

  2. Looks up the cleaned heading — or its :: path, for nested sections — in the heading-map to find the corresponding translated heading

  3. Uses heading-map matches first, falls back to position matching for any unmatched sections

Format rules

Example with nested headings:

English source:

## Model Description
### Assumptions
### Equilibrium Conditions
## Numerical Examples

Target translation metadata:

translation:
  headings:
    Model Description: "模型描述"
    Model Description::Assumptions: "假设"
    Model Description::Equilibrium Conditions: "均衡条件"
    Numerical Examples: "数值示例"

When heading maps are created

When to edit manually

You generally don’t need to edit heading maps by hand. However, manual editing is useful when:

Important: The translation.headings values must exactly match the heading text in the document. If you change a heading, update both the heading text and the map entry.

Missing heading maps

If a target document has no translation metadata, the action falls back to position-based matching — section 1 in English maps to section 1 in the translation. This works when both documents have the same number of sections in the same order, but is fragile.

Safety guard: Position-based fallback is only used when the source and target have the same number of sections. When section counts differ (e.g., a new section was added to the source but the translation PR hasn’t been merged yet), positions are shifted and the fallback is disabled. Unmatched sections are treated as new and translated from scratch.

The status CLI command reports files with missing heading maps as MISSING_HEADINGMAP.

Key generation rules

The heading-map key is the English heading text with the # markers and any MyST roles stripped — nothing else changes. Capitalization, spaces, and punctuation are preserved exactly:

English headingHeading-map key
## IntroductionIntroduction
## Model DescriptionModel Description
### The Bellman Equation (under ## Model Description)Model Description::The Bellman Equation
## Exercise 1.1Exercise 1.1

Top-level sections use the bare heading; nested sections prefix the parent chain joined with ::, at any depth (International Trade::Regional Trade Agreements::Implementation Mechanisms). Values are always the bare translated heading text, never a path.