Notes On Markdown Markup Language

Abstract: Brief reference notes and comments on Markdown markup language.

References

Introduction

Markdown and RestructuredText are the 2 most popular markup languages. These are very handy for casual notes taking and then later auto convert them to HTML format for better consumption for viewing or use with presentations. You don't have to directly code with ugly html tags and be very productive in taking notes using your favourite text editor.

Markdown is simple-to-use markup language widely preferred for generating simple documents like HTML page. However, by default, it is not as powerful as RST. There are extensions to Markdown which makes Markdown as powerful as RST while being simpler to use. Markdown implementations tend to differ quite a bit, so be careful.

Python comes with Markdown module with a set of extra Markdown extensions. These are the extensions which implement additional features on top of John Gruber's Markdown core specification.

I primarily use Python Markdown module with it's extensions though there are many implementations available in different languages. This document uses the python implementation as a reference implementation for the purpose of illustration.

Installing Python Markdown

    On ubuntu, you can just install python-markdown and python-pygments packages.
    If you use virtualenv, you can install these on your sandbox using pip:
    $ pip install markdown pygments      # pygments for code highlighting

    On ubuntu 12.04 installation, you get following extensions:

    $ cd  /usr/lib/python2.7/dist-packages/markdown/extensions
    $ ls  *.py

    abbr.py        def_list.py     footnotes.py  rss.py   toc.py
    attr_list.py   extra.py        headerid.py   meta.py  smart_strong.py
    codehilite.py  fenced_code.py  html_tidy.py  nl2br.py tables.py  wikilinks.py

    The *extra* extension is a pseudo extension which stands for collection
    of the following extensions = 
               ['smart_strong', 'fenced_code', 'footnotes', 'attr_list', 
                'def_list',     'tables',      'abbr' ]

    You get the following command line utility which is a wrapper for python markdown:
            /usr/bin/markdown_py

Using Python Markdown Commandline

You can use Markdown command line using any of the examples below::

    $ python -m markdown  input.md > output.html
    $ python -m markdown  -x extra  input.md > output.html
    $ python -m markdown  -x extra -x codehilite input_file.md > outfile.html

    $ markdown_py input_file.md
    $ markdown_py -x extra -x codehilite input_file.md > outfile.html
    $ markdown_py -x extra -x toc input_file.md > outfile.html

Basic Syntax

Code Blocks

First thing you should know is how to escape from default markup rules. The answer is to indent anything with 4 or more spaces. You can have HTML code and Markdown markup code: all will be displayed verbatim in your HTML page. i.e. All html angle brackets will be encoded for you automatically.

There is also another method to define code blocks without indenting: Just enclose them with ~~~~ lines. This is called Fenced Code Blocks -- we will look at it later.

Section Headers

