仙那度计划 (Project Xanadu) | 双链简史

本文正式开始之前,让我们回到故事的原点——追溯双向链接的历史,找寻永恒记忆宫殿的遗址

上都启示录:超链接(Hypertext)缘起

一切的一切,始于信息技术先驱 Ted Nelson(泰德 · 尼尔森)内心深处的愿景——一个能够在数字世界关联起一切事物的电脑文件系统。最初,Nelson 的构思是想建造一个数字资源库——以承载全世界范围内的所有电子出版物。

 

那之后,他将心目中关于这一想法的企划正式命名为 Project Xanadu「上都计划」。

尼尔森定义了「超文本」的概念

1965 年,Nelson 把他的想法诉诸于论文之上,并提交给了计算机协会(ACM)。

 范式:Xanadoc | Xanadu Space

这是一篇关于宇宙学的文档,由其他文献中的段落共同组成

感兴趣的朋友可自行访问 Xanadoc 或者观看 Nelson 发布的示范 Demo

 

失落的仙那度 | 万维网(World-Wide-Web)远非世外桃源

尼尔森不认同多数人对于「所见即所得」的看法

不难看出,Nelson 本人并不认可互联网时代下的万维网——他认为所谓的「所见即所得」,不过是局限在传统打印文件里的说法。

也就是说,一切计算机文档都是无互动性可言的,既不能被标注,也不允许插入(外部链接)——好比压在玻璃下的报纸,是可望而不可即的。

因此,当下的人们亟需一个可以关联所有文档的笔记工具,以满足信息时代日益增长的个人知识储备。


Roam Research:属于前方朝圣者的福音 | Project Xanadu 原教旨之十二

1.每一位用户都是独一无二且属安全认证的:

在 Roam 里,每一个云端库(Hosted Graph)都是独有且私有的。

ps:仅在创建图库阶段,可以将其设置为独立加密类型

2.每一位用户可自行搜索,检索,创建以及存储文档

每一位用户(编辑权限)可自行搜索,检索,创建以及存储区块(Block)和页面(Page)。

3.每一份文档可由任何数据类型的任意数量部分组成

Roam 的 Block 可由相当数量的不同数据文件组成,类型如下:

  • 文本(text)、图像(image),音视频(audio/video)
  • PDF文件、网页(web page)
  • 看板(kanban)、表格(table)
  • 画板(drawing board)
  • 白板工具(excalidraw)
  • 思维导图(diagram)

4.每一份文档可包含任意类型的链接,包括系统所有者可访问的任何文档的虚拟拷贝(转包)

每一个区块可包含任意类型块的引用,包括图库所有者可访问的任何区块的虚拟拷贝(嵌入)

5.链接是可见,且可从所有端点处出发跟踪

块引用是公开的,且能从所有引用过原区块的区块处反向跟踪

6.每一份文档都是独一无二且安全认证的

每一个区块都是独一无二且由双重标识(Private ID/Public ID)进行识别——每一页 Page 在命名空间(Namespace)的标题(Title)都是唯一的

对于云端加密库而言,每一个块(页面)引用都经由自动加密处理

特殊地,桌面端应用上的离线本地库无法加密由用户上传的图像等媒体附件

7.每一份文档都具备安全的访问控制

每一份页面都可以被共享给任何人,或具备阅读/编辑(read/edit)的账号邮箱

特殊地,共享独立页面将加载部分图库(Graph)的数据到任何一位访问者的浏览器上

因此,对于一位别有用心且精于钻研的人来说,他将可以从某一页面访问图库

8.每一份文档都可以进行快速搜索,存储以及检索,并且无须考虑其物理意义上的存储位置

每一个区块(文本/字符串)都可以进行快速搜索,存储(仅限于 Page)以及检索,并且无须考虑后端数据库的存储问题

9.每一份文档根据来自任意地点的访问频率,自动迁移到最合适的物理存储区

每一个区块涉及到的最近编辑数据,都以 EDN 格式扁平化存储为一系列简易数据集,并储存在本地缓存中

除此之外,对于无加密的云端库来说,还能够以离线的形式直接访问
警告:删除本地缓存将导致尚未同步的数据丢失

而对于任何共享了访问权限(阅读/编辑)的人来说,图库数据将加载至他们的浏览器上

10.每一份文档都有作自动冗余存储,即使在意外情况下也能保持可用性

仅对本地库而言,如果尝试清除本地存储,那么此举将即刻删除掉该浏览器上的所有图库
建议:用户方应自行设置好定期备份,以避免重要数据的损失

对于任何共享了访问权限(阅读/编辑)的人来说,都可以将图库整体导出为以下格式:MarkDown/MarkDown、JSON以及EDN

Roam 支持 4 种格式的整库导出

11.每一项事务都是保密且可由组成事务的部分(文档源)进行单独审计的

