首页 > 其他分享 >Quill文档(六):Parchment详解

Quill文档(六):Parchment详解

时间:2024-04-03 14:29:52浏览次数:24  
标签:Blot 格式化 详解 文档 格式 Parchment Quill 属性

Parchment 是 Quill 的文档模型。它是与 DOM 树并行的树形结构,并为内容编辑器(如 Quill)提供有用的功能。Parchment 树由 Blots 组成,这些 Blots 镜像了 DOM 节点的对应物。Blots 可以提供结构、格式和/或内容。Attributors 还可以提供轻量级格式信息。

注意:您不应使用 new 直接实例化一个 Blot。这可能会阻止 Blot 必要的生命周期功能。请改用 Registry 的 create() 方法。

npm install parchment

查看 使用 Parchment 克隆 Medium 以了解 Quill 如何使用 Parchment 作为其文档模型。

Blots


Blots 是 Parchment 文档的基本构建块。提供了几种基本实现,如 Block、Inline 和 Embed。通常,您将希望扩展这些之一,而不是从头开始构建。实现后,必须在使用前注册 Blots。

至少,一个 Blot 必须使用静态的 blotName 命名,并与 tagName 或 className 关联。如果一个 Blot 同时用标签和类定义,类具有优先权,但标签可以用作备选。Blots 还必须有一个 scope,这决定了它是内联的还是块级的。

class Blot {
  static blotName: string;
  static className: string;
  static tagName: string | string[];
  static scope: Scope;

  domNode: Node;
  prev: Blot | null;
  next: Blot | null;
  parent: Blot;

  // 创建对应的 DOM 节点
  static create(value?: any): Node;

  constructor(domNode: Node, value?: any);

  // 对于叶子,blot's value() 的长度
  // 对于父级,子节点值的总和
  length(): Number;

  // 在给定的索引和长度处操作,如果适用。
  // 通常会将调用传递给适当的子节点。
  deleteAt(index: number, length: number);
  formatAt(index: number, length: number, format: string, value: any);
  insertAt(index: number, text: string);
  insertAt(index: number, embed: string, value: any);

  // 返回此 blot 与祖先之间的偏移量
  offset(ancestor: Blot = this.parent): number;

  // 在更新周期完成后调用。不能更改文档的值或长度
  // 任何 DOM 操作都必须减少 DOM 树的复杂性
  // 一个共享的上下文对象被传递给所有 blots。
  optimize(context: { [key: string]: any }): void;

  // 当 blot 发生变化时调用,带有其变化的变更记录。
  // 可以更新 blot 值的内部记录,并允许修改
  // blot 本身。可以由用户更改或 API 调用触发。
  // 一个共享的上下文对象被传递给所有 blots。
  update(mutations: MutationRecord[], context: { [key: string]: any });

  /** 仅叶子 Blots */

  // 如果 domNode 是此 Blot 的类型,则返回由 domNode 表示的值
  // 不需要检查 domNode 是否可以表示此 Blot 类型,所以
  // 需要它的应用程序应在调用之前外部进行检查。
  static value(domNode): any;

  // 给定由节点和 DOM 选区范围的偏移量表示的位置,
  // 返回该位置的索引。
  index(node: Node, offset: number): number;

  // 给定 blot 内位置的索引,返回表示
  // 该位置的节点和偏移量,可由 DOM 选区范围消费
  position(index: number, inclusive: boolean): [Node, number];

  // 返回由此 blot 表示的值
  // 除非通过 API 或
  // 可由 update() 检测到的用户更改,否则不应更改
  value(): any;

  /** 仅父级 blots */

  // 可以是直接子级的 Blots 的白名单数组。
  static allowedChildren: Registry.BlotConstructor[];

  // 如果此 blot 变为空,则要插入的默认子级 blot。
  static defaultChild: Registry.BlotConstructor;

  children: LinkedList<Blot>;

  // 在构建期间调用,应填充其自己的子级 LinkedList。
  build();

  // 用于后代的有用搜索功能,不应修改
  descendant(type: BlotClass, index: number, inclusive): Blot;
  descendants(type: BlotClass, index: number, length: number): Blot[];

  /** 仅可格式化 blots */

