Skip to content

02

Markdown Syntax

GFM works as you'd expect. A few things are added on top, and a few are missing.

The world has plenty of markdown manuals already.

So this chapter is mostly about the places where MilkMind behaves differently from everyone else.

(The basics are all here too. Skip the parts you know.)

There is only one screen.

MilkMind has no separate edit view and preview view. There’s one.

There’s exactly one rule.

The line your cursor is on shows the source. Every line it has left shows the result.

Type # Heading and the # disappears and it becomes a heading. Click that line again and the # comes back.

It’s like the hood of a car. Closed while you drive, open while you fix something. Nobody drives around with the hood up.

Everything else follows from that rule.

Tables and code fences render as whole blocks, and clicking inside one brings the source back. Bullet markers (- · * · +) all display as • bullets.

Numbered lists (1.) keep their numbers visible, though.

Why leave the numbers?

Because the number is itself information. That one’s on purpose.

The basics are the same as everywhere else.

I’ll go quickly here.

Headings

# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6

Ctrl+1 through Ctrl+6 set the level, and Ctrl+0 turns it back into body text.

Setext headings (the underline kind) don’t get styled, though. Use #.

Heading             ← won't look like a heading
=====

Emphasis

Bold is **bold** or __bold__, and the shortcut is Ctrl+B. Italic is *italic* or _italic_, Ctrl+I.

Strikethrough ~~like this~~ and inline code `code` have no shortcuts. Use the Format menu, or just type them.

Lists

- bullet
- second
    - nested

1. numbered
2. second

Tab moves an item one level in, Shift+Tab one level out. Child items come along with it. You don’t have to move them one at a time.

Indent width is Settings ▸ Appearance ▸ List indent, from 2 to 8 spaces.

Quotes, code blocks, dividers

> This is a quote.

```
code block
```

---

Code blocks have no syntax highlighting. They get a monospace font and a background, and that’s it.

(No colors. Better you hear it now.)

There are six kinds of checkbox.

- [ ] is a task, and shows as an empty circle. - [x] is done, and gets a check mark.

That much is standard everywhere.

MilkMind adds four more.

- [/] is in progress — the circle fills halfway. - [-] is cancelled — a line goes through it. - [?] is under review — a ? goes in. - [!] is important — a ! goes in.

If a checkbox isn’t working, it’s one of three things

It has to be a list item. Start the line with -, *, or +.

There has to be a space after the ]. - [x]done is not a checkbox. This is the one that catches everybody.

The extended states have to be typed by hand. No menu, no shortcut. Type them.

Clicking a checkbox destroys the extended state

This one deserves its own heading.

Clicking a checkbox with the mouse only toggles between [x] and [ ]. Click a [/] to check it and you get [x] — the original state is gone.

It’s the light switch on your wall. However fancy a dimmer you wire up behind it, the switch itself only goes up or down.

If you want to keep a [/], edit it with the keyboard.

Celebration effects

Every time you check something off, confetti pops. And when you finish the last task in the document, fireworks go off across the whole screen.

You can also turn on ripples and a screen shake. → Settings ▸ Checkboxes

People get confused about when the fireworks fire, but the rule is simple.

Done and cancelled both count as finished. If even one task, in-progress, under-review, or important item is left, you don’t get them yet.

(Cancelled counts as finished. Deciding not to do something is also a decision.)

The header row decides the table.

| Name | Role | Field |
|---|:---:|---:|
| Ada | Engineer | Compilers |
| Alan | Researcher | Computation |

Alignment comes from colons in the divider row. :--- is left, :---: is center, ---: is right.

Markdown works inside cells. Bold, code, links, images — they all go in.

To use a literal pipe, escape it as \|.

And remember one thing.

The header row decides the column count.

It’s an egg carton. Three slots means three eggs. Extra cells in a body row get cut off; missing ones stay blank.

Insert the skeleton with the Text ▸ Table menu. For a table with a lot of data, the CSV block below is much easier.

