Syllabus Lesson 203 of 239 · Projects: Build Real Things
Projects: Build Real Things

Project: Markdown -> HTML

Every note app, README, and chat box that renders Markdown is running a function much like the one you are about to write. You will build to_html(md): take a Markdown string and return an HTML string. This is a real parser, and the interesting part is blocks that span multiple lines: a run of bullet points becomes one list, and a run of text lines becomes one paragraph.

The trick that makes this clean is a buffer-and-flush loop. You walk the lines one at a time. Bullet lines pile into a list buffer; text lines pile into a paragraph buffer. When you hit a line that ends the current block (a blank line, a heading, or a different block type), you flush the buffer into a finished HTML block.

blocks, para, items = [], [], []
for line in md.split("\n"):
    s = line.strip()
    if s == "":
        flush_list(); flush_para()   # blank line ends any open block
    elif s.startswith("- "):
        items.append(s[2:])          # keep collecting bullets
    else:
        ...

The rules (escaped here so you can read the tags):

  • # text -> <h1>text</h1>
  • ## text -> <h2>text</h2>
  • consecutive - item lines -> one <ul><li>item</li>...</ul>
  • blank-line-separated runs of text -> one <p>...</p> each (join the lines with a space)
  • **bold** anywhere -> <strong>bold</strong>

Handle the inline bold with one regex: re.sub(r"\*\*(.+?)\*\*", r"<strong>\1</strong>", text) and apply it to every block's text. Join the finished blocks with no separator. Mind the edge cases the tests check: bold inside a heading, a list that directly follows a heading with no blank line, and stray blank lines at the start or end. Press Run to render a full document to HTML.

Your turn

Write to_html(md) that converts Markdown to an HTML string: # H1 and ## H2 headings, consecutive - item lines into a single <ul>, blank-line-separated text into <p> paragraphs (lines joined by a space), and **bold** into <strong>. Use a buffer-and-flush loop so multi-line blocks collapse correctly.

Spotted a problem in this lesson? Report it

Code · runs in your browser
Output