  // 如果 domNode 是此 Blot 的类型,则返回由 domNode 表示的格式值
  // 不需要检查 domNode 是否为此 Blot 的类型。
  static formats(domNode: Node);

  // 应用格式到 blot。不应传递到子级或其他 blot。
  format(format: name, value: any);

  // 返回 blot 表示的格式,包括来自 Attributors 的格式。
  formats(): Object;
}

示例

实现一个表示链接的 Blot,它是一个父级、内联作用域、可格式化的。

import { InlineBlot, register } from 'parchment';

class LinkBlot extends InlineBlot {
  static blotName = 'link';
  static tagName = 'A';

  static create(url) {
    let node = super.create();
    node.setAttribute('href', url);
    node.setAttribute('target', '_blank');
    node.setAttribute('title', node.textContent);
    return node;
  }

  static formats(domNode) {
    return domNode.getAttribute('href') || true;
  }

  format(name, value) {
    if (name === 'link' && value) {
      this.domNode.setAttribute('href', value);
    } else {
      super.format(name, value);
    }
  }

  formats() {
    let formats = super.formats();
    formats['link'] = LinkBlot.formats(this.domNode);
    return formats;
  }
}

register(LinkBlot);

Quill 还在其源代码中提供了许多出色的示例实现。

Block Blot


基本实现了一个块级作用域的可格式化父级 Blot。默认情况下,格式化一个块级 Blot 将替换 Blot 的适当子部分。

在 Quill Parchment 模型中,"Block Blot" 是一种特殊类型的 Blot,它代表文档中的一个块级元素,比如一个段落 <p>、一个标题 <h1><h6>、一个列表 <ul><li> 等。Block Blot 是用来构建那些在文档中占据一整行或更多空间的元素的。

Block Blot 的特点如下:

  1. 块级作用域:Block Blot 定义了一个块级的作用域,这意味着它代表的内容在视觉上和其他内容(如另一个 Block Blot 或内联元素)有明显的分隔。这种分隔使得 Block Blot 可以独立地应用格式,而不会影响到其他内容。
  2. 可格式化:Block Blot 支持格式化操作,如加粗、斜体、下划线等。当用户对文档中的某个部分应用格式时,Parchment 会根据 Blot 的结构来确定如何应用这些格式。对于 Block Blot 来说,格式化通常意味着创建一个新的 Blot 实例,它具有与原始 Blot 相同的内容,但是带有新的格式属性。
  3. 父级 Blot:Block Blot 通常是其他 Blot(如 Inline Blot 或 Embed Blot)的父级。这意味着它可以包含其他类型的 Blot 作为其子级,形成一个树状结构,其中 Block Blot 位于树的上层。
  4. 默认替换行为:当对 Block Blot 应用格式化时,默认情况下,Parchment 会替换 Blot 的适当子部分。这意味着如果格式化应用于 Block Blot 的一部分,Parchment 会创建一个新的 Block Blot 实例,其中包含格式化的内容,并将原始 Blot 的未格式化部分与新创建的 Blot 连接起来。这样做可以保持文档的结构和格式的一致性。

例如,假设我们有一个包含文本的段落 Blot,用户决定将段落中的某些单词加粗。Parchment 将创建一个新的 Inline Blot 来表示加粗的单词,并将其插入到父级 Block Blot 中的适当位置。同时,未加粗的文本将保留在原始的 Block Blot 中。这样,文档的结构保持不变,同时满足了格式化的需求。

总之,Block Blot 在 Quill Parchment 模型中扮演着重要角色,它为文档中的块级元素提供了结构和格式化能力,同时保持了文档内容的组织和一致性。

Inline Blot


基本实现了一个内联级作用域的可格式化父级 Blot。默认情况下,格式化一个内联 Blot 要么用另一个 Blot 包装自己,要么将调用传递给适当的子级。

在 Quill Parchment 模型中,"Inline Blot" 是一种特殊类型的 Blot,它代表文档中的内联级元素,比如加粗 (<strong><b>)、斜体 (<em><i>)、下划线 (<u>) 等。Inline Blot 用于构建那些可以嵌入在文本流中而不会造成视觉分隔的元素。

