Markdown for documentation
Beginner Core Git VS Code UI IntelliJ UI GitLab UI GitHub UI
Why this matters
Documentation in a repository is written in Markdown: READMEs, guides, changelogs, and also every issue, merge request description and comment on GitLab and GitHub. Markdown is plain text, so Git can show exactly what changed and reviewers can comment on a line. Fifteen minutes of syntax covers almost everything you will ever write.
The syntax
Markdown is text with a few punctuation conventions. What you type on the left; what readers see on the right.
# Page title (one per file)
## Section
### Subsection
A paragraph is one or more lines of text.
Lines in the same paragraph join together.
A blank line starts a new paragraph.**bold**, *italic*, `inline code such as git status`
Use inline code for commands, file names (`README.md`) and values.- A bullet
- Another bullet
- Indented two spaces: a nested bullet
1. First step
2. Second step
3. Third step[Text of the link](https://gitlab.com)
[A file in the same repository](docs/faq.md)
[A section of this page](#section)
Three backticks, the language name, the code, three backticks:
```bash
git status
```markdown title="Tables, quotes, rules"
| Column | Another column |
|---|---|
| a cell | another cell |
> A quotation or a highlighted note.
---
The language name after the opening backticks (bash, python, yaml, markdown) turns on syntax colouring; leave it out for plain output. Inside a code block nothing is interpreted, which is why commands and file contents belong there.
Two rules cause most rendering surprises: put a blank line before a list, a table or a code block, and put a space after # in headings and after - in bullets.
What GitLab and GitHub add
Both platforms extend Markdown ("GitLab Flavored Markdown", "GitHub Flavored Markdown") with things you will use in issues and merge requests:
| You type | You get |
|---|---|
- [ ] task / - [x] done task |
A checklist with real checkboxes (the CONTRIBUTING file uses one) |
#12 |
A link to issue 12 |
!47 (GitLab) / #47 (GitHub) |
A link to merge request 47 / pull request 47 |
@ana |
A mention that notifies Ana |
a1b2c3d (a commit hash) |
A link to the commit |
:tada: |
An emoji (both platforms) |
~~struck~~ |
~~Struck-through text~~ |
In merge request descriptions, Closes #12 (or Fixes #12) is not decoration: it closes the issue automatically when the merge request is merged.
README conventions
A README is the front door of a project. Readers expect, in this order:
- Title and one-line description. What the project is, in a sentence.
- Getting started. How to install and run it, with commands in code blocks.
- Usage. The most common things to do with it.
- Where the docs are. Links into
docs/. - How to contribute. A link to
CONTRIBUTING.md. - Licence and contact, if relevant.
Look at the playground's README.md: in about fifty lines it follows most of that shape, with the title and description, what is in the folder, how to run it, how to run the tests, links to the documentation, and the team. It has no separate contributing section, because it links CONTRIBUTING.md from the documentation list instead, and no licence section, because the project is fictional. That is normal: the order above is a convention people expect, not a form to fill in.
Previewing
Markdown is readable as text, so cat docs/faq.md is a preview of sorts. The pipeline's Markdown check can also be run locally, if Node is installed:
$ npx --yes markdownlint-cli "**/*.md" --ignore node_modulesNo output means no problems. Each reported line shows the file, the line number, the rule (such as MD001) and a one-line explanation.
- Open a
.mdfile. - Press Ctrl+Shift+V (⇧⌘V) for a preview tab, or Ctrl+K then V for a preview beside the editor that updates as you type. Fallback: Command Palette → Markdown: Open Preview to the Side.
- Install the markdownlint extension (David Anson) to see the same lint warnings the pipeline reports, underlined in the editor.
- Open a
.mdfile. IntelliJ shows editor and preview side by side by default; the icons at the top right of the editor switch between Editor only, Editor and preview and Preview only. - If the preview is missing, enable the bundled Markdown plugin in Settings → Plugins.
GitLab renders every .md file when you click it in Code → Repository, and renders the README on the project's home page. To edit in the browser, open the file and click Edit → Edit single file (or Open in Web IDE for several files); the editor has a Preview tab. Issue and merge request descriptions have a preview tab too.
GitHub renders .md files in the Code tab and the README below the file list. The pencil icon opens an editor with a Preview tab. Issue and pull request text boxes have Write and Preview tabs.
Lint rules you will meet
Pipelines often run markdownlint on documentation. The rules that catch most people:
| Rule | Message | Fix |
|---|---|---|
| MD001 | Heading levels should only increment by one level at a time | Do not jump from # to ### |
| MD022 / MD032 | Headings and lists should be surrounded by blank lines | Add a blank line before and after |
| MD041 | First line in a file should be a top-level heading | Start the file with # Title |
| MD009 | Trailing spaces | Delete spaces at line ends (your editor can show them) |
| MD040 | Fenced code blocks should have a language specified | Add bash, text, yaml… after the backticks |
The playground's .markdownlint.json turns off the line-length rule (MD013), a common team choice.
Common mistakes
- A list glued to the paragraph above. Without a blank line, the bullets render as one paragraph. Add the blank line.
- Tabs for nesting. Use two (or four) spaces to indent nested bullets; tabs render unpredictably.
- Absolute links to files.
[FAQ](/Users/ana/trailguide/docs/faq.md)works only on Ana's machine. Use paths relative to the file:[FAQ](faq.md). - Screenshots of code. Paste the code in a code block; images cannot be searched, copied or diffed.
- Editing the rendered page. On GitLab and GitHub you edit the source text; the rendering is automatic.
Try it yourself
Goal: add a FAQ entry with a list and a link, preview it, and check it with the linter.
- Open
docs/faq.mdin the playground and add, at the end, a heading## How do I run the tests?followed by a two-step numbered list and a link togetting-started.md. - Preview it in your editor.
- If Node is installed, run the lint command from the Terminal tab; otherwise check by eye that headings and lists have blank lines around them.
- Run
git statusandgit diffto see what Git recorded, then decide whether to commit it or restore the file.
Expected result: the preview shows a heading, a numbered list and a working link; the linter reports nothing; git diff shows only added lines.
Show solution
## How do I run the tests?
1. Open a terminal in the `trailguide` folder.
2. Run `python3 -m unittest discover -s tests -v`.
See [Getting started](getting-started.md) for installing Python.## and after 1..