每一项事务都默认存储在与之对于的属性列表当中;每一项事务都仅可由共享相同事务ID的区块进行审计查询

此外,仅限于云端库而言,所有区块的类型内容(含图像等媒体附件)同数据集(非必要的元数据外)一样,均可经由加密处理

  • 常见的上传附件 (Uploads):图像、音视频、还有 PDF 文件
  • 一些非必要元数据 (Non-Necessary Metadata) 不会被加密:
    • 节点形式(无序/有序/文档)
    • 标题水平以及文本调整情况(居左/居中/居右)等
  • 所有 Blocks 的关键数据将被加密:
    • 各个用户的昵称/邮箱
    • 以及创建该区块的用户信息(昵称/邮箱)
    • 还有页面标题,图像链接等

12.Xanadu 客户端通讯协议是符合开源公布标准的;因此,涉及到第三方软件的开发与集成是被允许且支持的

在 Roam 中,涉及到第三方插件的开发和集成式被允许且支持的

用户方甚至可以直接在特定的页面或区块下方,自行修改定义图库样式 (Graph's CSS), 以及 JS

举例来说:油管视频(嵌入式)的 Comment Button 的样式修改

{
  background-color: white;
    right: 0;
    left: 98%;
    top: 95%;
    bottom: 0;
    z-index: 2;
    opacity: .8;
    position: absolute;
    border-top-left-radius: 7px;
}

类似的设置,都是可以直接在 Graph 里由用户方自行定义的


知识图谱 Roam Graph:非线性大纲笔记——打破传统文件柜的桎梏

对于非线性的网状形成,不只是页面与页面之间的联系,更要有任意段落的粒度参与。

跳出文档柜的层级藩篱,打造第二大脑的数字城堡

每一页 Page 都是 Graph 这座森林中的一棵树,而所有的 Blocks 则充当枝干和树叶的形式。

[[Page]]
* Branch
  * Branch
    * Leaf
    * Leaf
  * Leaf
  * Branch
    * Branch
      * Leaf
* Branch
  * Leaf
...

事实上,Page 和 Block 并没有本质上的区别,Page 只不过是一类特殊的 Block ——作为视图 (Graph Overview) 上独立且直观的节点;换句话说,Page 即是不存在父级节点 (Parent Node) 的区块。

更形象地说,Pages 与 Blocks 之间的关系基本可视作为正方形与长方形(前者为独立的个体,通常由后者组成)。

不只是树叶的繁荣,也要有花朵般的点缀

标题树 [[title]]

标题粒度

使用 [[]](双中括号)引用的 Pages,具备相对宽泛的节点粒度;如同森林里的树木,高矮胖瘦,各有不同。

顺便说一句,区块 (Blocks) 在粒度的定义上理应是“最自由自在的”。

 

标签垛 #tag

标签粒度

紧挨着 #(井号)的 Page 引用通常具备较小的节点粒度,这类标签常用于标记 Block(s) 在内容上可能涉及到的概念/范畴。

堆垛 #tag/sub-tag

对于递进式的标签链接,它们更接近于「堆垛」的状态。

只有当该标签(含子标签)相对于独立标签是不可分割的,才以“多步标签 (Multi-step label)”的形式进行引用

如果还是不能很好的 Get 到这一块的内容,可通过以下内容来理解:

上图为O2(氧分子),下图为O3(臭氧分子)

如图,两种分子都属于是氧元素的单质类型。不同的点在于臭氧分子比之氧分子多出了一个氧原子——因此说臭氧在形态上更进一步。

 

属性核 attribute::

属性粒度

attribute::#tag 相似,但在细粒程度上更加具体,普遍用来概括(涵盖)一类拥有共同特征(特性)的的人/事/物。

例如:作者/邮箱 (Author/Email)

Author:: Mac Arthur
Email:: macarthur@gmail.com

 

 种子/果核

简单来说,attribute:: 不仅可以用于描述一类具体的属性,还能用来概括具备同一特点的不同事物。

Forest
* Apple:: This is an apple
  * AppleCore:: An apple core

* Banana::
  * BananaSeed:: A banana seed
  * BananaSeed:: A banana seed
  * BananaSeed:: A banana seed

* Pear:: This is a pear

 

通用格式:

- attribute:: outline 
    - sub-attr-1:: detail
    - sub-attr-2:: detail
    - sub-attr-3:: detail

 

简而言之,一切与属性相关的数据,更接近于“元数据 (Metadata)”的概念。

用集合的表达式来理解的话,attribute:: 更接近于右侧对于 φ 的属性定义(特点/类别);左侧部分则是双冒号 :: 之后具体的(多数)对象。

可见,集合`{1,2,3,4}`中各元素满足同一特征 φ∈N*

而在 Roam 中,具备相同(近似)属性/属于相同(近似)类型,则可由 attribute:: 来定义或包含。

 

内联标题[[[[inline]]outline]]

标题中的标题:洋葱头,番石榴,柚子

除了上述三类引用,Page 还可以作为任意粒度的独立节点(相对于 Block 而言)——此类 Page 可以在标题的命名空间 (Namespace) 处内联其他 Page 的 Title,来进一步「增殖」该 Page 的节点粒度

Guava: [[[[seed]][[flesh]]]]

可见,Guava 通过前后内联其他 Page,使得原本的节点粒度进一步「增生」。


根系发达,枝头发芽

ps:枝头即 Headings,需要区别于页面标题 Title

世界上不存在两片完全相同的叶子

如果说,每一页 Page 都是一棵树,那么它的根须将可以与不同的 Pages 相连——它们之中的 Blocks 既是具备营养的花蜜果肉;也是充当养分的化肥颗粒;更是洞见灵感 (Insight) 的花种果核

而为了保证这样一幅“营养-养分”网络系统的自身稳定,Roam 不仅为每一个 Block (包括 Page 在内) 分配有独一无二的双重 ID,还在页面标题的命名上,采取了「非唯一则合并」的维稳手段。

对于页面标题的(重)命名,Roam 只允许同时存在一份同名 Page,并在内容上合并二者。

良好的开端,是成功的一半

每一页 Page 下的 Top-level Blocks,通常作为 Headings 存在

正如本章开头所提及的,Graph 本身像是一座大林场。每一页 Page 即是一棵 Tree,而这些 Top-level Blocks 则是树上的主要枝干,起到统领全文,提纲挈领的重要作用。

它们常以各级标题的形式出现,如一级/二级/三级标题:

一级标题

二级标题

三级标题

 

而这些 Top-level Blocks 都将 Page 视作唯一的父级节点;且 Top-level Blocks 不只是作为 Page 的直属(后代)节点,同时还是各段落的起首节点。

尽管标题水平 (Heading Level) 与节点当前所处的层级无关,但还是十分建议将 Heading Blocks 与线性的层级关系相匹配。

注:heading 仅作为一个 Blocks 的可选项(相对于 Pages 的 Title)

附庸的附庸不是我的附庸

一般来说,当把 ((block ref)) 置于某处时,该引用仅显示当前块的命名空间 (Namespace) 里的内容。

那么块引用 ((block ref)) 与嵌入 {{embed:((block ref))}} 间的区别又何在呢?

全文式索引的块引用

通俗地说,块引用是仅包含自身的;除非嵌入该引用,否则节点将视作从原本的层级关系中「抽离」出来而变得无法展开的。

只有当块引用被置于嵌入块内,即 {{embed:((block ref))}},才能够展开/收缩其下属的后代节点——之所以将块引用称作【全文式索引】的缘故,正是因为 ((block ref)) 总是指向被引用块的位置以及包含一个直属子级节点的属性列表

换句话说,只有被嵌入的 Block(s),才能「串联」起各个层级的后代节点,进而形成完整的 Branches 分支系列。

定位原区块的导航栏

左键位于左侧的 Bullet Node,将 Zoom-in 到当前区块(段落),或者在按住 Shift 键的同时左键节点,则可在右侧 Sidebar 处打开当前区块的“视窗口”;

而不管使用哪一种方式打开,都始终存在一个 Breadcrumb 导航栏指向当前节点的先代节点——这是因为所有节点的 ((block ref)) 都将默认存储在其所有后代的属性列表当中。

Breadcrumb 导览器

引用上下文的位置框

同样,左键位于视窗口顶部的(任一)先代节点,即可展示对应层级的上下文内容——此时,会出现一个“黄色边框的盒子”来「突出」原区块的位置。

在右侧 Sidebar 处 Zoom in 当前区块

简而言之,你进入的层级越高,那么你看到的上下文越多。


半场总结

综上所述,Roam 的双向链接 (Bi-Directional Liking) 足以证明涉及到整个 Graph 中的不同 Page/Block(s) 之间的链接是高度可靠的,且能在足够宽泛的粒度范畴内深度「反向追踪」。

【可溯源性】在设计上应当高于【延展性】。

概要

现在,让我们再次回顾一下目前提及的功能特性

  1. Page 对应不同节点粒度区间的基本引用形式:[[title]]/#tag/attribute::
  2. Page Title 命名的全局唯一性——Block Ref 同样具有潜在的唯一性
  3. Block Ref 引用的全文式索引
  4. 任一 Block 的 Breadcrumb 导航栏

可以说,Roam 在节点内容的粒度上没有任何限制,也支持上传各种类型的资源文件——除了文本,块引用本身还能展示图像,音视频等外部链接的内容。

在下文中,我们将继续探索 Roam 中的功能块 (Func-Blocks)。