Inline Blot 的特点如下:

  1. 内联级作用域:Inline Blot 定义了一个内联级的作用域,这意味着它代表的内容在视觉上与周围的文本融为一体,不会像块级元素那样有明显的分隔。Inline Blot 通常用于表示文本的样式或语义,而不是内容的结构。
  2. 可格式化:Inline Blot 支持格式化操作,这些操作可以应用于文档中的特定文本范围。当用户对文档中的文本应用格式时,Parchment 会根据 Blot 的结构来确定如何应用这些格式。
  3. 父级 Blot:Inline Blot 可以作为其他 Blot(如 Block Blot 或 Embed Blot)的子级。它可以嵌入到块级元素中,形成一个树状结构,其中 Inline Blot 位于树的中层。
  4. 默认替换或传递行为:当对 Inline Blot 应用格式化时,默认情况下,Parchment 会采取以下两种行为之一:
    • 包装:创建一个新的 Inline Blot 实例,它具有与原始 Blot 相同的内容,但是带有新的格式属性。这个新 Blot 会“包装”原始内容,从而应用格式。
    • 传递:如果格式化操作不适用于当前的 Inline Blot,Parchment 会将调用传递给适当的子级 Blot。例如,如果用户尝试对一个已经包含加粗文本的 Inline Blot 应用斜体格式,Parchment 可能会将斜体格式应用到加粗文本的子级 Blot 上。

这种默认行为使得 Inline Blot 能够灵活地处理多种格式化操作,同时保持文档内容的组织和一致性。Inline Blot 的设计允许它们在不破坏文档结构的情况下,轻松地添加或修改文本样式。

总之,Inline Blot 在 Quill Parchment 模型中扮演着关键角色,它为文档中的内联元素提供了结构和格式化能力,同时保持了文档内容的流畅性和样式的多样性。

在 Quill Parchment 模型中,"传递" 是指当一个格式化操作被应用到一个 Inline Blot 上,但这个操作对于当前的 Blot 类型不适用或不可能实现时,Parchment 会将这个格式化操作传递给当前 Blot 的子级 Blot。

这种机制允许格式化操作在 Parchment 树中向下流动,直到找到一个可以应用该格式的 Blot。这样做的目的是确保格式化操作能够在正确的位置和正确的元素上应用,即使它们可能跨越多个不同类型的 Blot。

以您提供的例子为例:

假设我们有一个文档,其中包含一个已经应用了加粗格式的 Inline Blot,现在用户想要对这个加粗的文本应用斜体格式。在 Parchment 中,加粗格式可能是通过一个 `BoldBlot` 类实现的,而斜体格式可能是通过一个 `ItalicBlot` 类实现的。

如果用户尝试对 `BoldBlot` 应用斜体格式,但由于 `BoldBlot` 已经处理了加粗格式,它可能不知道如何处理斜体格式。在这种情况下,Parchment 会检查 `BoldBlot` 的子级 Blot,看看是否有任何子级可以处理斜体格式。如果存在可以应用斜体格式的子级 Blot(例如,一个简单的文本节点或另一个 `ItalicBlot`),Parchment 就会将斜体格式化操作应用到这个子级 Blot 上。

这样,加粗的文本现在也会以斜体显示,因为斜体格式已经被成功应用到了正确的子级 Blot 上。这个过程确保了格式化操作的一致性和正确性,即使它们需要在不同类型的 Blot 之间传递。

总结来说,"传递" 机制是 Parchment 处理格式化操作的一种灵活方式,它允许格式化在文档的不同层级中流动和应用,确保了最终的格式化效果符合用户的预期。

Embed Blot


基本实现了一个非文本叶子 Blot,它是可格式化的。其对应的 DOM 节点通常是 Void Element,但也可以是 Normal Element。在这些情况下,Parchment 不会操作或通常不会意识到元素的子元素,并且正确实现 blot 的 index()position() 函数以正确处理光标/选择非常重要。

Scroll


Parchment 文档的根父级 Blot。它不可格式化。

在 Quill Parchment 模型中,Scroll 是一个特殊的 Blot,它代表整个文档的根父级结构。Scroll 作为文档的最顶层容器,负责管理所有的子 Blot,包括块级(Block)Blot、内联级(Inline)Blot 和嵌入(Embed)Blot 等。

