Mobiledoc is a simple post or article format that aims to be:
- Platform agnostic. Should be possible to render without an HTML parser.
- Efficient to transfer. Compresses well, and limits the duplication of content.
- Extensible at runtime. Stores content, not layout or final display.
Mobiledoc is primarily intended to be used for news-related content such as articles and blog posts. It is deliberately simple, and organizes its content in an array of "sections" that are considered as individual blocks of content.
There is no concept of layout or design built into Mobiledoc. It is up to the renderer to generate a display appropriate for its context. On mobile this may mean each section is full-width and they are displayed sequentially. On larger displays the sections may be rendered side-by-side. Mobiledoc makes no prescription for output display.
Often Mobiledoc will be used with one or more of:
- Mobiledoc Kit to author an editor
- Ember Mobiledoc Editor is one such editor
- Mobiledoc DOM Renderer
- Mobiledoc HTML Renderer
- Mobiledoc Text Renderer
Mobiledoc consists of a wrapping object, type definitions for markup, atoms and cards, and an array of section data. Using arrays makes Mobiledocs each to render quickly.
The wrapper signature:
{
version: "0.3.0", ──── Versioning information
markups: [ ──── Ordered list of markup types
markup,
markup
],
atoms: [ ──── Ordered list of atom types
atom,
atom
],
cards: [ ──── Ordered list of card types
card,
card
],
sections: [ ──── Ordered list of sections.
section,
section,
section
]
}
Markup definition signature
Markups have a tagName and an optional array of attributes. Not all markups can have attributes, but for those that do the attributes array is a single array of all the attribute names and values, one after another. E.g., ["a", ["href", "http://bustle.com", "target", "_blank"]
.
{
version: "0.3.0",
markups: [
[tagName, optionalAttributesArray], ──── Markup
["em"], ──── Example simple markup with no attributes
["a", ["href", "http://google.com", "target", "_blank"]], ──── Example markup with 2 attributes ("href" and "target")
]
}
Atom definition signature
Atoms have a name, text value and arbitrary payload.
{
version: "0.3.0",
atoms: [
[atomName, atomText, atomPayload], ──── Atom
['mention', '@bob', { id: 42 }] ──── Example 'mention' atom
]
}
Card definition signature
Cards have a name and arbitrary payload.
{
version: "0.3.0",
cards: [
[cardName, cardPayload], ──── Card
['image', { ──── Example 'image' card
src: 'http://google.com/logo.png'
}]
]
}
Markup Section
Markup sections, in addition to plain text, can include markups and atoms.
{
version: "0.3.0",
markups: [
["b"], ──── Markup at index 0
["i"] ──── Markup at index 1
],
atoms: [
["mention", "@bob", { id: 42 }] ──── mention Atom at index 0
["mention", "@tom", { id: 12 }] ──── mention Atom at index 1
]
sections: [
[sectionTypeIdentifier, tagName, markers], ──── sectionTypeIdentifier for markup sections
[1, "h2", [ is always 1.
[0, [], 0, "Simple h2 example"],
]],
[1, "p", [
[textTypeIdentifier, openMarkupsIndexes, numberOfClosedMarkups, value],
[0, [], 0, "Example with no markup"], ──── textTypeIdentifier for markup is always 0
[0, [0], 1, "Example wrapped in b tag (opened markup #0), 1 closed markup"],
[0, [1], 0, "Example opening i tag (opened markup with #1, 0 closed markups)"],
[0, [], 1, "Example closing i tag (no opened markups, 1 closed markup)"],
[0, [1, 0], 1, "Example opening i tag and b tag, closing b tag (opened markups #1 and #0, 1 closed markup [closes markup #1])"],
[0, [], 1, "Example closing b tag, (no opened markups, 1 closed markup [closes markup #0])"],
]],
[1, "p", [
[textTypeIdentifier, openMarkupsIndexes, numberOfClosedMarkups, atomIndex],
[1, [], 0, 0], ──── mention atom at index 0 (@bob), textTypeIdentifier for atom is always 1
[1, [0], 1, 1] ──── mention atom at index 1 (@tom) wrapped in b tag (markup index 0)
]],
]
}
The index in openMarkupsIndex
specifies which markups should be opened at
the start of the value
text. As these tags are opened, then create a stack
of opened markups. The numberOfClosedMarkups
says how many of those opened markup tags should
be closed at the end of a value
.
In addition to markers, markup sections may contain ATOMS.
Atoms in a markup section have a textTypeIdentifier
of 1 and contain an atomTypeIndex
.
They also contain the same openMarkupsIndex
and numberOfClosedMarkups
values that other markers have, so that markup can flow across them.
If an atom is present in Mobiledoc but no atom implementation is registered, the text value of the atom will be rendered as plain text as a fallback.
Card Section
{
version: "0.3.0",
cards: [
["card-name", { cardPayload }]
],
sections: [
[typeIdentifier, cardIndex], ──── typeIdentifier for card sections
[10, 0] is always 10.
]
}
cardPayload
is arbitrary and should be passed through to the card
implementation.