Markdown basics¶
Markdown is a lightweight markup language that enables you to format plain text using a simple syntax. It's easy to read and easy to write, eventually converting into structurally valid HTML, and is widely used for documentation, readme files, and content management systems. It enables you to focus on writing without worrying about complex formatting, making it an ideal choice for collaborative documentation projects.
It's text-based, meaning you can use a text editor to create and edit Markdown files. This makes it highly portable and compatible with version control systems like Git, enabling collaborative editing and tracking of changes over time. Plain text files with the .md extension store the Markdown. You can then share, version, and convert these files into HTML for web publishing.
Below is a summary of the most common formatting elements you'll use in a .md file.
Zensical Markdown
Zensical uses a flavour of Markdown called Python Markdown with some extensions. This ensures that your Markdown files are compatible with a wide range of tools and platforms, while also providing additional features for enhanced formatting and functionality. There are some differences between Zensical Markdown and other flavours of Markdown, so it's important to refer to the Zensical documentation for details.
Markdown Live Preview
You can use the Markdown Live Preview website to see how your Markdown will look when rendered. This is a great way to check your formatting and make adjustments as needed.
Headings¶
Add hash signs (#) before your text to create a heading. The number of hashes corresponds to the heading level.
The toc extension automatically turns every heading into a linkable anchor (the ΒΆ symbol you can see next to each heading on this page), and generates the sidebar and table of contents from them. The attr_list extension lets you override the generated anchor or add a CSS class, by adding an attribute block after the heading text, for example ## Heading {: #custom-id }. This lets you attr_list attach IDs, classes, and other HTML attributes almost anywhere in your Markdown.
Warning
As covered in Navigation structure in Customisation, each page in this template can contain only one heading 1 (#) - it's what drives the automatic chapter/section numbering (e.g. "9.1") across the whole document. Start a new page instead of adding a second heading 1 to this one.
Text formatting¶
You can make text bold, italic, or both to add emphasis without needing complex menus.
The pymdownx.betterem extension handles bold and italic emphasis, and is more consistent about nested and mixed emphasis (for example **bold _and italic_**) than plain Python Markdown. Strikethrough isn't part of core Markdown at all - the pymdownx.tilde extension provides it here. That same extension also enables subscript (H~2~O), and the paired pymdownx.caret extension enables superscript (A^T^A) and underline (^^text^^). See Formatting in Zensical basics for these and other extended styles, such as highlighting text and keyboard keys.
Links and images¶
The syntax for these is similar. Just add an exclamation mark at the beginning for an image.
[Link text](https://example.com)
[Link with title](https://example.com "Hover title")
[Reference-style link][example-ref]


[example-ref]: https://example.com "Hover title"
The attr_list extension lets you attach HTML attributes to a link or image by adding a {: ... } block straight after it, with no space:
This template uses that same syntax with a target="_blank" attribute throughout, to make external links (like the ones on this page) open in a new browser tab on the website. the PDF build strips those attributes back out, since "open in a new tab" has no meaning in a printed document.
The pymdownx.magiclink extension also auto-links bare URLs (https://example.com becomes a clickable link with no []() needed) and recognises shorthand references to GitHub/GitLab issues, pull requests, and commits.
Lists¶
Markdown handles ordered (numbered), unordered (bulleted), and definition lists.
Unordered lists¶
Use a minus sign (-), asterisk (*), or plus sign (+).
Ordered lists¶
Simply use numbers followed by a period. Python Markdown renumbers the list for you based on the first number used, so 1. for every item (or repeating the same number) is a common way to avoid manually renumbering items as you edit.
Definition lists¶
The def_list extension adds definition lists: a term on its own line, followed by one or more indented lines starting with a colon.
Term
: Definition of the term, indented under it.
Second term
: First definition.
: A second definition for the same term.
Code blocks¶
Markdown is a favourite for developers because of how it handles code snippets. This template uses the pymdownx.superfences extension for fenced code blocks (in place of Python Markdown's more limited built-in fenced_code), together with pymdownx.highlight and pymdownx.inlinehilite for syntax highlighting.
- Inline code: wrap text in backticks:
code. - Fenced code blocks: wrap multiple lines in "fences" using three backticks (```). Add the language name straight after the opening fence for syntax highlighting.
pymdownx.superfences also lets you nest fenced code blocks inside other Markdown structures such as lists and admonitions, and supports custom fence types - the Mermaid diagrams in Diagrams are a fenced ```mermaid block rather than plain code. For line highlighting, titled code blocks, and inline code with syntax highlighting, see Code blocks in Zensical basics.
Tables¶
Use pipes | and hyphens - to create tables. The tables extension is what enables this - it isn't part of core Python Markdown. Add colons to the separator row to control column alignment.
| Left-aligned | Centred | Right-aligned |
|:-------------|:-------:|--------------:|
| Row 1 | Data | Data |
| Row 2 | Data | Data |
Horizontal rule¶
Put three or more hyphens, asterisks, or underscores on their own line, surrounded by blank lines, to create a thematic break:
Task lists¶
Task lists aren't part of core Python Markdown either - they're enabled by the pymdownx.tasklist extension, configured in this template to render as clickable checkboxes rather than plain [x]/[ ] text.
Blockquotes¶
Use the > symbol before the text to create a callout or quote. Nest additional > symbols to quote within a quote.
For structured callouts with an icon and title (notes, warnings, tips), use an admonition instead - see Admonitions in Zensical basics.
Quick tips¶
-
Line breaks: To create a line break without starting a new paragraph, end a line with two or more spaces before hitting enter.
-
Escaping characters: If you want to show a literal character (like a
*) without it formatting the text, use a backslash:\*. -
Attributes on any element: The
attr_listextension used for links, images, and headings above works on most other Markdown elements too - for example adding a CSS class to a paragraph or list item with{: .my-class }directly after it.
Where to go next¶
The syntax on this page works in any Markdown file, including plain README files on GitLab or GitHub. Continue to Zensical basics for the extensions that only work in this template's own Zensical-built pages - admonitions, content tabs, diagrams, and more.