Scroll Blot 的特点如下:

  1. 根父级Scroll 是 Parchment 树的根节点,所有的其他 Blot 都是它的直接或间接子节点。它为文档提供了一个统一的起点,使得对文档的所有操作都有一个共同的参照点。
  2. 不可格式化:与文档中的其他 Blot 不同,Scroll Blot 不支持格式化操作。这是因为 Scroll 代表的是文档的整体结构,而不是文档内容的一部分。格式化通常应用于文本或其他内容元素,以改变它们的样式或语义,而 Scroll 作为一个容器,它本身并不包含任何需要格式化的文本或内容。
  3. 文档边界Scroll Blot 定义了文档的边界和视口。在 Web 应用程序中,这通常对应于浏览器窗口中的一个可滚动的容器元素,如 <div><iframe>。用户可以在其中滚动查看文档的全部内容。
  4. 管理子 BlotScroll Blot 负责管理其下的所有子 Blot,包括创建、插入、删除和更新子 Blot。它为文档提供了一个结构化的框架,使得对文档内容的操作可以有序进行。

总的来说,Scroll 在 Parchment 模型中扮演着至关重要的角色,它是文档结构的起点和组织者,确保了文档内容的有序展示和有效管理。由于它不直接参与内容的格式化,因此被设计为不可格式化的 Blot,以避免对文档整体结构造成不必要的干扰。

Attributors


Attributors 是表示格式的另一种更轻量级的方式。它们的 DOM 对应物是 Attribute。就像 DOM 属性与节点的关系一样,Attributors 旨在属于 Blots。在 Inline 或 Block blot 上调用 formats() 将返回相应 DOM 节点表示的格式(如果有的话)以及 DOM 节点的属性表示的格式(如果有的话)。

在 Quill Parchment 模型中,Attributors 提供了一种轻量级的方式来表示和处理文档中的格式。它们是对 DOM 属性的一种抽象,允许 Parchment 以一种更高效和灵活的方式管理格式信息。

以下是 Attributors 的一些关键特点和解释:

  1. 轻量级格式表示:Attributors 是一种替代 Blots 的方式,用于表示文档中的格式。与 Blots 不同,Attributors 不直接代表文档的结构或内容,而是代表与 Blots 相关联的格式信息。这使得它们在处理格式时更加高效,因为它们只关注格式而不是整个节点的内容或结构。
  2. DOM 属性的对应物:在 DOM 中,属性(Attribute)是附加到元素节点上的名称-值对,用于提供有关元素的额外信息。例如,一个 <a> 元素可能有一个 href 属性来指定链接的目标。在 Parchment 中,Attributors 以类似的方式表示这些属性,但它们是作为 Blots 的一部分来管理的。
  3. 属于 Blots:Attributors 旨在与 Blots 结合使用。它们可以附加到 Inline 或 Block Blots 上,为这些 Blots 提供格式信息。当格式化操作发生时,Attributors 可以被添加、修改或删除,以反映 Blot 的格式变化。
  4. formats() 方法:在 Parchment 中,调用一个 Blot 的 formats() 方法将返回与该 Blot 相关的所有格式信息。这包括由 DOM 节点直接表示的格式(例如,一个加粗的 <strong> 元素),以及由 DOM 节点的属性表示的格式(例如,一个设置了 style="color: red;" 的元素)。Attributors 使得 formats() 方法能够返回这些信息,而不需要深入到 DOM 节点的内部结构。

总之,Attributors 在 Quill Parchment 模型中提供了一种灵活且高效的方式来处理文档格式。它们使得格式信息的管理与文档内容的表示分离,从而简化了格式操作的实现,并提高了性能。通过与 Blots 的结合使用,Attributors 为文档的格式化提供了一种强大而轻量级的方法。

在 Quill Parchment 模型中,Attributor 是一个用于管理和应用轻量级格式的类。这些格式通常是通过 DOM 元素的属性来表示的,例如,通过 classstyle 或其他自定义属性。Attributor 类提供了一种机制,允许开发者定义如何将这些属性映射到 Parchment 树中的格式。

Attributors 接口

Attributors 具有以下接口:

class Attributor {
  attrName: string;
  keyName: string;
  scope: Scope;
  whitelist: string[];

  constructor(attrName: string, keyName: string, options: Object = {});
  add(node: HTMLElement, value: string): boolean;
  canAdd(node: HTMLElement, value: string): boolean;
  remove(node: HTMLElement);
  value(node: HTMLElement);
}

