Markdown Cheat Sheet

This is a quick reference guide for Markdown syntax, both as a refresher for myself, and test page for styling. Heck, testing rendering is only reason why there are those over-verbose explanations, instead of leaving the page as simple list of syntax examples.

I’ve also added few custom extensions, that are also explained here. Maybe I’ll put them in some package at some point if they are useful enough.

Polish pangrams for font support check

Pójdź, kińże tę chmurność w głąb flaszy!

Pójdź, kińże tę chmurność w głąb flaszy!
Jan Gwalbert Henryk Pawlikowski, 1936

Dość błazeństw, żrą mój pęk luźnych fig

Dość błazeństw, żrą mój pęk luźnych fig
— L. Jakubowicz, 1936

Headings <- this one is h2

To create a heading, add one to six # symbols before your heading text. The number of # you use will determine the hierarchy level and typeface size of the heading.

# H1
## H2
### H3
#### H4

This is an H3 header

This is an H4 header - last one styled

Inline text formatting

Lots of options for styling inline text. Heck, I’ll probably wont even use all of these, but here they are for reference:

SyntaxResult
**bold**bold
*italic*italic
***bold and italic***bold and italic
~strikethrough~strikethrough
`inline code`inline code
<sub>sub</sub>scriptsubscript
<sup>super</sup>scriptsuperscript
<ins>inserted text</ins>inserted text
<mark>highlighted text</mark>highlighted text

The simplest one - just directly use url, like https://ajur.pl/ or www.ajur.pl - this will become clickable links, if they start with http or www.

To create a linked text, use the following syntax: [link text](URL). Like link to my home page.