[link text](https://example.com)

Ctrl+K inserts one, and Ctrl+click opens it.

A plain click just moves the cursor.

Feels inconvenient?

This is an editor, not a web page. Clicking to fix the text comes first. Opening comes second.

[Google](https://google.com) and other web addresses open in your browser.

[another note](other.md) opens in MilkMind itself. That covers three extensions: .md, .markdown, and .txt. If Window open mode is set to “new window”, it opens in a new one.

Anything else, like [sheet](data.xlsx), gets handed to the OS default program.

[down here](#tasks) scrolls to that heading inside the document.

Moving around inside a document

An anchor is the heading lowercased with spaces joined by -. Non-English headings work too.

[to the properties section](#properties-dont-show-up-in-the-body)

Absolute paths, relative paths, and UNC paths all work. Paths with spaces work.

[document](C:\Users\me\notes\file.md)
[relative path](sub/notes.md)
[path with spaces](C:\Program Files (x86)\App\readme.md)

Relative paths only work after the document has been saved, though.

The reference point is the folder the document lives in. You’ve written “two doors down from here” — and “here” hasn’t been decided yet.

Deep links accept five schemes only. Other custom schemes won’t open.

[Obsidian](obsidian://open?vault=MyVault&file=Note)
[VS Code](vscode://file/C:/proj/main.ts)
[Notion](notion://...)   [Zotero](zotero://...)   [Logseq](logseq://...)

Right-click a local file link and you get Windows Explorer’s real context menu.

(Not an imitation of it. That menu.)

Bare URLs aren’t clickable

People ask about this a lot.

https://example.com          ← looks blue, but Ctrl+click does nothing
[link](https://example.com)  ← write it like this

It’s colored blue, so it looks like it should work, and it doesn’t. A doorknob painted on a wall.

<https://example.com> behaves the same way.

Images can carry a size.

![description](image.png)
![description](https://example.com/pic.png)
![description](C:\photos\pic.png)

Put a | after the alt text and add numbers to set the size. The unit is pixels. It won’t take % or em.

![|300](pic.png)            300px wide
![|300x200](pic.png)        300 wide, 200 tall
![description|300](pic.png)  keeps the alt, 300 wide
![300](pic.png)             numbers only = size (no alt)

Pasting images

Paste an image from the clipboard with Ctrl+V and it gets saved as a file, with the link written in for you.

Where it lands is Settings ▸ Files ▸ Image save location. The default is assets. The filename comes out as image-<time>-<random>.png.

It accepts PNG, JPEG, GIF, WebP, BMP, and SVG.

Save the document first. Before you do, you’ll get a dialog instead — MilkMind doesn’t know where to put the image yet.

Image paths can’t contain spaces

Links tolerate spaces. Images don’t.

![](my photo.png)      ← won't display
![](my%20photo.png)    ← encode it
![](my_photo.png)      ← or rename the file

Only three code fences are special.

csv, mermaid, and mindmap.

Those three render as a picture or a table. Any other language tag is just a code block.

Click inside any of the three and the source comes back up. Same hood rule.

CSV — paste it straight from Excel

```csv
Name,Role,Field
Ada,Engineer,Compilers
Alan,Researcher,Computation
```

You don’t have to wrap a block copied out of Excel in pipes by hand. Paste it, tag it csv, done.

It exports as a table to HTML, PDF, and DOCX too.

The first row is the header. Wrap a value in double quotes to put commas and line breaks inside a cell ("Last, First"). Comma is the only separator.

Markdown doesn’t render inside CSV cells, though. If you need bold or a link, use a regular table.

Mermaid — diagrams

```mermaid
graph TD
  A[idea] --> B[outline]
  B --> C[mind map]
  C --> D[document]
```

Flowcharts, sequence diagrams, Gantt charts — Mermaid syntax broadly works.

Bad syntax puts an error message in that spot. Exports carry it along as a picture.

Mindmap — a small map inside the document

```mindmap
# Project
## Phase 1
- research
- design
## Phase 2
- build
```

This embeds a static mind map picture inside the document.

You can name a layout, too.

```mindmap fishbone
# Cause analysis
...
```

Pick from left, right, side, down, and fishbone. Leave it out and it follows the document’s current layout.

Two things to know.

It’s read-only. You can’t drag the picture around to edit it — you edit the code.

It doesn’t export as a picture. In HTML, PDF, and DOCX it stays a code block. That’s where it parts ways with CSV and Mermaid.

YouTube — plays right there

Use image syntax on a YouTube address and you get an embedded player.

![](https://www.youtube.com/watch?v=VIDEO_ID)
![](https://youtu.be/VIDEO_ID)
![](https://www.youtube.com/shorts/VIDEO_ID)
![](https://www.youtube.com/embed/VIDEO_ID)

It has to be ![](...) image syntax. Write [title](youtube address) and it’s just a link. One exclamation mark apart.

Sizes work here too — ![|800](https://youtu.be/VIDEO_ID) (the default is 560×315).

In mind map nodes it shows up as a clickable thumbnail. It isn’t included in exports.

Footnotes only live inside the editor.

There's a source for this[^1] and another one[^note].

[^1]: The first footnote.
[^note]: You can name them.

References show as superscript, and hovering one brings the content up in a tooltip. Miss a definition and it tells you: “undefined: [^1]”.

There are three limits.

A definition starts at the beginning of a line, and is one line only. You can’t continue it across several.

Define the same name twice and the last one wins.

Footnotes are editor-only. They don’t reach the mind map, HTML copy, or exports.

Markdown doesn’t render inside the tooltip either.

(Footnotes can’t leave the editor yet. That’s where it stands today.)

Properties don’t show up in the body.

It’s the YAML block at the top of the document.

---
title: My note
tags: [ideas, draft]
---

You won’t see it in the editing area, though. You open the Properties panel above the editor to change it.

That’s deliberate.

Think of the label sewn inside a shirt. The wash instructions are genuinely useful information — but printed across the chest, it isn’t a shirt anymore.

While you’re writing, it belongs out of sight.

Frontmatter also has to be at the very start of the file. One blank line above it and it won’t be recognized.

MilkMind only reads three keys

mindmap-plugin, mindmap_type, and banner.

Everything else (title, tags, and so on) is preserved untouched. If you have keys you’ve been using, they stay.

mindmap-plugin

mindmap-plugin: basic

With this key present, the document opens as a mind map. It beats the startup-view setting.

It’s a marker compatible with the Obsidian markmind plugin. View a document as a map and save, and MilkMind writes this line in for you.

mindmap_type

mindmap_type: fishbone

This pins the layout for this document only. Values are left, right, side, down, and fishbone.

The document’s setting beats the global default. Change the default layout in settings and this file still won’t budge.

Hit the layout switch button in the map view and MilkMind writes this line automatically.

mindmap-type (with a hyphen) is also read. It’s written with an underscore.

banner: assets/hero.png
banner: https://example.com/hero.png
banner: "![[assets/hero.png]]"

This puts a gradient banner image at the top of the editing view. It recognizes the wikilink form (![[...]]) too.

Turn it off with Settings ▸ Appearance ▸ Document banner.

Start with what isn’t here.

If you’re coming from another app, read this part first.

Things that simply don’t exist.

Wikilinks [[note]] aren’t supported. The only exception is inside a banner: value. Math ($x^2$, $$...$$) isn’t there either. No KaTeX, no MathJax. Highlight ==like this==, code syntax highlighting, and Ctrl+F find-in-document are all absent. Raw HTML written in the document doesn’t render, and gets stripped when you copy as HTML.

Things where the markers just stay put.

Callouts > [!NOTE] look like an ordinary quote. Emoji codes :smile: stay as literal text. A 😄 you typed yourself is fine. Superscript ^up^ and subscript ~down~ leave their markers visible. Setext headings don’t get styled. Use #.

Things already mentioned above.

Bare URLs aren’t clickable. Write them as [text](url). Spaces in image paths have to be encoded as %20.

Not a short list, is it?

Knowing what’s missing before you start beats digging around two hours later wondering why it won’t work.

Postscript. There was only ever one rule.

Thanks for making it this far.

It looks like a pile of syntax, but there’s nothing to memorize.

If you take one line out of this chapter, take this one.

The line with the cursor shows source. The line without it shows result.

Checkboxes, tables, CSV, Mermaid — all of it comes out of that one line. Press it and it opens; leave and it closes.

Come back and look the rest up when you need it. That’s what this document is for.

([?] and [!] have to be typed by hand. Type them three times and your fingers learn it before you do.)