Google Wave 协议的常见问题解答说 [HTML]“没有理想的属性”并且“HTML 使 OT(操作转换)即使不是不可能也很困难”[1]。为什么会这样?如果 HTML 被简单地视为纯文本然后应用 OT 会出现什么问题?
3 回答
我在这里假设您了解 OT 的基础知识。以纯文本形式在 HTML 上进行 OT 的主要问题是合并 html 标签。举个简单的例子,假设我们有一个文档如下:
Hello world
Alice 然后决定世界应该是粗体:
Hello <b>world</b>
这可以用 OT 中的双插入操作来表示,示意性地表示:
Edit A: Keep 6 : Insert "<b>" : Keep 5 : Insert "</b>"
如果 Bob 在看到 Alice 的编辑之前决定“世界”应该是斜体,他将添加操作
Edit B: Keep 6 : Insert "<i>" : Keep 5 : Insert "</i>"
如果服务器在 Alice 之后收到 Bob 的编辑,则需要将 B 与 A 转换为 B'。
Keep 语句通过转换保持不变,但 Insert "" 转换为 Insert "" 可以成为 Keep 3 : Insert "" 或 Insert "" : Keep 3。通常服务器将配置为在第一次编辑之后放置稍后的编辑。
Edit B': Keep 6 : Keep 3 : Insert "<i>" : Keep 5 : Keep 3 : Insert "</i>"
这里问题变得很明显。将 A 然后 B' 应用于原始字符串会给出无效的 html:
Hello <b><i>world</b></i>
理论上,这可以通过改变前后插入来解决,但是对于更复杂的示例,这会变得很麻烦,可能涉及对每个转换的完整文档扫描。
正如另一个答案所指出的,使用带外注释+纯文本可以避免这种混乱。到目前为止,我只在学术论文中看到的另一种方法是将 XML 结构视为具有 OT 操作的树,用于添加、删除节点,例如:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.100.74
我没有完整的答案,但我有兴趣看到在使现有开源操作转换库与富文本一起工作方面所做的更多工作,所以我将贡献我所知道的。
HTML 和 Wave 模式之间的重要区别似乎在于标记文本格式的方式:HTML 的嵌套标签层次结构与 Wave XML 范围的带外注释(在文档的页脚中)。带外注释可能是标记文本格式的一种更自然的方式,因为它们允许重叠(非嵌套)格式。它允许这样的事情(在伪标记中),这不是使用嵌套表示的有效 XML:
(b) This is bold (i) while this range is both bold and italic (/b) and this last bit is just italic (/i)
OT中有一些方法支持 SGML(XML 的超集),但没有实现。因此,这并非不可能!不过,我同意,OT 并不是启用 XML 的最佳方法。这是因为 OT 是为线性数据结构设计的。但是 HTML/XML 要复杂得多:它具有属性,并且像树一样构建。它是一棵树的事实是可以解决的,但是 OT 不支持属性(实现为有序关联数组)。仅仅是因为 OT(目前)不支持关联数组。上面的方法实际上建议将属性视为字符串:例如“id='myid' value='mystuff'” 但是当一个用户删除所有属性时,您可以轻松破坏“attributes-string”的整个语法,并且另一个在“mystuff”之后直接插入一个“字符。<div ">
,这是无效的语法。
也许这会让你感兴趣:
CEFX 是一个旨在支持 XML 的项目——据我所知,它已经死了。但它使用了 OT 方法。由于某种原因,无法编辑字符串 - 只有 xml 元素。
Google 的 Drive SDK 支持类似图形的数据结构。然而,它是专有的,没有人知道它是如何工作的。
我正在开发一个支持任意数据结构的框架。目前支持 Text、Json、XML 和 HTML。它有不同的方法:检查一下:Yatta!
顺便说一句:Wave 协议和 Eric Drechsel 所描述的内容在 OT 中被称为注释。它通常用于支持富文本。