[My home page](https://ajur.pl/)

Section links (To headings) work as well, just use # followed by the heading text in lowercase, with spaces replaced by hyphens. For example link to go to top:

[go to top](#markdown-cheat-sheet)

Relative links work as well, just remember to use relative/absolute url path, not content file path. For example: relative link to links page, and absolute linkt to first article:

[links page](../links/)
[First Article](/articles/first-article/)

Links url can also be added as reference, which is useful for long urls or when you want to reuse the same url multiple times. You can define a reference link like this: [reference name]: URL, and then use it in your text like this: [link text][reference name]. For example: Or even shorter [ref-name][] if reference name is the same as link text:

Either [Google browser][Google]
Or this [Google][]
Will link to the same place.

[Google]: https://www.google.com
Todo

Sometime in the future I might add Obsidian styled wiki links, as I like their simplicity, so I’m dorpping here to Alex’s blog post about doing exactly that.

Footnotes

Footnotes syntax is similar to reference links, but with a caret ^ instead of square brackets. You can define a footnote like this: [^1]: Footnote content, and then reference it in your text like this: [^1]. For example:

This is some text with a footnote reference.[^1]
[^1]: This is the content of the footnote.

Rendered footnote1 will appear as a superscript number, and the content will be displayed at the bottom of the page.

Lists

List are simple, and we can mix and match all styles. Only pain is nesting ordered lists, as they require non-default indentation.

Unordered list

Ordered list

  1. ordered item 1
  2. just put number and dot, it will auto-increment
    1. you dont even have to place proper numbers, it will fix them for you
  3. nesting is bit trickier
    1. you need to indent at least to line up with the first character previous item
      1. if using obysdian, it will auto-indent with 4 spaces
      2. this is bit tricky if when i have 2 spaces indent in vscode

Checklist

Easier to explain with code:

- [x] completed item
- [ ] incomplete item
    - [ ] subitem of incomplete item

Block elements

Blockquotes

To create a blockquote, add a > in front of a paragraph. You can also nest blockquotes by adding additional > symbols.

This is a blockquote. It can span multiple lines and paragraphs.

This is a nested blockquote.

> This is a blockquote.
> It can span multiple lines and paragraphs.
>
> > This is a nested blockquote.

Alerts / Callouts / Admonitions

I’ve found plugin for adding callouts, yay!. It has multiple types, includes icons, titles and can be collapsable. Here are examples of some types:

Note

Useful information that users should know, even when skimming content.

Tip

There are a lot more types, just check plugin source code.

Info

Key information users need to know to achieve their goal.

Collapsable abstract/tldr with custom title

Might to know information that users can skip if they want.

> [!note]
> Useful information that users should know.

> [!note]- Collapsable note with custom title
> Might to know information that users can skip.

Code blocks

To create a code block, wrap your code in triple backticks (```) and optionally specify the language for syntax highlighting. Use more backticks if your code contains triple backticks.

Note that usual markdown syntax of indentation won’t work, as Astro uses GHF for rendering.

```javascript
function greet(name) {
  return Math.PI; // 3.14...
}
```

Astro uses Shiki for syntax highlighting, which supports a wide range of languages and themes.

I’ve also added custom plugin to shiki, witch allows passing in css class to code blocks. Thats usefull for adding utility classes. Most notably:

To add them, just add class (with dot) after language name:

```javascript .full-bleed
// code here will be full bleed
```
more code examples, including bleed examples

Python:

def greet(name):
    return "Hello, " + name + "!"

HTML with .soft-bleed:

<div class="container"><p>Some faily <em>loooooong</em> line</p></div>
<div class="container"><p>Another one, bit shorter</p></div>
<div class="container"><p>Short</p></div>

Typescript with .full-bleed:

class ThemeSwitcher extends HTMLElement {
   #storageKey = "theme-preference";
   #symbols: Record<string, string> = {
     auto: "",
     light: "☀︎",
     dark: "",
   };

   button: HTMLButtonElement;
   currentTheme: string;
   
   constructor() {
     super();
     this.button = this.querySelector("button")!;
     this.currentTheme = localStorage.getItem(this.#storageKey) ?? "auto";
     this.updateButton();
     this.button.addEventListener("click", () => this.toggleTheme());
   }

   updateButton() {
     this.button.textContent = this.#symbols[this.currentTheme] || "";
   }

   toggleTheme() {
     const themes = ["auto", "light", "dark"];
     const currentIndex = themes.indexOf(this.currentTheme);
     const nextIndex = (currentIndex + 1) % themes.length;
     this.setTheme(themes[nextIndex]!);
   }

   setTheme(theme: string) {
     this.currentTheme = theme;
     localStorage.setItem(this.#storageKey, theme);
     this.updateButton();
     if (theme === "auto") {
       const darkQuery = window.matchMedia("(prefers-color-scheme: dark)");
       theme = darkQuery.matches ? "dark" : "light";
     }
     document.documentElement.setAttribute("data-theme", theme);
     window.dispatchEvent(new CustomEvent("themechanged", { detail: { theme } }));
   }
 }

 customElements.define("theme-switcher", ThemeSwitcher);

Images

Basic markdown syntax

Basic syntax for adding images is similar to links, but with an exclamation mark at the beginning: ![alt text](image URL). Local images paths are relative to current md file.

![Nature pic](https://static.photos/nature/320x180/115)
![Mountains](./img-local-to-content-mdx.webp)

Mountains

Astro <Image> component

Astro provides an <Image> and <Picture> components that offers advanced features like automatic optimization, lazy loading, and support for various image formats.

These components are available only in .astro or .mdx files, and not in regular markdown files.

To use it, you need to import the component, and image (unless its external or in public folder), than use Image component in your mdx:

import { Image } from 'astro:assets';
import test_img from './img-local-to-content-mdx.webp';

<Image src="{test_img}" alt="Mountains" width="100px" />
Mountains

It supports even more attributes, but also accepts any valid HTML attributes, so you can add custom classes, styles, data attributes, etc.

<Image src={test_img} alt="Mountains" layout='full-width' style="height: 10vh" />
Mountains
Tip

I’ve set some global defaults for images, in particular:

  • responsiveStyles: true to make images responsive by default.
  • layout: 'constrained' to make images scale down to fit their container
    • full-width will enlarge image to fit parent container.
    • other values are very specific, check css docs.
  • objectPosition: 'center' to make sure images cover their container without distortion and are centered. More options are for really specific use.
  • also, as objectPosition only defines position within container, I’ve added centering styles to all images by default.

Video

No special support for videos for now. Use HTML.

Todo

Custom video component for local, or even better, easier embedding of external videos (like from YouTube or Vimeo).

Audio

No special support for audio for now. Use HTML.

Todo

Custom audio component for local, or even better, easier embedding of external audio (like from Spotify or SoundCloud).

Tables

To create a table, use pipes | to separate columns and hyphens - to create the header row. You can also align text in columns using colons :.

| Syntax      | Description |
| ----------- | ----------- |
| Header      | Title       |
| Paragraph   | Text        |

| Left Aligned | Center Aligned | Right Aligned |
| :--- |:---:| ---:|
| Left         | Center         | Right         |
SyntaxDescription
HeaderTitle
ParagraphText
Bit longer textto see how it breaks
Left AlignedCenter AlignedRight Aligned
LeftCenterRight
Some extra long textto ensure that table is responsive and doesn’t break layouteven if it has to be scrollable

Footnotes

  1. This is the content of the footnote.