The Challenge

In this challenge, you are supposed to write a program or function that takes in a String, which will contain the simplified Markdown-like Markup, and outputs the corresponding HTML Markup.

The Input

You can take input in whatever way you wish to. The type of the input should be String.

The Output

You can output the result in any way you want. Logging to Console or Terminal, printing on screen, returning from function etc. are perfectly valid.

The Rules

  • Convert each occurrence of *foo* and _foo_ to <em>foo</em>.
  • Convert each occurrence of **foo** and __foo__ to <strong>foo</strong>.
  • Convert each occurrence of <tab or four spaces here>foo\n to <pre><code>foo</code></pre>.
  • Convert each occurrence of #foo\n to <h1>foo</h1>.
  • Convert each occurrence of ##bar\n to <h2>bar</h2>.
  • Convert each occurrence of ###bar\n to <h3>bar</h3>.
  • Convert each occurrence of ####bar\n to <h4>bar</h4>.
  • Convert each occurrence of #####bar\n to <h5>bar</h5>.
  • Convert each occurrence of ######bar\n to <h6>bar</h6>.
  • Convert each occurrence of [foo](https:\\www.bar.com) to <a href="https:\\www.bar.com">foo</a>.
  • Convert each occurrence of ![foo](https:\\www.bar.com) to <img src="https:\\www.bar.com" alt="foo"/>.
  • Convert each occurrence of >foo\n to <blockquote>foo</blockquote>.
  • Convert each occurrence of - foo\n as <li>foo</li> (add <ul> before the li if the - is the first of its consecutive series and add </ul> if it is the last.)
  • Convert each occurrence of n. foo\n (where the first n denotes an Integer such as 12,1729 etc.) as <li>foo</li> (add <ol> before the li if the element is the first of its consecutive series and add </ol> if it is the last.)
  • Although there exist many more rules of conversion, you are supposed to follow only the abovementioned ones (for the sake of simplicity).
  • You are supposed to output only the corresponding HTML Markup for the given String. No need to add extra elements that are necessary for creating a valid HTML file (like <body>, <html> etc.). However, if they are present in the input String, then you will have to output them too, that is, replace < and > with &lt; and &gt;, repspectively.
  • You must NOT use any built-in! (I doubt whether there exists one)

Note : In the abovementioned rules, foo, bar and https:\\www.bar.com are only placeholders. Your program or function must be flexible enough to work for Strings different than these too.


This is , so the shortest code in bytes wins!

Test Cases

"**Hello**" -> "<strong>Hello</strong>"

"#IsThisAwesome?\n" -> "<h1>IsThisAwesome?</h1>"

">![Image](http:\\www.somewhereontheinternet.com) -> "<blockquote><img src='https:\\www.somewhereontheintenet.com' alt='Image'/></blockquote>"

">Some Content\n- Item1\n- Item2\n- Item3\n" -> "<blockquote>Some Content</blockquote><ul><li>Item1</li><li>Item2</li><li>Item3</li></ul>"

"1.Hello\n2.Bye\n3.OK\n" -> "<ol><li>Hello</li><li>Bye</li><li>OK</li></ol>"

Special Thanks to FakeRainBrigand!

This challenge was originally proposed by @FakeRainBrigand in the Sandbox. He granted me the permission to post this challenge on the regular website. Due to unclear and broad specifications, the challenge was closed. Now, it has been reopened with clearer and fewer specs by @Arjun.

  • \$\begingroup\$ Good point. I removed that from the post. \$\endgroup\$ – Christopher Jan 30 '17 at 2:17
  • 1
    \$\begingroup\$ It would be nice to have a more rigorous specification for each rule. For instance I notice that your ordered list input are not numbers 1-3 while the result is. It would be nice to know exactly what is required. \$\endgroup\$ – Wheat Wizard Jan 30 '17 at 2:22
  • \$\begingroup\$ I didn't write this challenge but thanks for the feedback \$\endgroup\$ – Christopher Jan 30 '17 at 2:27
  • 7
    \$\begingroup\$ I vote to close as unclear what you're asking because there are at least 500 unexplained corner cases. Markdown is an incredibly tricky language that everyone has some idea of what it 'should look like', but a formal specification is quite long. This is nowhere near a complete specification. \$\endgroup\$ – orlp Jan 30 '17 at 7:52
  • 2
    \$\begingroup\$ R E T I N A. \$\endgroup\$ – Matthew Roh Mar 25 '17 at 2:18

