Why code gets its own formatting

Documentation for IT work is full of things a reader has to type or recognize exactly: commands, file paths, configuration keys, hostnames, error codes. Code formatting does three jobs for them. It shows the text in a monospace font, so characters such as l, 1 and I or O and 0 are easy to tell apart. It marks the text as literal: "type exactly this". And it switches Markdown off: an asterisk, underscore or backslash inside code stays what it is, instead of turning the next words italic.

Markdown has two forms: inline code for a word or command inside a sentence, and code blocks for whole lines.

Inline code

Inline code is text between backticks (`, on many keyboards the key left of the 1). The syntax itself, the code span, is explained with the other inline formatting; here is how to use it well.

Restart the service with `systemctl restart portal` on `web01`.
The settings are in `/etc/portal/portal.yaml`; set `max_sessions` to `500`.
On Windows, the log is `C:\Kestrel\Portal\logs\portal.log`.
<p>Restart the service with <code>systemctl restart portal</code> on <code>web01</code>.
The settings are in <code>/etc/portal/portal.yaml</code>; set <code>max_sessions</code> to <code>500</code>.
On Windows, the log is <code>C:\Kestrel\Portal\logs\portal.log</code>.</p>

The result is the HTML <code> element. Notice the underscore in max_sessions and the backslashes in the Windows path: inside backticks they need no escaping. That makes backticks the right tool for anything technical: a file name such as __init__.py without backticks would turn into bold text.

Good candidates for inline code:

  • commands, options and short snippets: git pull --rebase
  • file names and paths: README.md, /var/log/
  • configuration keys and values: timeout: 30
  • hostnames, ports and identifiers: db02:5432
  • exact error codes and messages: HTTP 503

Do not use it for emphasis or for product names ("Kubernetes" is a name, not code). Too much monospace makes a paragraph hard to read and hides the parts that really are literal.

Backticks inside inline code

To show a backtick inside inline code, surround the code with a longer run of backticks than it contains. When the code starts or ends with a backtick, add a space on both sides; the renderer removes one space at each end.

In PowerShell, `` ` `` continues a line. In Bash, `` echo `date` `` runs a command.
<p>In PowerShell, <code>`</code> continues a line. In Bash, <code>echo `date`</code> runs a command.</p>

Fenced code blocks

A fenced code block is a block of code between two fence lines. A code fence is a line of at least three backticks (```) or at least three tildes (~~~). Everything between the opening and the closing fence is shown exactly as typed: line breaks, indentation and special characters included.

If the portal does not come back, check its log:

```bash
systemctl status portal
journalctl -u portal --since "10 min ago"
```
<p>If the portal does not come back, check its log:</p>
<pre><code class="language-bash">systemctl status portal
journalctl -u portal --since &quot;10 min ago&quot;
</code></pre>

The renderer produces <pre><code>: <pre> keeps the line breaks and spacing, and <code> marks the content as code. The characters <, >, & and " are escaped, so a code block can safely show HTML or shell redirection.

A fenced code block. The opening fence of three backticks is followed by the info string bash. The code lines follow. A closing fence of three backticks ends the block. The renderer turns it into a pre element containing a code element with the class language-bash. ``` bash systemctl status portal journalctl -u portal ``` opening fence + info string content, shown as typed closing fence <pre><code class="language-bash">…</code></pre>
The parts of a fenced code block. The first word after the opening fence becomes the class of the code element.

A few rules decide where a fenced block ends:

  • The closing fence must use the same character as the opening fence and be at least as long. A ``` line inside a block opened with ```` is just content.
  • A fenced block may interrupt a paragraph: no blank line is needed before it. Adding one anyway makes the source easier to read and keeps stricter renderers happy.
  • A block that is never closed runs to the end of the document (or of the list item or quote it is in). Everything after it becomes code.
```bash
systemctl restart portal

## Verify

Check the **status page**.
<pre><code class="language-bash">systemctl restart portal

## Verify

Check the **status page**.</code></pre>

The info string and syntax highlighting

The info string is the text after the opening fence on the same line. By convention its first word is the name of the language: ```python, ```yaml, ```json. The CommonMark specification leaves the meaning to the renderer; markdown-it, like most renderers, turns the first word into a class on the <code> element (language-yaml).

Set the alert threshold in `monitoring.yaml`:

```yaml
alerts:
  portal_response_ms: 800
  notify: noc@example.com
