Step 1 of 5 · Reading · ~3 min
Read
Block Elements
Setext Headings
Markdown's older heading style underlines the text instead of prefixing it:
Release 2.1
===========
Known issues
------------
Same output as # Release 2.1 and ## Known issues. Only two levels exist —
= gives H1, - gives H2, and there is no setext H3. A parser has to support
both styles anyway, because a decade of real-world documents contains both.
How long does the underline have to be?
Any length. The spec says "a sequence of = characters or a sequence of -
characters" and imposes no minimum, so Release 2.1 followed by a single = is
a perfectly valid H1. Length is decoration, not syntax.
What the underline may not contain is internal whitespace. = = is not an
underline — that document is just a paragraph. Up to three spaces of indentation
before the underline is fine; four is too many and turns the line into indented
code.
Why is a row of dashes the hardest line in Markdown?
Because --- means three different things depending on what sits above it.
This is the first place in the course where a line cannot be classified on its own. The block scanner needs lookbehind — it has to know what the previous line turned out to be:
Note the asymmetry in rows two and four. A lone === with nothing above it is
not a break of any kind — it is literal text. A lone --- is a thematic break.
The characters are not interchangeable outside the underline role.
What counts as "text above"?
Only lines that would otherwise be a paragraph. A blockquote, a list item, an ATX heading or a code fence above the dashes does not get underlined:
| Above the dashes | Result |
|---|---|
✓ Release 2.1 | <h2>Release 2.1</h2> |
✗ > Release 2.1 | blockquote, then a separate <hr /> |
✗ - Release 2.1 | list item, then a separate <hr /> |
| ✗ nothing (blank) | <hr /> |
And the sharpest edge of all: the heading swallows every paragraph line
above it, not just one. Foo, then Bar, then --- is a single two-line H2 —
not a paragraph followed by a heading. If you want them separate, put a blank
line between them.
Your exercise
Convert setext headings, emit <hr /> for a bare row of dashes, and pass
everything else through untouched.
The mistake the grader catches is checking the dashes before checking what is
above them. If your loop tests "is this line a thematic break?" first, the
input para followed by --- emits <p>-less text and then <hr />, while
the test demands <h2>para</h2> on one line. The order of your branches is the
whole exercise: look ahead from the text line to the underline, and only fall
back to the thematic break when no paragraph line precedes it.
The second trap is forgetting to consume both lines. After emitting the heading
your index has to advance by two, or the underline reappears in the output as a
stray ===.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…