Proposal for adding a meta-data syntax to Markdown

This document describes a syntax for attaching meta-data to block-level elements (headers, paragraphs, code blocks,…), and to span-level elements (links, images,…).

Last updated January 2nd, 2007: integrated topics discussed in mailing list.

Table of contents:

1. Overview

This proposal describes two additions to the Markdown syntax:

  1. inline attribute lists (IAL)

    ## Header ##       {key=val .class #id ref_id}
  2. attribute lists definitions (ALD)

    {ref_id}: key=val .class #id

Every span-level or block-level element can be followed by an IAL:

### Header ###     {#header1 class=c1}

Paragraph *with emphasis*{class=c1}
second line of paragraph
{class=c1}

In this example, the three IALs refer to the header, the emphasis span, and the entire paragraph, respectively.

IALs can reference ALDs. The result of the following example is the same as the previous one:

### Header ###  {#header1 c1}

Paragraph *with emphasis*{c1}
second line of paragraph
{c1}

{c1}: class=c1

2. Attribute lists

This is an example attribute list, which shows everything you can put inside:

key1=val key2="long val" #myid .class1 .class2 ref1 ref2

More in particular, an attribute list is a whitespace-separated list of elements of 4 different kinds:

  1. key/value pairs (quoted if necessary)
  2. references to ALD (ref1,ref2)
  3. id specifiers (#myid)
  4. class specifiers (.myclass)

2.1. id and class are special

For ID and classes there are special shortcuts:

The following attribute lists are equivalent:

{#myid .class1 .class2} 
{id=myid class=class1 .class2}
{id=myid class="class1 class2"}
{id=myid class="will be overridden" class=class1 .class2}

3. Where to put inline attribute lists

3.1. For block-level elements

For paragraphs and other block-level elements, IAL go after the element:

This is a paragraph.
Line 2 of the paragraph.
{#myid .myclass}

A quote with a citation url:
> Who said that?
{cite=google.com}

Note: empty lines between the block and the IAL are not tollerated. So this is not legal:

This is a paragraph.
Line 2 of the paragraph.

{#myid .myclass}

Attribute lists may be indented up to 3 spaces:

Paragraph1
¬{ok}

Paragraph2
¬¬{ok}

Paragraph2
¬¬¬{ok}

3.2. For headers

For headers, you can put attribute lists on the same line:

### Header ###     {#myid}

Header     {#myid .myclass}
------

or, as like other block-level elements, on the line below:

### Header ###     
{#myid}

Header     
------
{#myid .myclass}

3.3. For span-level elements

For span-level elements, meta-data goes immediately after in the flow.

For example, in this:

This is a *chunky paragraph*{#id1}
{#id2}

the ID of the em element is set to id1 and the ID of the paragraph is set to id2.

This works also for links, like this:

This is [a link][ref]{#myid rel=abc rev=abc}

For images, this:

This is ![Alt text](url "fresh carrots")

is equivalent to:

This is ![Alt text](url){title="fresh carrots"}

4. Using attributes lists definition

In an attribute list, you can have:

  1. key=value pairs,
  2. id attributes (#myid)
  3. class attributes (.myclass)

Everything else is interpreted as a reference to an ALD.

# Header #      {ref}

Blah blah blah.

{ref}: #myhead .myclass lang=fr

Of course, more than one IAL can reference the same ALD:

# Header 1 #      {1}
...
# Header 2 #      {1}

{1}: .myclass lang=fr

5. The rules

5.1. The issue of escaping

  1. No escaping in code blocks.

  2. Everywhere else, all characters can be escaped:

  3. Quotes must be escaped inside quoted values:

  4. There is an exception for backward compatibility:

    [text](url "title"with"quotes")

5.2. Syntax for attribute lists

Consider the following attribute list:

{key=value ref key2="quoted value" }

In this string, key, value, and ref can be substituted by any string that does not contain whitespace, or the unescaped characters },=,',".

Inside a quoted value, you may use },= unescaped but you must escape the other kind of quote.

6. Things to discuss

In this example:

7. Design rationale


Created by Maruku at 23:18 on Monday, January 08th, 2007.