In this episode, we implement a minimal subset of Markdown in Elixir by chaining together regex replace functions into a processing pipeline. If you've ever written a static page on Github or a comment on Reddit, then you've used Markdown. Here's a quick overview in case you're not familiar with it.
Markdown is a terse, human-readable document format that is easily converted to HTML. Anything that appears between a pair of asterisks is *italicized*, while text between a pair of asterisks is **bolded**. A line starting with # creates an H1 tag while starting with ## creates an H2 tag, etc, etc. Markdown is pretty handy when you just want to write a document quickly.
The plan
-
Create a new module with a
to_html
function that converts Markdown to HTML by calling a pipeline of other functions -
Create an
italics
function that will take a text input and useRegex.replace
to globally replace*text*
with<em>text</em>
and return the new text. -
Create a similar
bold
function that will globally replace**text**
with<strong>text</strong>
-
Create a
p
function that wraps lines of text with<p>
tags - Create a test string that uses various features and lets us easily test our module as we add to it.
- Try writing an output.html file from a simple markdown file.
This module isn't that complex, but it's a great way to show off the power of Elixir's function pipelines! We'll go into a more standard way of doing unit tests once we start working with mix
in a few lessons.
Challenge 5
Add two more HTML tags to markdown—"big" and "small". Decide for yourself what the syntax should be to generate them.
(solution here)
3 Comments
I found that if p function put in first pipeline chain will cause error when test_str is poem, and italics, bold are used for end words.
Interesting. I haven't encountered that error. What's the full input string you're trying to convert?
I wonder why you catch on the empty lines in the regex instead of just that :
Regex.replace(~r/[\r\n|\n|\r|^]+([^\r\n]+)([\r\n|\n|\r]+$)?/, txt, "<p>\1</p>")