You prefix with hashes (#) to define section headers::

# Header 1 #                 (Works with markdown. Not with RST)
## Header 2 ##               (Trailing hashes are optional)
### Header 3 ###
#### Header 4 ####
##### Header 5 with no trailing hashes also OK

Bullet Lists

* First bullet 
* Second bullet
* Third bullet (you can mismatch *, +, etc)

<!-- Use empty comment or fenced-code-block to force transition here -->

5. any number
8. For numeric list
4. This will be 3rd bullet number

Rendered like below:

  1. any number
  2. For numeric list
  3. This will be 3rd bullet number

Paragraph

Paragraph is text surrounded by whitespace. Paragraphs can be on one line or can span many lines.

Markdown link is very simple. Some examples::

    [link text here](link.address.here)
    [link text here](link.address.here "Optional Title")
    [Google](http://google.com)      
    <http://stackoverflow.com/>                # Link shows up verbatim

Rendered as

link text here
link text here
Google
http://stackoverflow.com/ # Link shows up verbatim

Inline Markups

Examples::

This is _italics_, *emphasised*, **bold**, __strong__, and `code()`.

Rendered as below:

This is italics, emphasised, bold, strong, and code().

Inline Image

Example::

![picture alt desc](/img/mouse.svg "Optional Title")

Original Source: http://www.clker.com/clipart-1831.html

Rendered as:

picture alt desc

Block Quotes

Blockquotes are like quoted text in email replies and, they can be nested:

> Block quote level 1      # Generates <blockquote> ... </blockquote>
>> Block quote level 2     #

Block quote level 1

Block quote level 2

Custom CSS class/id attribute

The attribute list extension of python markdown module supports adding custom classes or id attribute. It is part of Markdown Plus syntax (not core) ::

##### Example Title1 {#myid .myclass}
[ Click here to go to  Title1](#myid)
Example Title1

Click here to go to Title1

If you want to customize a <div> block of elements with your own CSS class, do the following. The core markdown specification allows inline HTML but does not process markup inside inline html. However with the extra extension of python markdown, it is possible to do so. Note the markdown=1 attribute of the div block below. This enables processing of markdown syntax inside the html block.

<div class="custom-class" markdown="1">
This *word* is italicised. This **word** is bold.
</div>

This is rendered as below:

This word is italicised. This word is bold.

Fenced Code Blocks

Fenced Code Blocks implemented using original specification from PHP Markdown Extra.

Fenced code blocks have some advantages over indented code blocks:

Example:

~~~~{.python}
// This is fenced code block
while True:
   enjoy_life()
~~~~

which is rendered as:

// This is fenced code block
while True:
    enjoy_life()

Code highlighting

For syntax highlighting of code, you need to give hint about the code. It is taken from the first line of the code in any one of these forms as the first line in the code:

#!/usr/bin/python 
!python

Markdown generates line numbers and css class attributes for syntax highlighting.

    #!/usr/bin/python
    complete = False
    while not complete:
        process_event()

For more information about colorizing your code, see this blog markdown-pygments-django

Codehilite Highlighting Issues

The Code Blocks (aka Literal Blocks) are either indented or fenced (using ~~~~). It is used to escape all markups. You can freely use html and markdown markups and they will be properly escaped to display content verbatim.

The Codehilite extension attempts to highlight all codeblocks trying to guess the language used. e.g. python or java, etc. If the guess fails, it is treated as text and no highlighting will happen. Sometimes, the guess can be wrong and it may colorize verbatim text content in undesirable ways. Note that in any case, the html tags such as < and > are properly escaped irrespective of whether codehilite enabled or not.

To protect the literal text block from wrong highlighting, just specify :::text as the first line. The codehilite will remove this line and won't try to highlight inappropriately. The :::python prefix would be the hint to treat the content as python code.

If you have not enabled codehilite extension, don't specify this prefix since it would appear on the output.

~~~~~
:::text

You can have literal block.
  indented or un-indented.
    It is included *verbatim* as the **original**
        <b>html tags properly escaped </b>  
~~~~~

Rendered as

You can have literal block.
   indented or un-indented.
     It is included *verbatim* as the **original**
        It is included *verbatim* as the **original**
            <b>html tags properly escaped </b>

Hard Line Breaking

If you do not want to use monospaced code blocks but want to force new lines, you can just leave 2 spaces at the end of the line to do so:

This line is broken
into small lines
with 2 trailing spaces

Horizontal rules

Some ways of inserting horizontal line ::

* * * *
****
--------------------------

Result Line


Markdown plus tables

Syntax for table (Not available in basic markdown, but available through extensions)::

    | HdrC1  | HdrC2  | HdrC3  |
    |--------|--------|--------|
    |  R1C1  |  R1C2  |   R1C3 |
    |  R2C1  |  R2C2  |   R2C3 |

Rendered as:

HdrC1 HdrC2 HdrC3
R1C1 R1C2 R1C3
R2C1 R2C2 R2C3

Markdown plus definition lists

Definition lists are essentially 2 columns table and are useful to display things like SQL query results.

It is a list of (term, definition) tuples. A term can have multiple defintions. Multiple terms (synonyms) can have single definition::

    Animal
    : Land Animals
    : Water Animals
    : Amphibians

    Camel
    Giraffe
    Elephant
    : Herbivore

Rendered as below:

Animal
Land Animals
Water Animals
Amphibians
Camel
Giraffe
Elephant
Herbivore

Markdown Abbreviation Tag

Abbreviation tag produces <abbr> tag for abbreviations. On hovering the term browser displays the title.

Example Source::

The HTML and W3C are couple of abbreviations.
*[HTML]: Hyper Text Markup Language
*[W3C]: World Wide Web Consortium

Rendered as::

The HTML and W3C are couple of abbreviations.

Source Document

This document has been written using Markdown markup language and converted to HTML using markdown_py command using Macbook Pro running Ubuntu 12.04 release. See the source

Comments