#view #db #block #model #style #spans #markup

assemblage_view

Linearized View Model and Bindings for AssemblageDB

1 unstable release

0.1.0 Aug 18, 2021

#2199 in Database interfaces

AGPL-3.0

290KB
5K SLoC

Linearized View Model & Bindings for AssemblageDB

Assemblage View is a relatively thin layer between frontend implementations and AssemblageDBs, exposing the document-graphs of AssemblageDBs as a linearized view-model that can more easily be processed by a frontend. Assemblage View can be thought of as the Ariadne to AssemblageDB's labyrinth, providing a flat and linear view onto a deeply nested and possibly cyclic structure, with links to other paths that "branch off" the main path.

Assemblage View implements bindings that can be used from JS to query and update an AssemblageDB running on wasm, with an ultra-minimal markup language inspired by Markdown as a way to edit text blocks and sync their visual representation with the DB.

Please note that the view model is still rather experimental (even more so than the AssemblageDB data model) and may change considerably in the future.

Data Model

Nodes in an AssemblageDB form a directed, possibly cylic graph and cannot be straightforwardly displayed without first "linearizing" them into a view that shows only a single subtree and renders all connected parents or siblings as links that branch off. This crate provides such a frontend-independent view model, which can be used as a high level, linearized interface to an AssemblageDB by frontends on different platforms.

A linearized view consists of 6 different levels of components:

  • A single Space, which contains one or more tiles (usually arranged horizontally side by side).
  • Tiles, a single node and its subtree (of descendants), which can contain zero or more sections.
  • Sections, a single editable subsections or an uneditable group of subsections that appear as children of multiple nodes.
  • Subsections, which contain a single block and one or more branches leading to other nodes before or after the block.
  • Blocks descendants of the top-level node that must be displayed as blocks due to their layout or style.
  • Spans, the descendants of the block descendants that must be displayed as spans due to their layout or style.

As a result, frontends only have to follow a very simple document model, which is always just 6 levels deep: A space contains tiles, which contain sections, which contain subsections, which contain a single block, which contain spans.

By design, nested lists (as in Markdown) or multiple levels of headings are not supported. Instead of a single, complex and hierarchical document, Assemblage spaces favor a collection of relatively flat tiles. The richer structure of an Assemblage space emerges as the result of the interplay of these intertwined nodes.

Markup

Assemblage View supports an ultra-minimal markup language inspired by Markdown, but much simpler and deliberately focused on flat markup for a single block of text.

Features

  • extremely minimal: Only 4 block styles and 5 span styles.
  • simple to parse: Each style corresponds to a single character.
  • unambiguous: Only one way to write each style.
  • flat: No nesting, neither for headings nor lists.

Markup Example

(Note that the following code block is not strictly speaking the markup language that is parsed by the functions provided in this crate, as these functions always parse a single line of markup into a single AssemblageDB block.)

# Headings start with "#".
> Block quotes start with ">".
- Lists...
- ...start...
- ...with...
- ..."-"!
, Oh and by the way, asides start with ",".

The above 4 block styles are all there is to block styling.
They can be combined in any order:

#>, A block quote heading aside.
,>#> Also a block quote heading aside.

But " " is needed to separate the block markers from the text:

#This is just regular text, as block styles need to end with a " ".
#>-This is also just regular text...

There are also 5 different span styles:

*These three words* are bold.
And _this_ is italic.
Words can be ~struck from a sentence~.
Code can be displayed with a `monospaced typeface`!
Some |parts of a sentence| can be marked and thus highlighted.

Each span style can be escaped, for example in: 2 \* 2 = 4.

And that's it!

Why not Markdown?

Markdown is relatively easy to write, but is far from simple to parse and process, with many different implementations that do not always follow the same specification. More importantly however, Markdown provides markup capabilities for full documents including multiple (nested) hierarchy levels and the ability to include arbitrary HTML, which ties Markdown to the web.

Instead, the ultra-minimal markup language implemented here provides markup only for text blocks (not full documents) and does not support any nesting, neither of headings nor of lists or other structures. This is deliberate, as nested structure and rich hierarchies arise from the graph structure and interplay of different AssemblageDB nodes, not as the result of a single and complex markup block.

Minimal markup encourages structure through the combination of different documents, whereas sophisticated markup encourages siloization into fewer less richly connected documents.

Specification (as ABNF)

markup       = [block-markup] span-markup
block-markup = 1*(heading / quote / list / aside) " "
heading      = "#"
quote        = ">"
list         = "-"
aside        = ","
span-markup  = normal / bold / italic / struck / mono / marked
normal       = *(unescaped / escaped)
unescaped    = ; all characters except "\", "*", "_", "~", "`", "|" and newline
escaped      = "\\" / "\*" / "\_" / "\~" / "\`" / "|"
bold         = "*" span-markup "*"
italic       = "_" span-markup "_"
struck       = "~" span-markup "~"
mono         = "`" span-markup "`"
marked       = "|" span-markup "|"

Dependencies

~5–19MB
~253K SLoC