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

assemblage_view

AssemblageDB的线性化视图模型和绑定

1 个不稳定版本

0.1.0 2021年8月18日

#2289数据库接口

AGPL-3.0

290KB
5K SLoC

AssemblageDB的线性化视图模型 & 绑定

Assemblage View是前端实现和AssemblageDB之间的一层相对较薄的层,将AssemblageDB的文档图暴露为线性化视图模型,可以更容易地由前端处理。Assemblage View可以被视为AssemblageDB迷宫中的阿尔戈斯,提供了一个平坦且线性的视图,对于深层嵌套且可能具有循环的结构,以及与其他路径的链接,这些路径从主路径“分支”出来。

Assemblage View实现了可以从JS使用的绑定,用于查询和更新在wasm上运行的AssemblageDB,使用受Markdown启发的极简标记语言来编辑文本块,并同步它们的视觉表示与数据库。

请注意,视图模型仍然相当实验性(甚至比AssemblageDB数据模型还要实验性),将来可能会发生重大变化。

数据模型

AssemblageDB中的节点形成一个有向图,可能是循环的,不能直接显示,必须先将其“线性化”到一个只显示单个子树的视图,并渲染所有连接的父节点或兄弟节点作为分支的链接。这个crate提供了一个前端独立的视图模型,可以由不同平台的前端用作对AssemblageDB的高层、线性化接口。

线性化视图由6个不同级别的组件组成

  • 一个空间,包含一个或多个图块(通常横向排列)。
  • 图块,一个节点及其子树(后代),可以包含零个或多个部分。
  • 部分,单个可编辑的子部分或不可编辑的子部分组,它们作为多个节点的子节点出现。
  • 子部分,包含一个块和一或多个分支,这些分支指向块之前或之后的其他节点。
  • ,顶级节点的后代,由于布局或样式原因必须以块的形式显示。
  • 跨度,由于布局或样式原因必须以跨度形式显示的块的后代。

因此,前端只需遵循一个非常简单的文档模型,该模型总是6层深:一个空间包含图块,图块包含部分,部分包含子部分,子部分包含单个块,块包含跨度。

按照设计,不支持嵌套列表(如Markdown中的)或多个级别的标题。Assemblage空间更倾向于一系列相对扁平的板块。Assemblage空间的丰富结构是通过这些交织节点的相互作用产生的。

标记语言

Assemblage视图支持一种受Markdown启发的极简标记语言,但它更简单,且故意专注于单个文本块的扁平标记。

特性

  • 极简:只有4种块样式和5种跨度样式。
  • 易于解析:每种样式对应一个字符。
  • 明确:每种样式的写法只有一种。
  • 扁平:不支持嵌套,无论是标题还是列表。

标记示例

(注意,以下代码块并非严格意义上的标记语言,因为这些函数始终将单行标记解析为一个AssemblageDB块。)

# 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!

为什么不使用Markdown?

Markdown相对容易编写,但解析和处理起来远非简单,有众多不同的实现,它们并不总是遵循相同的规范。更重要的是,Markdown为完整文档提供了标记功能,包括多个(嵌套)层级和包含任意HTML的能力,这使得Markdown与网络紧密相关。

相反,这里实现的极简标记语言只为文本块(而不是完整文档)提供标记,不支持任何嵌套,无论是标题、列表或其他结构。这是故意的,因为嵌套结构和丰富层次结构是从AssemblageDB节点的图结构和不同节点之间的相互作用中产生的,而不是从单个复杂标记块中产生的。

极简标记鼓励通过不同文档的组合来构建结构,而复杂的标记则鼓励将结构分割成较少且联系较少的文档。

规范(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 "|"

依赖项

~4-18MB
~235K SLoC