在Quill的Parchment模型中,Attributor类是一个基础类,用于定义如何将一个属性添加到HTML元素上。这个类或其子类(如ClassAttributorStyleAttributor)可以用来指定如何在文档中添加、检查、移除和获取特定的属性值。下面详细解释Attributor类的组成部分和方法:

属性

  1. attrName (string): 属性的名称,这是在Quill编辑器中用于引用该属性的名称。
  2. keyName (string): 实际附加到DOM元素上的属性名称。对于StyleAttributor,这将是CSS样式的名称;对于ClassAttributor,这将是类的前缀。
  3. scope (Scope): 属性应用的范围,这决定了属性可以应用于哪些类型的Blot(即Parchment中的基本格式单元)。Scope可以是Scope.BLOTScope.INLINEScope.BLOCKScope.ATTRIBUTE等。
  4. whitelist (string[]): 可选的,定义有效值的白名单。如果定义了,只有列表中的值才会被添加到元素上。

构造函数

  • constructor(attrName: string, keyName: string, options: Object = {}): 在创建Attributor实例时,你需要提供属性名称、键名,以及一个可选的包含额外选项的对象。这个选项对象可以用来设置scopewhitelist

方法

  1. add(node: HTMLElement, value: string): boolean: 将属性添加到指定的节点上。如果属性成功添加,则返回true;否则返回false。这个方法会检查值是否在whitelist中(如果有的话),然后将其添加到节点上。
  2. canAdd(node: HTMLElement, value: string): boolean: 检查是否可以将值添加到节点上。这涉及到检查whitelist以及该属性类型的其他可能限制。
  3. remove(node: HTMLElement): 从节点上移除该属性。具体行为取决于子类的实现,例如,从一个元素上移除一个类或一个样式。
  4. value(node: HTMLElement): 从指定的节点上获取属性值。这个方法的实现会根据属性的类型(类、样式或属性)来获取相应的值。

通过这些方法和属性,Attributor类及其子类为Quill提供了一种灵活的方式来控制编辑器内容的富文本格式。

注意,自定义 Attributors 是实例,而不是像 Blots 那样的类定义。与 Blots 类似,您可能希望使用现有的 Attributor 实现,如基础 Attributor、Class Attributor 或 Style Attributor。

Attributors 的实现出奇地简单,其源代码可能是理解的另一个来源。

Attributor

使用普通属性来表示格式。

import { Attributor, register } from 'parchment';

let Width = new Attributor('width', 'width');
register(Width);

let imageNode = document.createElement('img');

Width.add(imageNode, '10px');
console.log(imageNode.outerHTML); // 将打印 <img width="10px">
Width.value(imageNode); // 将返回 10px
Width.remove(imageNode);
console.log(imageNode.outerHTML); // 将打印 <img>

Class Attributor

使用类名模式来表示格式。在 Quill Parchment 模型中,Class Attributor 是一种特殊的 Attributor,它使用 HTML 元素的 class 属性来表示和管理文档中的格式。Class Attributor 允许开发者定义特定的类名模式,这些模式可以对应于文档中的不同格式,如文本对齐方式、颜色、字体等。

import { ClassAttributor, register } from 'parchment';

let Align = new ClassAttributor('align', 'blot-align');
register(Align);

let node = document.createElement('div');
Align.add(node, 'right');
console.log(node.outerHTML); // 将打印 <div class="blot-align-right"></div>