PHP, 770 Bytes

Online Version

There are some rules to make html with this markup

the replacement of blockquote must before all others

h6,h5,h4,h3,h2,h1 is the next order

strong, em

img, a

and (li ,ul, li,ol) or (li ,ol, li,ul)

,'%- (.*)\n%Us'
,'%\d+\. (.*)\n%Us'
,'%(\t|    )(.*)\n%Us'
,'<img src="\2" alt="\1"/>'
,'<a href="\2">\1</a>'
echo preg_replace($s,$r,$i);
  • \$\begingroup\$ Good job! Testing right now \$\endgroup\$ – Christopher Mar 25 '17 at 15:11

Lua, 641 bytes

t={"<","&lt","^.+(>)","&gt","^(#+)(.*)",function(a,b)return("<h%d>%s</h%d>"):format(#a,b,#a)end,"^>(.*)","<blockquote>%1</blockquote>","^[\t ]+(.*)","<pre><code>%1</code>","!%[(.-)%]%((.-)%)",'<img src="%2" alt="%1"/>',"%[(.-)%]%((.-)%)",'<a href="%2">%1</a>',"%*%*","","__","","%b","<strong>%1</strong>","","","%b**","<em>%1</em>","%*","","%b__","<em>%1</em>","_",""}for l in io.lines()do u,U=l:match("^- ")or u and print("</ul>"),u o,O=l:match("^%d%. ")or o and print("</ol>"),o for i=1,#t,2 do l=l:gsub(t[i],t[i+1])end print((l:gsub("^- (.*)",(U and""or"<ul>").."<li>%1</li>"):gsub("^%d%. (.*)",(O and""or"<ol>").."<li>%1</li>")))end

Try it online!

Readable Version and Explanation

t = { -- Table used for simple replacements
    "<", "&lt",
    "^.+(>)", "&gt", -- Cannot be at the beginning of a line because of blockquotes
    "^(#+)(.*)", function(a,b)return("<h%d>%s</h%d>"):format(#a,b,#a)end, -- Combined h# replacement
    "^>(.*)", "<blockquote>%1</blockquote>",
    "^[\t ]+(.*)", "<pre><code>%1</code>",
    "!%[(.-)%]%((.-)%)", '<img src="%2" alt="%1"/>',
    "%[(.-)%]%((.-)%)", '<a href="%2">%1</a>',
    "%*%*", "", -- Using the actual control character is shorter than using an escape code
    "__", "",
    "%b", "<strong>%1</strong>",
    "", "",
    "%b**", "<em>%1</em>",
    "%*", "",
    "%b__", "<em>%1</em>",
    "_", ""

for l in io.lines() do -- For every line in STDIN
    u,U=l:match("^- ") or u and print("</ul>"),u -- Some compact logic to print the end of the lists and mark things as such
    o,O=l:match("^%d%. ") or o and print("</ol>"),o

    for i=1,#t,2 do
        l=l:gsub(t[i],t[i+1]) -- Run through the table of replacements

    print(( -- Use two parentheses so that we only print the first return value
        l:gsub("^- (.*)", (U and "" or "<ul>") .. "<li>%1</li>") -- Rest of the list logic
        :gsub("^%d%. (.*)", (O and "" or "<ol>") .. "<li>%1</li>")

I can expand upon specific things if wanted, but it's very late as-of posting this so it'll have to wait until later.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.