Skip to content

Step 1 of 5 · Reading · ~3 min

Read

Lists & Code

Code Blocks

Code is the one construct a Markdown parser must be able to keep its hands off. Everything inside a code span or a code fence is literal: no emphasis, no links, no entity interpretation. Getting that isolation right is what lets people paste Markdown examples into Markdown documents at all. Your program will turn code spans and fenced blocks into <code> and <pre> and leave everything else on the line alone.

Fenced blocks: what exactly opens and closes one?

A fence is a line of at least three backticks or three tildes, indented by at most three spaces. Four rules do all the work, and each one has a failure mode:

RuleConsequence when you ignore it
The opener is 3+ backticks or 3+ tildes, never mixed~~~ cannot be closed by backticks
The closer uses the same character, is at least as long, and has nothing after it but spacesa 3-backtick line does not close a 4-backtick fence, so a fenced example of fences works
An info string after a backtick fence may not contain a backtickotherwise an inline span such as x would open a fence by accident
An unclosed fence runs to the end of the documentthere is no error and no backtracking

The first word of the info string is the language tag. It becomes class="language-NAME" on the <code> element, which is all a syntax highlighter needs. Anything after the first word is ignored.

~~~ruby extra words        <pre><code class="language-ruby">puts 1
puts 1                  -> </code></pre>
~~~

Three details are what the tests compare against. The content is HTML-escaped even though it is code (< and & and "). Every content line ends with a newline, so the text before </code> ends with one; an empty block has none. And if the opening fence is indented, up to that many spaces are removed from each content line, so an indented fence inside a list does not leak its indent into the code.

Inline code: how many backticks?

A code span opens with a run of N backticks and closes with the next run of exactly N. That is how you put a backtick inside code: surround it with two. If no run of N follows, the opening run is plain text.

source            output
`len()`           <code>len()</code>
``a`b``           <code>a`b</code>             (a single backtick inside is not a closer)
`` `x` ``         <code>`x`</code>             (one space stripped from each end)
`  x  `           <code> x </code>             (one space stripped, the rest stays)
`unclosed         `unclosed                    (no closing run: literal)

The space rule exists so you can write code that itself starts or ends with a backtick. It applies only when the content both begins and ends with a space and is not entirely spaces.

Inside a code span, nothing is interpreted, so `*not em*` is <code>*not em*</code>. The same holds for the <script> in `<script>`: it is escaped to &lt;script&gt; and shows up as text.

Indented code blocks

Four spaces of indentation also makes code, with two differences worth knowing: there is no language tag, and an indented block cannot interrupt a paragraph, so indented lines under prose are just continuation lines. Fenced blocks have neither restriction, which is why they won. This exercise does not implement indented blocks.

Common mistakes

  • Including the closing fence in the content. The closer is consumed, not output.
  • Closing on any run of backticks. a`b must not close at the single backtick.
  • Forgetting the final newline. A one-line block still ends with a newline before </code>.
  • Running span rules inside a fence. A fenced line is content even when it holds backticks.

Your exercise

Write code_spans (one line) and convert (the whole document). The starter gives you escape_html and the two fence-recognising functions. Lines that are not part of a fenced block are printed after code spans are converted, so blank lines stay where they were.

Up nextBlockquotes & HRLists & Code

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…