Git Course 0%

Markdown for documentation

Beginner Core Git VS Code UI IntelliJ UI GitLab UI GitHub UI ≈ 12 min

What you will learn

  • The Markdown syntax for headings, emphasis, lists, links, images, code, tables and quotes
  • The extras GitLab and GitHub add: task lists, issue links, mentions
  • How to preview Markdown in VS Code and IntelliJ, and what a Markdown linter checks

After this lesson you can

  • I can write a README or a guide in Markdown that renders correctly on GitLab and GitHub
  • I can fix the lint errors a pipeline reports on my Markdown

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.

Headings and paragraphs
# 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.
Emphasis and code
**bold**, *italic*, `inline code such as git status`

Use inline code for commands, file names (`README.md`) and values.
Lists
- A bullet
- Another bullet
  - Indented two spaces: a nested bullet

1. First step
2. Second step
3. Third step
Links and images
[Text of the link](https://gitlab.com)
[A file in the same repository](docs/faq.md)
[A section of this page](#section)
![Alternative text for the image](docs/images/logo.svg)

Code blocks
Three backticks, the language name, the code, three backticks:

```bash
git status
Text

```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:

  1. Title and one-line description. What the project is, in a sentence.
  2. Getting started. How to install and run it, with commands in code blocks.
  3. Usage. The most common things to do with it.
  4. Where the docs are. Links into docs/.
  5. How to contribute. A link to CONTRIBUTING.md.
  6. Licence and contact, if relevant.

Look at the playground's README.md: it follows exactly this shape, in fifty lines.

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:

Terminal
$ npx --yes markdownlint-cli "**/*.md" --ignore node_modules

No output means no problems. Each reported line shows the file, the line number, the rule (such as MD001) and a one-line explanation.

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.

  1. Open docs/faq.md in 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 to getting-started.md.
  2. Preview it in your editor.
  3. 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.
  4. Run git status and git diff to 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

Markdown
## 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.
Note the blank lines before the list and before the last paragraph, and the space after ## and after 1..

Check yourself

1. Your bullets render as one long paragraph. The most likely cause is…
2. What does Closes #12 in a merge request description do?
3. The pipeline reports MD040 Fenced code blocks should have a language specified. What is the fix?

Key terms

Markdown Repository (repo)