```
<p>Set the alert threshold in <code>monitoring.yaml</code>:</p>
<pre><code class="language-yaml">alerts:
  portal_response_ms: 800
  notify: noc@example.com
</code></pre>

Syntax highlighting

Syntax highlighting is the coloring of code by its parts: keywords, strings, comments and numbers each get their own color or weight. It makes code easier to scan and makes some mistakes, such as an unclosed string, stand out. The Markdown renderer does not do this itself. It only records the language in the class name; a highlighter then reads that class and colors the code. On GitHub and GitLab this happens on the server. On a documentation site it is often a JavaScript library such as Prism or highlight.js. This encyclopedia uses Prism for Python, YAML, JSON and other languages; the Markdown examples on this page are shown without colors on purpose.

Language names differ a little per highlighter, but the common ones work everywhere: bash or shell, powershell, python, javascript, json, yaml, sql, html, css, diff. An unknown name does no harm: the code is simply shown without colors. Use text, or no info string, for log output and other plain text.

Showing a fence inside a code block

Documentation about Markdown, or a README that explains how to write a good issue, sometimes has to show a code block as an example. The inner fence would close the outer block too early. The fix is a longer outer fence, or a fence of the other character:

Paste the error in your ticket like this:

````markdown
```text
ERROR 1045 (28000): Access denied for user 'portal'@'web01'
```
````
<p>Paste the error in your ticket like this:</p>
<pre><code class="language-markdown">```text
ERROR 1045 (28000): Access denied for user 'portal'@'web01'
```
</code></pre>

The outer block opens with four backticks, so the three-backtick lines inside are ordinary content. A ~~~ fence around the example works the same way, because a backtick line can never close a tilde fence.

Indented code blocks

An indented code block is the original Markdown way to show code: every line indented by at least four spaces (or a tab), after a blank line. The renderer removes the four spaces and shows the rest as code.

To see who is logged in:

    who
    last -n 5
<p>To see who is logged in:</p>
<pre><code>who
last -n 5
</code></pre>

It still works everywhere, but it has drawbacks: there is no place for a language, so no syntax highlighting; an indented line directly under a paragraph is not code but part of the paragraph; and inside lists, the indentation that makes a block "code" is mixed up with the indentation that keeps it inside the list item. Prefer fenced blocks. The one case where you need to know the indented form is when Markdown surprises you: text that you indented for neatness suddenly appears as a code block.

Escalation contacts:

    Tomasz Nowak (NOC) for network outages
<p>Escalation contacts:</p>
<pre><code>Tomasz Nowak (NOC) for network outages
</code></pre>

Code blocks in lists

Runbooks are numbered steps with commands in between. To keep a code block inside a list item, indent the whole fenced block (fences included) to the start of the item's text: three spaces after 1., two after -.

1. Stop the portal:

   ```bash
   systemctl stop portal
   ```

2. Clear the session cache.
<ol>
<li>
<p>Stop the portal:</p>
<pre><code class="language-bash">systemctl stop portal
</code></pre>
</li>
<li>
<p>Clear the session cache.</p>
</li>
</ol>

Without the indentation, the code block ends the list. The next step then starts a new list, numbered from 2: it looks almost right in the browser, but the steps are no longer one list, and the command is no longer part of step 1.

1. Stop the portal:

```bash
systemctl stop portal
```

2. Clear the session cache.
<ol>
<li>Stop the portal:</li>
</ol>
<pre><code class="language-bash">systemctl stop portal
</code></pre>
<ol start="2">
<li>Clear the session cache.</li>
</ol>

The page on lists explains the indentation rules for list items in detail.

Commands readers can copy safely

Most code blocks in IT documentation are copied straight into a terminal, often at night during an incident. Write them for that moment:

  • No prompt characters. Leave out $, # or PS C:\> in blocks meant for copying. A pasted $ systemctl … fails, and a # turns the whole line into a comment.
  • Commands and output apart. Put the command in one block and the expected output in a second block (marked text), with a sentence in between. Readers then copy only what they should run.
  • Clear placeholders. Write values the reader must replace in capitals or angle brackets, and say so: ssh <your-username>@jump01.
  • No secrets. Never paste real passwords, tokens or keys into a code block, not even in a private repository. Point to where the secret is stored instead.
  • Straight quotes. Write and copy code from a code editor, not from a word processor or chat app that turns " into curly quotes. A command with curly quotes looks right and fails.
Check how full the log disk is:

```bash
df -h /var/log
```

The output looks like this; act when `Use%` is above 85%:

```text
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1        50G   44G  6.0G  89% /var/log
```
<p>Check how full the log disk is:</p>
<pre><code class="language-bash">df -h /var/log
</code></pre>
<p>The output looks like this; act when <code>Use%</code> is above 85%:</p>
<pre><code class="language-text">Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1        50G   44G  6.0G  89% /var/log
</code></pre>