Skip to content

MCF 1.1 course authoring

Quick start

  1. Create a package-root manifest.yaml.
  2. Declare mcf: "1.1" and a package kind.
  3. For a course, add ordered chapter directories under chapters/.
  4. Add chapter.yaml and ordered .mcf lessons to each chapter.
  5. Put every lesson's Markdown inside explicit activities.
  6. Declare local assets that need attribution or accessibility alternatives.
  7. Validate before distributing a directory or .mcf.zip.

Use courses/minimal as the smallest current course and courses/feature-showcase as the complete syntax example.

Minimal course

mcf: "1.1"
kind: course
id: example-course
title: "Example Course"
language: en
chapters:
  - source: chapters/start

chapters/start/chapter.yaml:

id: start
title: "Start"
lessons:
  - lessons/welcome.mcf

chapters/start/lessons/welcome.mcf:

---
id: welcome
title: "Welcome"
---

:::mcf-activity
type: notes
id: welcome-notes
:::

# Welcome

This is portable course source.

:::mcf-end

Authoring guidance

  • Treat IDs as permanent public handles; do not derive persistence from titles.
  • Put ordering in manifests and chapter files, never in filename sorting.
  • Use BCP 47 language tags such as en, fr-CA, or zh-Hant.
  • Use ISO 8601 durations such as PT45M and PT2H.
  • Give every informative image meaningful Markdown alt text.
  • Declare asset licenses, creators, captions, transcripts, and descriptions.
  • Use open_response for ungraded reflection and essay for manually evaluated extended writing.
  • Attach rubrics to manually evaluated essays and assignments.
  • Keep completion rules about authored requirements, never a learner's stored status.
  • Prefer standard core fields; use a reverse-domain extension only when the core cannot express the requirement.
  • Treat imported packages as untrusted content.

Math and YAML escaping

TeX in an ordinary Markdown activity body is written directly in the body. For example, inline math can contain \times, \sqrt, \%, \frac, and subscripts:

The scale factor is $12\times 12$, and $x_1$ is the first value.

Display math is also written directly in the Markdown body:

$$
\frac{1}{2} = 0.5
$$

TeX in a YAML rich-content field such as prompt, hint, explanation, option text, or feedback is decoded by YAML before Markdown and math processing. Use a single-quoted scalar for a one-line value:

explanation: '$12\times 12 = 144$; $\sqrt{16}=4$; $37\%=0.37$.'

Use a literal block scalar, preferably |-, for multiline or display math:

explanation: |-
  $$
  \frac{1}{2} + \sqrt{x^2}=|x|
  $$

If double quotes are deliberately required, escape each literal backslash:

prompt: "Evaluate $\\frac{1}{2}$ and identify $x_1$."

Do not rely on a compiler or reader to repair malformed or semantically unintended source. In particular, an unescaped \t in a YAML double-quoted scalar becomes a tab; the decoded value no longer contains the intended \times command. The same kind of issue can affect \sqrt, \%, and \frac.

Standalone content

Set kind to module, lesson, question_bank, or asset_collection to distribute reusable units. Every package still has a root manifest.yaml.

Use package relationships for translations, versions, derivations, and required question banks. Do not copy external package content without preserving its license and attribution.

Validation

From this repository:

python3 scripts/check_conformance.py courses/feature-showcase

A passing schema check is necessary but not sufficient. Full validation also checks paths, files, lesson grammar, uniqueness, answer references, rubric and completion references, and package relationships.