以下是 Class Attributor 的使用示例和解释:

  1. 导入 ClassAttributor 和 register
    首先,从 'parchment' 模块导入 ClassAttributorregister 方法。ClassAttributor 是用来创建和管理基于类的格式的实例,而 register 方法用于将这个 Attributor 注册到 Parchment 系统中,使其可以被 Parchment 识别和使用。
  2. 创建 Class Attributor 实例
    使用 new ClassAttributor('align', 'blot-align') 创建一个新的 Class Attributor 实例。当你调用new ClassAttributor(name, key, options)来创建一个新的ClassAttributor实例时,你需要提供三个参数:
  • name: 这是属性的名称。在Quill编辑器中使用此名称来引用和应用该属性。
  • key: 这是将被附加到HTML元素上的CSS类的前缀。实际的类名将是key + 属性值。这允许通过CSS对具有此属性的文本应用样式。
  • options (可选): 这是一个对象,可以包含一些额外的配置选项,比如属性的作用域(scope)。
  1. 注册 Class Attributor
    使用 register(Align) 将新创建的 Class Attributor 实例注册到 Parchment 系统中。注册后,Parchment 将能够识别和处理 'blot-align' 格式。
  2. 操作 DOM 元素
    创建一个新的 div 元素,并使用 Align.add(node, 'right') 方法将 'right' 类添加到该元素上。这个方法会在元素的 class 属性中添加或更新 'blot-align-right' 类,从而应用对齐格式。
  3. 查看结果
    使用 console.log(node.outerHTML) 打印出修改后的 DOM 元素的 HTML 字符串。输出将是 </div class="blot-align-right">,这表明 Class Attributor 成功地将对齐格式应用到了 div 元素上。

这意味着,如果你在Quill编辑器中设置了某段文本的对齐方式为右对齐,那么这段文本的HTML元素将获得一个class="ql-align-right"的属性。你可以在CSS中定义.ql-align-right类来控制这些文本的样式,如下所示:

cssCopy code
.ql-align-right {
  text-align: right;
}

这样,所有应用了ql-align-right类的文本都将被设置为右对齐。通过这种方式,ClassAttributor允许你通过CSS类来控制Quill中文本的样式,使样式定义更加灵活和可维护。

Style Attributor

使用内联样式来表示格式。在Quill Parchment模型中,StyleAttributor是用于创建基于内联样式的属性的工具。与ClassAttributor不同,它不是通过添加CSS类来应用样式,而是直接在元素的style属性上设置具体的样式值。这对于一些需要直接映射到具体样式属性的格式化非常有用,例如字体大小、文本颜色等。

StyleAttributor的构造函数接受三个参数:

  1. name: 这是属性的名称,在Quill编辑器中用于引用和应用该属性。这个名字通常是一个简短且描述性的标识符,表示该样式控制的视觉特征,如colorfont等。
  2. key: 这是对应的HTML样式属性名。这个键指明了将要在元素的style属性中设置哪个具体的CSS属性。例如,如果你想控制文本的颜色,这个键可能就是color,对应的CSS属性就是color
  3. options (可选): 一个包含额外配置选项的对象。虽然通常不常用,但它可以提供额外的控制,例如定义属性的作用域(比如是否适用于行内元素或块级元素)。

示例解释

考虑以下示例:new StyleAttributor('color', 'color')。这里:

  • 'color'(第一个参数)是属性名称,在Quill中用来引用和应用颜色属性。
  • 'color'(第二个参数)是HTML样式属性名,指示应该修改元素的哪个样式。在这个例子中,它指示应该修改元素的color样式,这会影响元素的文本颜色。

通过使用这个StyleAttributor,当你在Quill编辑器中设置文本颜色时,它会直接在相应元素上设置style属性,如style="color: #333333;"。这样,你就可以直接在文本上应用颜色样式,而无需定义和应用CSS类。

这种方法的好处是可以直接在元素级别控制样式,而不依赖于外部的CSS类,从而使得样式的应用更为直接和精确。但与此同时,它可能使得样式的复写和全局管理变得更加困难,特别是在需要统一控制编辑器内多个元素样式的情况下。

import { StyleAttributor, register } from 'parchment';

let Align = new StyleAttributor('align', 'text-align', {
  whitelist: ['right', 'center', 'justify'], // 没有值意味着左对齐
});
register(Align);

let node = document.createElement('div');
Align.add(node, 'right');
console.log(node.outerHTML); // 将打印 <div style="text-align: right;"></div>

Registry


所有方法都可以从 Parchment 访问,例如 Parchment.create('bold')。

// 根据名称或 DOM 节点创建一个 blot。
// 当仅给定 scope 时,创建与 scope 同名的 blot。
create(domNode: Node, value?: any): Blot;
create(blotName: string, value?: any): Blot;
create(scope: Scope): Blot;

// 给定 DOM 节点,找到相应的 Blot。
// 冒泡在搜索具有其对应 DOM 节点的子节点的 Embed Blot 时很有用。
find(domNode: Node, bubble: boolean = false): Blot;

