The tree
The directories of a repository carry its structure. No file declares its kind or its id.
| This | Carries |
|---|---|
| a directory | what it contains |
| a filename stem, or a directory name | the id |
| the depth | the kind |
order: in the index.md of a container | the order |
| the front matter | the title, and the other fields of the node |
Kinds by depth
| Path | Kind |
|---|---|
index.md | the repository root |
<domain>/index.md | a domain |
<domain>/<section>/index.md | a section |
<domain>/<section>/<topic>/index.md | a topic |
<domain>/<section>/<topic>/<deck>.md | a deck |
<domain>/checkpoints/index.md, and the index.md in each directory under it | a checkpoint folder |
any other .md file under <domain>/checkpoints/ | a checkpoint |
The root, a domain, a section, a topic and a checkpoint folder are containers. A container is a directory with its own index.md. A deck and a checkpoint are single files.
The app shows a topic as a chapter in its menu.
Three reserved names
| Name | Means |
|---|---|
index.md | the file of a container |
checkpoints/ | the checkpoints of a domain, beside its sections (Exams) |
assets/ | pictures, beside any index.md (Math, figures and assets) |
What the tree reads, and what it ignores
- At the root, every directory is a domain, and it must have an
index.md. - In a domain, every directory is a section, except
checkpoints/. - In a section, every directory is a topic.
- In a topic, every
.mdfile exceptindex.mdis a deck. A subdirectory other thanassets/is an error. - The tree ignores a
.mdfile where only directories belong. So aREADME.mdat the root, or a note beside the sections, is not content. - The tree ignores a directory whose name starts with
., so.github/is safe. - The tree ignores a file that is not
.mdand not a picture, for exampleLICENSE. - A picture (
.png,.jpg,.jpeg,.webp,.svg) outside anassets/directory is an error.
So keep only domains at the root, beside index.md, the files the tree ignores, and an optional assets/.
A subdirectory in a topic gives this fault:
ERROR ./math/alg/linears/more: `more` is a directory, and only files belong at this depth, so nothing can ever reach it: move it up a level
Two limits hold for every file. A .md file is 512 KB at most: a deck that long is many decks. A path is 16 levels at most below the root, its own name included, so phy/checkpoints/mit/2020/fall/q.md is six levels. The checker reads nothing deeper.
ERROR ./math/alg/linears/big.md: this file is 600000 bytes, over the 524288-byte cap on a `.md` file: split it into more decks
ERROR ./math/checkpoints/a/b/c/d/e/f/g/h/i/j/k/l/m/n/q.md: this sits more than 16 levels below the repository root, and nothing is read that deep: move it up
On disk, the checker reads files and directories only. It does not follow a symbolic link, and it refuses one. It also refuses a device, a pipe or a socket:
ERROR ./math/alg/linears/link.md: `link.md` is a symbolic link, and the check does not follow one: put the file itself in its place
Every container must hold at least one child:
ERROR ./math/alg/linears/index.md: this topic holds nothing: give it children, or take it out
Ids
An id is the filename stem of a file, or the name of a directory. The deck solving.md has the id solving. The topic linears/ has the id linears. Nothing declares an id.
- An id is unique per kind in a domain. Two topics in different sections cannot both be
basics. Two decks in different topics cannot both beintro. - Checkpoints are free from this rule. Two checkpoint folders can each hold a
2020.md. - Some ids are reserved. The app uses these words in its routes, so a domain, a section, a topic or a deck cannot take them:
index,today,practice,account,cards,checkpoint,checkpoints,exam,exams,reference,test.
Use lowercase letters, digits and - in an id. The id is part of the address of each page in the app.
Two decks with one id:
ERROR ./math/geo/lines/solving.md: `solving` is already the id of a deck, at math/alg/linears/solving.md: ids are unique per kind
A reserved id:
ERROR ./math/alg/test/index.md: `test` is reserved, because the app routes on it: rename this one
The id of a domain in the app
In the app, the id of a domain is not its directory name. It is a hash of the repository address and the directory name, for example bfa9e982. So two repositories can each hold a math/, and their progress never mixes. The ref is not part of the hash, so a branch and a tag of one repository give the same domain.
The address folds before the hash: https://GitHub.com/Alice/Algebra.git and github.com/alice/algebra give the same id. The directory name does not fold: Math/ and math/ are two domains.
A rename
A rename changes an id, and the ids of everything under it. A refresh in the app finds a renamed deck by its content and moves the progress with it. Publish and add to Stemin gives the rules. A change of order changes no id, so you can reorder at any time.
order:
The index.md of a container lists its children by id, in the order the learner meets them:
---
title: Electromagnetism
order: [fields, direct-current, components, dc-analysis, electromagnetic, alternating-current]
---
The checker holds order and the directory to an exact match, in both directions:
| Fault | Message |
|---|---|
a child that order does not list | `extra` is here and `order` does not list it: add it to `order`, or mark the file `draft: true` |
a name in order with no child | `order` names `missing`, and no file or directory here carries that id |
| a name twice | `order` names `solving` more than once |
| a name of a draft | `order` names `extra`, which is marked `draft: true`: take it out of `order`, or take the draft mark off |
order is optional. Without it, the children sort by id, in byte order: uppercase before lowercase, and 10 before 9.
The order of a domain lists its sections. It never lists checkpoints.
To add a deck, make two changes: add the file, and add its id to the order of its topic.
draft: true
Put draft: true in the front matter of a file to hold it back. A draft is outside the order match, and the app never builds it.
---
title: Phasors
draft: true
---
It works on every kind: a deck, a checkpoint, or the index.md of a container. On an index.md, it holds back the whole container and everything in it.
Front matter
Each file can start with YAML front matter between two --- lines. The first line of the file must be ---.
| Kind | Fields |
|---|---|
| the root | format (required), author, description, order |
| a domain | title, lang (required), author, labels, order, draft |
| a section | title, tiers, order, draft |
| a topic | title, tier, requires, order, draft |
| a deck | title, draft |
| a checkpoint folder | title, order, draft |
| a checkpoint | title, draft |
The root and the domain explains the fields of the root, the domain and the section. References and derivations explains requires.
A field that is not in this table is an error. The checker names the fields that the file takes:
ERROR ./math/alg/linears/solving.md: `titel` is not a field of a deck: a deck takes title, draft
YAML that does not parse is an error in every file, a deck and a checkpoint too:
ERROR ./math/alg/linears/solving.md: front matter will not parse: did not find expected ',' or ']' at line 2 column 1, while parsing a flow sequence at line 1 column 8
An index.md holds front matter and nothing else. Text after it is an error.
A node without a title: shows its id. A deck without a title: shows its full id in the app, for example bfa9e982/alg/linears/solving. Give each node a title.
A full example
This is the tree of the Stemin Foundations repository, shortened:
index.md the root: format, author, description, order
README.md ignored
math/ domain id: math
├── index.md title, lang, labels, order
└── alg/ section id: alg
├── index.md title, tiers, order
├── linears/ topic id: linears
│ ├── index.md title, tier, order
│ ├── solving.md deck id: solving
│ ├── matrix-form.md deck id: matrix-form
│ └── glance.md deck id: glance
└── quadratics/ topic id: quadratics
├── index.md title, tier, requires, order
└── quadratic-formula.md deck id: quadratic-formula
phy/ domain id: phy
├── index.md
├── eam/ section id: eam
│ ├── index.md
│ ├── fields/ topic id: fields
│ │ ├── index.md
│ │ ├── field.md deck
│ │ ├── electric-field.md deck
│ │ └── assets/ pictures for the decks of this topic
│ │ ├── gravity-field.svg
│ │ └── capacitor-field.svg
│ └── direct-current/ topic id: direct-current
│ ├── index.md
│ ├── charge.md
│ └── ohms-law.md
└── checkpoints/ the checkpoints of the domain
├── index.md order
└── eam/ checkpoint folder
├── index.md title, order
└── direct-current-quantities.md checkpoint
The two index.md files of the root and of math/:
---
format: 3.0.0
author: Alice Smith
description: Mathematics and physics, from first principles to exam practice.
order: [math, phy]
---
---
title: Mathematics
lang: en
labels: { reference: Formula, references: Formulary, derivation: Proof, checkpoint: Exam, checkpoints: Exams }
order: [alg]
---