{
"site": "at://did:plc:uyjvm2kqevlb4pa6sf63476h/site.standard.publication/3mi2kahf6x22y",
"$type": "site.standard.document",
"title": "Lexicons",
"content": {
"$type": "org.blocknote.document#content",
"blocks": [
{
"id": "86c3dfc2-09ec-44d3-a99c-39c381b169f3",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "This post is in reaction to ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"href": "https://bsky.app/profile/pfrazee.com",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "@pfrazee.com",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"text": " here: ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"href": "https://bsky.app/profile/pfrazee.com/post/3mfd4onkpkk2o",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "https://bsky.app/profile/pfrazee.com/post/3mfd4onkpkk2o",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
}
]
},
{
"id": "c7ca1e7a-29f9-4c06-bd2e-db3e8c675201",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "f326cc6c-8640-4ac8-9a0c-ff2ff4286171",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"href": "https://blocknotejs.org",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "BlockNote",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"text": ", is an extensible rich text editor ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"href": "https://www.blocknotejs.org/docs/foundations/document-structure",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "with a structure",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"text": " very similar to what Paul was describing: ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "36e5cbde-ec9d-443b-b651-7e95edbc28e7",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "It is ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"href": "https://www.blocknotejs.org/docs/foundations/schemas",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "extensible",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"text": ", meaning that it can offer the addition of new block types; and, even swapping out of the schema entirely.",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "1e75b676-0927-4f0d-aa66-a46af3054a3f",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "6eba65b4-183d-40f8-b930-5af8959b994d",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "So, given this, there should be a very straightforward mapping from BlockNote’s JSON to a lexicon, so just as a proof of the concept - I made that mapping. This allows a BlockNote document to be represented as a lexicon & convert to and from the format (essentially a 1:1 mapping since they are so similar).",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "93f60a24-5666-49d8-8762-fcd9b3cb8049",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "e7d19121-9e8d-40ca-94d3-55312c008bdf",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "I actually see this lexicon as sort of being the foundation for a new type of rich text editor, which can have community-driven embeds, in a marketplace.",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "d41b916b-d491-438c-8912-6eb704ca58d7",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "b3e3cd6c-9b7e-49b2-b029-2a3309b0ddaf",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "Take a look at this Typepec for BlockNote for more: ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"href": "https://github.com/typespecs/BlockNote/blob/main/lib/main.tsp",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "https://github.com/typespecs/BlockNote/blob/main/lib/main.tsp",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
}
]
},
{
"id": "d115c479-4773-4fab-af90-3b5cf730bc1a",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "52cc9c67-11da-43a4-a8a6-259f24649f32",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "In BlockNote, we de-couple the schema from the document content, this allows us to be agnostic of the implementation of our blocks (content types like paragraphs, code-blocks), while still having a regular structure that we can use to understand the document’s content in a consistent way. Let’s look at an example of the schema that this very document relies on: a paragraph block:",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "ac9521c4-a652-4d32-a357-97d7bfd1628b",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "471727fe-a4dd-478c-92cb-03582c86b17c",
"type": "codeBlock",
"props": {
"language": "typescript"
},
"inlineContent": [
{
"text": "interface ParagraphBlock {\n id: string;\n type: \"paragraph\";\n props:",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"text": " ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {
"textColor": "rgb(225, 228, 232)"
}
},
{
"text": "{\n backgroundColor: string;\n textColor: string;\n textAlignment: \"left\" | \"center\" | \"right\" | \"justify\";\n };\n content: InlineContent[];\n children",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"text": ":",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {
"textColor": "rgb(249, 117, 131)"
}
},
{
"text": " Block[];\n};",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "24167dea-7f8c-4f0f-87b1-70b19ede770f",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "5db8ef4c-01af-404a-acdf-bb4f0b70c2ef",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "Or, more generically:",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "05486797-b6a6-4a2c-95d7-208ca729624f",
"type": "codeBlock",
"props": {
"language": "typescript"
},
"inlineContent": [
{
"text": "type Block = {\n id: string;\n type: string;\n props: Record<string, boolean | number | string>;\n content: InlineContent[] | TableContent | undefined;\n children: Block[];\n};\n\ntype Link = {\n type: \"link\";\n content: StyledText[];\n href: string;\n};\n\ntype StyledText = {\n type: \"text\";\n text: string;\n styles: Styles;\n};\n\ntype CustomInlineContent = {\n type: string;\n content: StyledText[] | undefined;\n props: Record<string, boolean | number | string>;\n};\n\ntype InlineContent = Link | StyledText | CustomInlineContent;\n\n// tables are special cased, for now\ntype TableContent = {\n type: \"tableContent\";\n columnWidths: (number | undefined)[];\n headerRows?: number;\n headerCols?: number;\n rows: {\n cells: TableCell[];\n }[];\n};\n\ntype TableCell = {\n type: \"tableCell\";\n props: {\n backgroundColor: string;\n textColor: string;\n textAlignment: \"left\" | \"center\" | \"right\" | \"justify\";\n colspan?: number;\n rowspan?: number;\n };\n content: InlineContent[];\n};",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "a0eaad57-c079-4633-8a50-1856f1cecf31",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "05c3b60d-96ea-4b13-bab7-7054a91cf282",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "Too abstract? Let’s see a BlockNote document:",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "15e7f7b2-8271-4213-9c21-81652291a2d2",
"type": "codeBlock",
"props": {
"language": "json"
},
"inlineContent": [
{
"text": "[\n {\n \"id\": \"502a74dd-55ba-4637-9e78-9e355fc01469\",\n \"type\": \"paragraph\",\n \"props\": {\n \"backgroundColor\": \"default\",\n \"textColor\": \"default\",\n \"textAlignment\": \"left\"\n },\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Hello world\",\n \"styles\": {}\n }\n ],\n \"children\": []\n },\n {\n \"id\": \"721f2779-fc08-4354-99b6-6031c722cdfe\",\n \"type\": \"heading\",\n \"props\": {\n \"backgroundColor\": \"default\",\n \"textColor\": \"default\",\n \"textAlignment\": \"left\",\n \"level\": 1,\n \"isToggleable\": false\n },\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Heading\",\n \"styles\": {}\n }\n ],\n \"children\": []\n },\n {\n \"id\": \"13a9c876-9809-44c9-8b37-ccba066dad10\",\n \"type\": \"paragraph\",\n \"props\": {\n \"backgroundColor\": \"default\",\n \"textColor\": \"default\",\n \"textAlignment\": \"left\"\n },\n \"content\": [],\n \"children\": []\n }\n]",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
},
{
"id": "d8d1fb3c-2008-4911-b267-ece27f9c89d5",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "dc1fd688-8281-4c4b-ae6c-56b8e82d2f2c",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
},
"inlineContent": [
{
"text": "Want to the see the mapping of this very document? ",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
},
{
"href": "https://pdsls.dev/at://did:plc:uyjvm2kqevlb4pa6sf63476h/site.standard.document/3mi2kahquxs2y",
"type": "link",
"$type": "org.blocknote.schema#link",
"content": [
{
"text": "Head on over to it on pdsls!",
"type": "text",
"$type": "org.blocknote.schema#styledText",
"styles": {}
}
]
}
]
},
{
"id": "e9f16690-269c-46a7-be77-0cce1d3da3d9",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
},
{
"id": "2c8123e7-e0a6-43f4-9300-349c259a6a0a",
"type": "paragraph",
"props": {
"textColor": "default",
"textAlignment": "left",
"backgroundColor": "default"
}
}
]
},
"updatedAt": "2026-03-28T10:41:39.614Z",
"publishedAt": "2026-03-28T10:41:39.614Z",
"textContent": "This post is in reaction to @pfrazee.com here: https://bsky.app/profile/pfrazee.com/post/3mfd4onkpkk2o\nIt is extensible, meaning that it can offer the addition of new block types; and, even swapping out of the schema entirely.\nSo, given this, there should be a very straightforward mapping from BlockNote’s JSON to a lexicon, so just as a proof of the concept - I made that mapping. This allows a BlockNote document to be represented as a lexicon & convert to and from the format (essentially a 1:1 mapping since they are so similar).\nI actually see this lexicon as sort of being the foundation for a new type of rich text editor, which can have community-driven embeds, in a marketplace.\nTake a look at this Typepec for BlockNote for more: https://github.com/typespecs/BlockNote/blob/main/lib/main.tsp\nIn BlockNote, we de-couple the schema from the document content, this allows us to be agnostic of the implementation of our blocks (content types like paragraphs, code-blocks), while still having a regular structure that we can use to understand the document’s content in a consistent way. Let’s look at an example of the schema that this very document relies on: a paragraph block:\ninterface ParagraphBlock {\n id: string;\n type: \"paragraph\";\n props: {\n backgroundColor: string;\n textColor: string;\n textAlignment: \"left\" | \"center\" | \"right\" | \"justify\";\n };\n content: InlineContent[];\n children: Block[];\n};\nOr, more generically:\ntype Block = {\n id: string;\n type: string;\n props: Record<string, boolean | number | string>;\n content: InlineContent[] | TableContent | undefined;\n children: Block[];\n};\n\ntype Link = {\n type: \"link\";\n content: StyledText[];\n href: string;\n};\n\ntype StyledText = {\n type: \"text\";\n text: string;\n styles: Styles;\n};\n\ntype CustomInlineContent = {\n type: string;\n content: StyledText[] | undefined;\n props: Record<string, boolean | number | string>;\n};\n\ntype InlineContent = Link | StyledText | CustomInlineContent;\n\n// tables are special cased, for now\ntype TableContent = {\n type: \"tableContent\";\n columnWidths: (number | undefined)[];\n headerRows?: number;\n headerCols?: number;\n rows: {\n cells: TableCell[];\n }[];\n};\n\ntype TableCell = {\n type: \"tableCell\";\n props: {\n backgroundColor: string;\n textColor: string;\n textAlignment: \"left\" | \"center\" | \"right\" | \"justify\";\n colspan?: number;\n rowspan?: number;\n };\n content: InlineContent[];\n};\nToo abstract? Let’s see a BlockNote document:\n[\n {\n \"id\": \"502a74dd-55ba-4637-9e78-9e355fc01469\",\n \"type\": \"paragraph\",\n \"props\": {\n \"backgroundColor\": \"default\",\n \"textColor\": \"default\",\n \"textAlignment\": \"left\"\n },\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Hello world\",\n \"styles\": {}\n }\n ],\n \"children\": []\n },\n {\n \"id\": \"721f2779-fc08-4354-99b6-6031c722cdfe\",\n \"type\": \"heading\",\n \"props\": {\n \"backgroundColor\": \"default\",\n \"textColor\": \"default\",\n \"textAlignment\": \"left\",\n \"level\": 1,\n \"isToggleable\": false\n },\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Heading\",\n \"styles\": {}\n }\n ],\n \"children\": []\n },\n {\n \"id\": \"13a9c876-9809-44c9-8b37-ccba066dad10\",\n \"type\": \"paragraph\",\n \"props\": {\n \"backgroundColor\": \"default\",\n \"textColor\": \"default\",\n \"textAlignment\": \"left\"\n },\n \"content\": [],\n \"children\": []\n }\n]\nWant to the see the mapping of this very document? Head on over to it on pdsls!"
}