Mini Markdown

January 21, 2020

Today’s exercise is an interview question. The situation is an interviewee at home, sharing his screen with an interviewer at his office. The interviewee has one hour to write the following program while the interviewer watches:

Write a program that takes a text file as input and writes an html file as output. The input consists of one or more paragraphs (maximal lines of text separated by blank lines). The following elements of John Gruber’s Markdown language are supported:

– ###### up to six levels of headings

– unordered lists introduce by a dash (like this paragraph)

– plain text paragraphs

Your task is to write a mini-Markdown processor; you have one hour to complete it. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

2 Responses to “Mini Markdown”

  1. Daniel said

    Here’s a solution in Python.

    @programmingpraxis, your solution seemingly does not add a closing for list items occurring as the last elements of the input text.

    import os
    import sys
    
    assert len(sys.argv) == 2
    
    with open(sys.argv[1]) as f:
        lines = [line for line in f.read().splitlines() if line]
    snippets = []
    for line in lines:
        if line.startswith('-'):
            if snippets and snippets[-1] == '  </ul>':
                snippets.pop()
            else:
                snippets.append('  <ul>')
            snippets.append('    <li>' + line[1:].strip() + '</li>')
            snippets.append('  </ul>')
        elif line.startswith('#'):
            # WARN: this approach emits <h7>, <h8>, etc.
            line_ = line.lstrip('#')
            level = len(line) - len(line_)
            snippets.append(f'  <h{level}>{line_.strip()}</h{level}>')
        else:
            snippets.append('  <p>' + line + '</p>')
    
    print('<html>' + os.linesep + '<body>')
    print(os.linesep.join(snippets))
    print('</body>' + os.linesep + '</html>')
    

    Example Usage:

    $ python3.7 markdown.py input.txt
    <html>
    <body>
      <p>This is a text paragraph.</p>
      <h1>Heading level 1</h1>
      <p>This is another text paragraph.</p>
      <ul>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
      </ul>
      <p>This is still another text paragraph.</p>
      <h3>Heading level 3</h3>
      <p>This is the last text paragraph.</p>
    </body>
    </html>
    
  2. Daniel said

    Here’s my same comment included above, this time with HTML escaping to try preventing dropped text.

    @programmingpraxis, your solution seemingly does not add a closing </ul> for list items occurring as the last elements of the input text.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: