Markdown

Markdown is a class of languages meant to make writing HTML text documents easier. Unfortunately, there are several different versions, and not all of them have specifications. We'll only touch on some of the features here.

To show it working, this chapter was actually produced using the ixml below on a Marked-down version of the chapter.

Structure

Since Markdown is just a representation of an HTML document, the top level is:

 html: head, body.

We can add anything we like to the head using insertions:

 head: meta, title.
 meta: name, content.
 @name: +"generator".
 @content: +"ixml".
 title: +"Markdown".

This will cause every serialised result to start

 <html>
   <head>
      <meta name='generator' content='ixml'/>
      <title>Markdown</title>
   </head>
   <body>

For the time being, let's keep the body simple: headings and paragraphs separated by blank lines:

 body: part++(-#a+).
 -part: heading; para.
 -heading: h1; h2; h3; h4; h5; h6.
 -para: p.

First the headings: these are line starting with a number of # characters, and optionally may end with them as well.

 h1: -"# " , htext, -"#"*, -#a.
 h2: -"## ", htext, -"#"*, -#a.
 h3: -"### ", htext, -"#"*, -#a.
 h4: -"#### ", htext, -"#"*, -#a.
 h5: -"##### ", htext, -"#"*, -#a.
 h6: -"###### ", htext, -"#"*, -#a.

Heading text is a series of heading characters. Hash characters are only allowed in the text if they are followed by a non-hash character:

 -htext: hc+.
 -hc: ~["#"; #a]; "#", ~["#"; #a].

Now paragraphs. They mustn't start with a hash, clearly, and consist of a number of lines of text:

 p: ~["#"], line++nl, -#a.
 -line: c+.
 -c: ~[#a].

We have separated out the separating nl, since it should be retained in the output, and not deleted.

 nl: #a.

Text Style

Text within a paragraph can be marked with an asterisk, an underscore, or a backtick to produce strong or emphasised or code. So we change the definition of the contents of line accordingly:

 -line: c+.
 -c: ~[#a; "*_`"]; em; strong; code.
 
 strong: -"**", cstar+ , -"**";
         -"__", cunder+ , -"__".
 
 em: -"*", ~["*"], cstar+, ~["*"], -"*";
     -"_", cunder+ , -"_".
 
 code: -"`", ccode+, -"`".
 
 -cstar: ~["*"; #a].
 -cunder: ~["_"; #a].
 -ccode: ~["`"; #a].

Finally, we will add one more type of paragraph, code blocks, which will be produced using the pre element in HTML, and start with a space in the input. So add the new type of paragraph:

 -para: p; pre.

Make sure that p paragraphs don't start with a space:

 p: ~["# "], line++nl, -#a.

and now define a pre paragraph similar to p paragraphs:

 pre: (" ", preline)++nl, -#a.
 -preline: ~[#a]*.

Exercise

Take the ixml code collected above, and add a horizontal rule element, that consists of a line starting with three or more hyphens. (Don't forget to make sure that p paragraphs consequently don't start with a hyphen).

Add a hypertext a element, of the form

 [text of the link](link)

for example

 [the ixml code collected above](../examples/markdown.ixml)

This can go anywhere in the body of a p paragraph.