@ atjson/ 文件
该文件是AtJSON的核心组成部分. 它是一个库,提供创建注释和文档的工具,查询它们,并在它们之间转换. 我们在这里走过,描述如何使用AtJSON.
说明简介
说明是写作和技术中都使用的一个术语. 书面说明是信息丰富的一页上的标记。 它们可以是复制编辑的笔记,也可以是规定修改文本的简称. 软件系统利用它们在现有数据中添加额外的上下文信息.
当我们在AtJSON中提及说明时,我们主要是指软件定义. 我们正在标出案文的范围,为案文/文件增加更有意义的信息。 让AtJSON有一点不同之处 就是我们如何看待说明.
通常在处理文本时,我们会想到标记语言,如HTML,XML,和标记下. AtJSON可以口出标记并用说明来表示. 需要注意的重要特征是,它并不区分不同类型的加价. 这是一个灵活而强大的基础,因为它使我们能够以不同格式无缝地转换和操纵说明,仿佛它们是相同的格式.
举例来说,下面的标记式文件:
_Roses_ are red,
_Violets_ are blue.
可以被解析成AtJSON文件,通过将其传递到AtJSON的一个源. 来源有点像解析器,但被称为源,因为他们使用解析器,通常我们不会在源中进行任何解析. 在这里,我们使用AtJSON的内置的Commonmark source,这是一种文档格式,支持CommonMark spec中指定的所有标记下特性.
import CommonmarkSource from "@atjson/source-commonmark";
CommonmarkSource.fromRaw("*Roses* are red, \n*Violets* are blue.");
结果是下标文档的逻辑表达:
{
"content": "*Roses* are red, \n*Violets* are blue.",
"annotations": [
{
"type": "-commonmark-em",
"start": 0,
"end": 7,
"attributes": {}
},
{
"type": "-atjson-parse-token",
"start": 0,
"end": 1,
"attributes": {
"-atjson-reason": "em_open"
}
},
{
"type": "-atjson-parse-token",
"start": 6,
"end": 7,
"attributes": {
"-atjson-reason": "em_close"
}
},
{
"type": "-commonmark-hard_break",
"start": 16,
"end": 19,
"attributes": {}
},
{
"type": "-commonmark-em",
"start": 20,
"end": 29,
"attributes": {}
},
{
"type": "-atjson-parse-token",
"start": 20,
"end": 21,
"attributes": {
"-atjson-reason": "em_open"
}
},
{
"type": "-atjson-parse-token",
"start": 28,
"end": 29,
"attributes": {
"-atjson-reason": "em_close"
}
}
]
}
页:1
At JSON 存有销售商前缀的说明. 其目的是防止不同类型的文件相撞.
位置表示 * 字符之间的位置,而不是字符边界。 这意味着
{ start: 0, end: 1 }超过内容的第一个字符.
一旦降分在AtJSON,我们可以开始修改文档.
页:1
我们跳过一个直接使用AtJSON的例子,但让我们回溯一下来解释AtJSON的另一个核心概念. 说明不能活在乙醚中 - 他们需要的东西锁定。 所以我们把它们附在一份文件上。 文件是内容+说明的组合. 内容, 为我们的目的, 文本,和说明 是一堆关于文本的信息.
上面,JSONblob是原始的看文件.
文档将注释类联系起来,将JSON变成一个无需供应商前缀即可访问的全注释类.
作为文档的入门,让我们创建一个小文档定义,描述地址:
import Document, { InlineAnnotation } from "@atjson/document";
class Name extends InlineAnnotation {
static vendorPrefix = "address";
static type = "name";
}
class AddressLine extends InlineAnnotation {
static vendorPrefix = "address";
static type = "line";
}
class PostalCode extends InlineAnnotation {
static vendorPrefix = "address";
static type = "postal-code";
}
class City extends InlineAnnotation {
static vendorPrefix = "address";
static type = "city";
}
class Region extends InlineAnnotation {
static vendorPrefix = "address";
static type = "region";
}
class Address extends Document {
static schema = [Name, AddressLine, PostalCode, City, Region];
}
这似乎是一个奇怪的例子,但如果我们调出我们的地址 康德纳斯特的纽约办公室:
Condé Nast
1 WTC
New York, NY 10006
我们可以开始标注一些说明:
let address = new Address({
content: "Condé Nast\n1 WTC\nNew York, NY 10006",
annotations: [],
});
address.addAnnotations(
new Name({ start: 0, end: 10 }),
new AddressLine({ start: 11, end: 16 }),
new City({ start: 17, end: 25 }),
new Region({ start: 27, end: 29 }),
new PostalCode({ start: 30, end: 35 })
);
这样存储数据似乎很武断. 我们为什么要这么做?
我们认为这为人们提供了最自然的输入机制, 同时提供了强大的机器读取能力。 文档提供了管理说明的工具,因此当文本被添加或删除时,它会像预期的那样"只是工作". 因此,如果我们想在这里修改文本,我们在"Condé Nast"后插入了"娱乐",说明会保持完整,事实上会覆盖正确的文本!
这里的灵活性也意味着我们可以把这个地址变成更适合谷歌的东西,例如JSONLD. 我们可以利用AtJSON在这里的渲染来取出这个文件,并把它变成一个可以显示搜索结果中丰富的位置卡的东西. 请注意,为了做到这一点,我们定义了一个渲染规则,用于我们迄今为地址计划定义的每一条注释:
import Renderer from "@atjson/renderer-hir";
class JSONLDRenderer extends Renderer {
private jsonld: any;
constructor() {
this.jsonld = {
"@context": "https://schema.org",
"@type": "Place",
address: {
"@type": "PostalAddress",
},
};
}
*Name() {
let name = yield;
this.jsonld.name = name.join("");
}
*AddressLine() {
let streetAddress = yield;
this.jsonld.address.streetAddress = streetAddress.join("");
}
*City() {
let addressLocality = yield;
this.jsonld.address.addressLocality = addressLocality.join("");
}
*Region() {
let addressRegion = yield;
this.jsonld.address.addressRegion = addressRegion.join("");
}
*PostalCode() {
let postalCode = yield;
this.jsonld.address.postalCode = postalCode.join("");
}
*root() {
yield;
return this.jsonld;
}
}
发送我们通过此程序创建的文档将生成一个 JSON-LD 对象:
{
"@context": "https://schema.org",
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressLocality": "New York",
"addressRegion": "NY",
"postalCode": "10006"
},
"name": "Condé Nast"
}
这有点像旋风,但我们认为它提供了一个很好的例子,你可以开始思考如何使用说明!
页:1
我们称定义的文件计划为"源". 他们并不是完全的解析者,因为他们以这种格式代表了AtJSON中的内容. 我认为他们是一个记者拥有的来源,他们从该来源收集信息,并在他们的报道中使用这些信息.
++ 如何在文档中查找数据
AtJSON中的说明可以像一个小数据库一样处理. 这有点像JQuery突然打开了 在网站上可以做什么的可能性 因为你可以做简单而优雅的操控.
对文档的查询有2个层次. 第一个是部分匹配:
doc.where({ type: "-offset-link" });
此查询将在文档中找到所有链接
页:1
部分匹配查询语言需要供应商前缀
使用函数语法的等同版本是:
import { Link } from "@atjson/offset-annotations";
doc.where((annotation) => annotation instanceof Link);
页:1
函数语法返回水合注解. 您可能在这里遇到未知的注释, 这些注释是文档计划不支持的 。 小心点
关于未知说明的QQA 注释
AtJSON从不删除或删除数据. 相反,它没有得到文件的支持或理解. 如果一个特性停止使用,或从遗留系统迁移,我们可以选择忽略它,同时保留数据.
此数据被存储为未知的注释,这是将所有注释信息存储在属性散列中的注释. 被序列化到JSON时,它们看起来像是原始的注释,但在渲染它们时被忽略了.
{
"type": "-html-marquee",
"start": 0,
"left": 10,
"attributes": {
"-html-style": "rainbow"
}
}
变为:
new UnknownAnnotation({
start: 0,
end: 10,
attributes: {
type: "-html-marquee",
attributes: {
"-html-style": "rainbow",
},
},
});