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:
| Rule | Consequence 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 spaces | a 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 backtick | otherwise an inline span such as x would open a fence by accident |
| An unclosed fence runs to the end of the document | there 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 <script> 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`bmust 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.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…