Skip to main content

The Delta Format

The Delta format is at the base of QuillJS's text editing capabilities. You can read the in-depth guide on the QuillJS website. This introductory overview goes over what you need to understand to effectively work on BobaEditor.

What is a Delta?

A Delta is a presentation-agnostic representation of formatted text. It contains everything we need to translate text into a visual format (e.g. HTML) without implementation-specific details.

The separation of representation and implementation means changes to BobaEditor's rendering logic also influence the rendering of older, stored Deltas. This makes it possible to change our output (e.g. CSS classes, rendered HTML elements, JavaScript event handlers) without worrying about compatibility with previous versions, something that would be extremely hard if we stored the rendered HTML.

What does a Delta look like?

In its simplest form (the one eventually stored in the database) a Delta is an array of insert operations.

Delta:

[
{ "insert": "This is a H1 Header" },
{ "insert": "\n", "attributes": { "header": 1 } },
{ "insert": "You can have various types of formatting, like " },
{ "insert": "inline code", "attributes": { "code": true } },
{ "insert": ", " },
{ "insert": "bold text", "attributes": { "bold": true } },
{ "insert": ", or even " },
{ "insert": "spoilers!", "attributes": { "inline-spoilers": true } },
{ "insert": "!\n" },
{ "insert":
{
"block-image": {
"src": "/img/documentation/cool.png",
"width": "200",
"height": "106"
}
}
},
{ "insert": "As seen above ☝️, images and other types of embeds are also supported." }
]

Output:

This is a H1 Header

You can have various types of formatting, like inline code, bold text, or even spoilers!!

As seen above ☝️, images and other types of embeds are also supported.

Insert operations

There are three types of insert operations:

  • Inline formatting: for inline styles (e.g. bold, text spoilers).
  • Line formatting: for styles applied to the preceding line as a whole (e.g. paragraph centering, headings, lists).
  • Embeds: for non-text content.

Inline formatting

Inline formatting applies only to the text within a specific insert operation. The type of formatting is specified through the "attributes" property of the corresponding insert operation.

Delta:

[
{ "insert": "Here's an " },
{ "insert": "example", "attributes": { "italic": true } },
{ "insert": " of " },
{ "insert": "inline ", "attributes": { "bold": true } },
{ "insert": "~styles~", "attributes":
{
"bold": true,
"link": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"italic": true
}
}
]

Output:

Here's an example of inline ~styles~

Custom inline formats

For a practical example of a custom inline styles, you can refer to InlineSpoilers.tsx.

The InlineSpoilers class extends the blots/inline class from Quill. This is used for inline text that can accept further formatting.

You can read more about inline blots on the "Cloning Medium with Parchment" example on the QuillJS website.

Line formatting

Line formatting applies to the whole preceding line, as delineated by the newline character (\n). The type of formatting is specified through the "attributes" property of the corresponding insert operation, whose textual value is a single \n.

Delta:

[
{ "insert": "When a insert operation contains only a single '\\n' its attributes apply to the whole previous \n" },
{ "insert": "line (which can still have " },
{ "insert": "inline attributes", "attributes": { "bold": true } },
{ "insert": ")" },
{ "insert": "\n", "attributes": { "header": 1 } },
{ "insert": "!" }
]

Output:

When a insert operation contains only a single '\n' its attributes apply to the whole previous

line (which can still have inline attributes)

!

Custom line formats

BobaEditor doesn't currently have an example of a custom line formatting element, which are (in theory, since we've never tried) implemented by extending the blots/block class from Quill. These are used for text formatting operations that are mutually exclusive (i.e. a <h1> element cannot appear within a <blockquote>).

You can read more about block blots on the "Cloning Medium with Parchment" example on the QuillJS website.

Embeds

Embeds are complex, non-textual elements. In the case of embeds, the value of the insert attribute will be an object with a single attribute named after the type of embed itself. The value of this attribute will be passed to the embed element for rendering.

Delta:

[
{ "insert": "Embeds represent complex non-textual elements, like images:" },
{ "insert":
{
"block-image": {
"src": "https://media1.tenor.com/images/4335e4cadbb8ac96f1e888710ebbff08/tenor.gif?itemid=15782429",
"width": "200",
"height": "200",
"spoilers": true
}
}
}
]

Output:

Embeds represent complex non-textual elements, like images:

Custom embeds

For an example of how to implement a custom embed, you can look at BlockImage.tsx. This, like other embeds, extends the blots/block/embed class from Quill. The important methods to implement are:

  • create: the entry point of embed rendering. Its only argument is the value of the embed attribute specified by the blotName property (block-image in the previous example).

    create returns the root DOM node of the embed element, which is created by calling super.create() and whose node type (e.g. div) is determined by the tagName property.

  • value: given the root DOM node returned by create, extracts the value of the embed element.

    value returns the proprieties that need to be stored to recreate the embed during the insert operation ({src: ..., width: ..., ...} in the previous example).

You can read more about embed blots on the "Cloning Medium with Parchment" example on the QuillJS website.