Skip to content
mdbin
Documentation menu

docs/code-blocks

Code blocks

Wrap code in a fenced code block and mdbin highlights it automatically. Add a language after the opening fence to pick the grammar.

Writing a code block

Put three backticks, the language name, your code, then three backticks to close:

```js
export function greet(name) {
  return `Hello, ${name}!`;
}
```

That renders as:

export function greet(name) {
  return `Hello, ${name}!`;
}

The language is taken from the first word after the opening fence. If you leave it off — or use a name mdbin doesn't recognise — the block still renders, just without colouring:

no language here — plain, escaped text

Supported languages

Highlighting is powered by highlight.js (the common bundle), which covers the languages you'll reach for most often, including:

javascript, typescript, python, php, ruby, go, rust, java, c, cpp, csharp, bash, shell, json, yaml, sql, css, html / xml, markdown, and more.

Use the language's common name as the fence info string (e.g. ```python).

Code changes (diffs)

To show a change to some code, put a unified diff — the format git diff prints — in a ```diff block. Name the language after diff to highlight the code, and add title= for a filename bar:

```diff php title=app/Foo.php
@@ -176,7 +176,4 @@ private function collected()
     * label it as one
-    * The four clauses are
-    * comparison flipped
+    * The selection is
     *
```

On the published page that renders as a single-column change view: removed lines in red with a -, added lines in green with a +, and the old and new line numbers in two gutters.

  • You set the line numbers. Each hunk starts with a header, @@ -176,7 +176,4 @@: the old side starts at line 176 and the new side at line 176. Unchanged and removed lines count up the old side; unchanged and added lines count up the new side. The counts after the commas are shown as written but not checked, so a hand-written hunk doesn't have to get them right. Anything after the closing @@ is shown as the hunk's label.
  • Every line starts with a prefix: a space for an unchanged line, - for a removed one, + for an added one. A line starting with \ (such as \ No newline at end of file) is shown as a note.
  • Several hunks go one after another in the same block, each with its own @@ header.
  • Pasting git diff output works as-is — the diff --git, index, --- and +++ lines above the first hunk are skipped. Use one block per file.
  • The language is optional, and title= cannot contain spaces. Without a title= the bar reads "Untitled".
  • Diff / Old / New switches the block between the change and either side of it as plain code. Copy takes the code with the change applied — unchanged and added lines, without the +/- signs — or, on Old, the code as it was before. Separate hunks are copied with a blank line between them.
  • Each line is highlighted on its own, so a line from the middle of a multi-line comment or string may be coloured as code.
  • Without a valid @@ header, a diff block renders as ordinary highlighted diff text, exactly as before. So does a block longer than 2,000 lines.
  • Indenting the whole block by one to three spaces strips that much from every line, which can turn it back into ordinary diff text — start the fence at the left margin.

The change view draws in the reader's browser: on the document page and in the editor's preview. The raw and .md views, link previews and these docs pages show the source.

Headings and anchors

Every heading gets a stable id and a hover anchor, so you can deep-link to any section. The id is derived from the heading text (lowercased, h- prefixed), and duplicates are de-duplicated within a document. Documents with several headings also get an automatic table of contents.

Links are auto-detected and safe by default:

  • Only http, https, mailto, relative, and # links are allowed — javascript: and other unsafe protocols are rejected.
  • Every link opens in a new tab and carries rel="nofollow noopener noreferrer".

What's sanitized

To keep shared documents safe to open:

  • Raw HTML is disabled in Markdown — it's the primary defence against cross-site scripting.
  • The rendered output is run through a sanitizer that strips dangerous tags and attributes (e.g. style, form, input, inline event handlers) — the one exception is the layout styles KaTeX itself generates for typeset math, kept only inside a formula.

You never have to think about this — just write Markdown and it stays safe.