Project 1: Markdown Compiler
In this project you’ll write a Python program that reads a Markdown file and compiles it into HTML.
Markdown is a much smaller language than HTML. You have already used GitHub-flavored Markdown in every README.md and GitHub issue, including the ones for your labs. Reddit comments and R Markdown reports use it too. Your program will do the same job on a smaller scale: read Markdown like # Header and **bold** and write out the matching <h1> and <b> tags. The compiler uses string slicing, the find method, and loops over characters from the readings on Python and strings.
A Financial Aside
Suppose an entry-level engineer takes a week to build GitHub’s Markdown compiler. Entry-level engineers at GitHub make around $148k a year, so the feature costs about $3000 in salary. GitHub has well over 100 million users, which puts the one-time development cost at a small fraction of a cent per user. After that week of development, the compiler can handle each new page automatically.
Due: Wednesday, October 7 at 11:59pm, see the schedule.
Start
Open the markdown-compiler starter repository, select Use this template, and create a repository named markdown-compiler under your account. Clone your copy and do all of your work inside it.
Learning Objectives
- understand the Markdown language
- understand string manipulation in Python
- understand how compilers translate from one programming language into another
Build the Compiler
The starter code splits the compiler into small functions with doctests, just like a lab. Solve it the way you solve a lab: make the doctests pass one function at a time instead of trying to write the whole compiler at once.
Step 1: make the tests pass. Your repository ships with three GitHub Actions, and right now they all fail. Fix the code in markdown_compiler/ until each one passes:
You do not need to edit the Actions themselves; they show exactly how your code is tested. The command_line test also requires the --add_css flag in markdown_compiler/__main__.py; a FIXME comment marks where to add it.
Step 2: generate and inspect a page. Once the tests pass, run your compiler on the example document, both without and with CSS:
$ markdown-compiler --input_file=example/README.md
$ markdown-compiler --input_file=example/README.md --add_cssEach command writes an HTML file next to the input, at example/README.html. The second command overwrites the first, so open the file in your browser after each run and inspect it. You do not submit screenshots: Gradescope runs the command on a new Markdown fixture and checks the generated HTML directly.
The
--add_cssflag adds two stylesheets to the generated page, so the same Markdown can produce pages with different designs.
Run these commands as you complete each function. A broken function is easier to spot in a half-rendered page than in a wall of doctest failures.
Grading Rubric
This project is worth 20 points. GitHub Actions provide quick public feedback while you work, but the score comes from instructor-owned pytest tests inside Gradescope:
The authoritative tests belong to the instructor, so changing a doctest or GitHub workflow cannot change your grade. Gradescope shows which behavior failed and you can fix, push, and resubmit. Its cases follow the starter’s doctests, including unchanged text with unmatched delimiters and preserved indentation inside fenced code blocks. The command-line check installs your submitted package and runs its markdown-compiler command without downloading dependencies. The style check uses the same command as the public workflow: flake8 markdown_compiler --ignore=E501.
Extra Credit
The compiler does not support Markdown lists. For example, the Markdown
1. this
2. is
3. a
4. listcurrently compiles to
1. this 2. is 3. a 4. listinstead of
<ol><li>this</li><li>is</li><li>a</li><li>list</li></ol>For 1 point of extra credit, so the maximum score is 21/20, add list support:
- Add 3 doctests to the
compile_linesfunction that contain Markdown lists. These should be good doctests that reasonably test that the list functionality works; come talk to us if you’d like feedback on whether yours are good ones. - Modify your code so that these doctests pass.
Submit
If you completed the list extra credit, add this file at the repository root:
# submission.toml
[features]
ordered_lists = trueThe extra-credit test runs only when that feature is claimed. It checks the generated list items and runs the three list doctests you added to compile_lines.
Commit and sync the required files. On Gradescope, choose GitHub and submit your markdown-compiler repository and the branch containing your commit.