// 搜索 Blot 或 Attributor
// 当仅给定 scope 时,找到与 scope 同名的 blot
query(tagName: string, scope: Scope = Scope.ANY): BlotClass;
query(blotName: string, scope: Scope = Scope.ANY): BlotClass;
query(domNode: Node, scope: Scope = Scope.ANY): BlotClass;
query(scope: Scope): BlotClass;
query(attributorName: string, scope: Scope = Scope.ANY): Attributor;

// 注册 Blot 类定义或 Attributor 实例
register(BlotClass | Attributor);

标签:Blot,格式化,详解,文档,格式,Parchment,Quill,属性
From: https://blog.csdn.net/2401_83707780/article/details/137343159

相关文章

  • Lombok常用注解详解: val, @Cleanup, @RequiredArgsConstructor
    From: https://blog.csdn.net/hy6533/article/details/131030094从零开始SpringBoot35:Lombok图源:简书(jianshu.com)Lombok是一个java项目,旨在帮助开发者减少一些“模板代码”。其具体方式是在Java代码生成字节码(class文件)时,根据你添加的相关Lombok注解或类来“自动”添加......
  • GitHub新手用法详解
    GitHub是全球最大的代码托管平台,提供了强大的版本控制和协作功能。无论是个人项目还是团队协作,GitHub都是一个非常实用的工具。本文将为GitHub新手提供一个快速入门指南。基础概念在开始之前,让我们先了解几个基本概念:仓库(Repository):存储项目代码的地方,可以包含文件、文件......
  • NRM详解
    1.nrm是什么nrm(NPMregistrymanager)是npm的镜像源管理工具,使用它可以快速切换npm源。什么意思呢,npm默认情况下是使用npm官方源(使用npmconfigls命令可以查看),在国内用这个源肯定是不靠谱的,一般我们都会用淘宝npm源:https://registry.npm.taobao.org/,修改源的......
  • 【Docker】专题六:Docker Registry 详解
    以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发!欢迎扫码关注个人公众号!目录一、基本介绍二、Registry创建方法三、Registry常用API请求四、Registry镜像清理一、基本介绍笔者在【Docker】专题一:Docker基本架构 中介绍......
  • 大模型中常用的注意力机制GQA详解以及Pytorch代码实现
    分组查询注意力(GroupedQueryAttention)是一种在大型语言模型中的多查询注意力(MQA)和多头注意力(MHA)之间进行插值的方法,它的目标是在保持MQA速度的同时实现MHA的质量。这篇文章中,我们将解释GQA的思想以及如何将其转化为代码。GQA是在论文GQA:TrainingGeneraliz......
  • 详解Assertion desc failed at src/libswscale/swscale_internal.h:668
    目录详解Assertiondescfailedatsrc/libswscale/swscale_internal.h:668错误原因解决方案1.检查输入参数2.升级FFmpeg版本3.检查编译选项4.优化代码5.寻求帮助结论详解Assertiondescfailedatsrc/libswscale/swscale_internal.h:668在使用FFmpeg进行视......
  • IP知识详解
    IP基本认识IP在TCP/IP参考模型中处于第三层,也就是网络层。网络层的主要作用是:实现主机与主机之间的通信,也叫点对点(endtoend)通信。网络层与数据链路层有什么关系呢?IP的作用是主机之间通信用的MAC的作用则是实现「直连」的两个设备之间通信IP则负责在「没有......
  • SSH原理详解
    SSH(SecureShell,安全外壳)是一种网络安全协议,通过加密和认证机制实现安全的访问和文件传输等业务。传统远程登录或文件传输方式,例如Telnet、FTP,使用明文传输数据,存在很多的安全隐患。随着人们对网络安全的重视,这些方式已经慢慢不被接受。SSH协议通过对网络数据进行加密和验证,在不安......
  • 动态规划详解
    动态规划详解动态规划(DynamicProgramming,简称DP)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。在计算机科学中,动态规划是解决优化问题的一个强大工具。......
  • 可视化红黑树详解(gif图演示,洛谷P3369 普通平衡树)
    写在前面推荐一个很实用的工具:红黑树可视化本文参考OIwiki中的红黑树代码,读者也可以参考该篇解析(写得还是很不错的),不过OIWiki里删除后平衡维护的Case4和Case5在代码细节上稍微有些问题(把c......