Awesome
Notion Abstract Syntax Tree.
by Notion Tweet.
ntast is a specification for representing Notion contents as abstract syntax trees. It implements the unist specification. It can represent different types of pages in Notion: Page, Table, Board, List, Calendar, Gallery, and Timeline.
Contents
Introduction
This document defines a format, written in TypeScript, for representing Notion contents as abstract syntax trees.
Where this specification fits
ntast extends unist, a format for syntax trees, to benefit from its ecosystem of utilities, unified, and unified ecosystem.
ntast relates to Notion in that it enables reading from, applying transformations, and writing to Notion. It has a set of utilities to transform between ntast syntax trees and Notion API schemas.
ntast relates to JavaScript in that it has an ecosystem of utilities for working with compliant syntax trees in JavaScript. However, ntast is not limited to JavaScript and can be used in other programming languages.
What this specification isn't about
ntast focuses on only content and doesn't work with Notion-application data, such as Workspaces, Accounts, Members, Permissions, and similar settings. Ecosystem plugins may extend functionalities for these data using Notion API.
Nodes
Block
interface Block extends UnistNode {
id: string;
}
Block (UnistNode) represents a node in ntast and a content block in Notion.
Each block has a unique id
.
Example:
{
id: "b3e6e681-2eaa-4f1a-89c4-dde7f7f7a167",
type: "text",
};
Parent
interface Parent extends UnistParent {
children: Block[];
}
Parent (UnistParent) represents a node in ntast containing other nodes (said to be children).
Its children
are limited to only Block(s).
Literal
interface Literal extends UnistLiteral {
value: Value[];
}
Literal (UnistLiteral) represents a node in ntast containing a value.
Its value
is an ordered list of Value object(s).
Page
interface Page extends Block, Parent, Literal {
type: "page";
icon?: string;
cover?: string;
}
Page represents a Page
in Notion.
A page can be the root of a tree or a child of another page (known as a sub-page in Notion).
<p align="left"><img height="128" src="images/subpage-0.png"></p>Example:
<p align="left"><img height="32" src="images/subpage-1.png"></p>Yields:
{
id: "b3e6e681-2eaa-4f1a-89c4-dde7f7f7a167",
type: "page",
value: [["This is a subpage"]],
icon: "☺️",
children: [],
};
Text
interface Text extends Block, Literal {
type: "text";
}
Text represents a Text
block in Notion.
Example:
<p align="left"><img height="32" src="images/text-1.png"></p>Yields:
{
id: "333f9503-77f2-45b3-92df-89e2094fb354",
type: "text",
value: [
["Tools you're familiar with will just work: "],
["bold", [["b"]]],
[", "],
["italic", [["i"], ["b"]]],
[", "],
["strikethrough", [["s"]]],
[", "],
["code", [["c"]]],
[", and more."],
],
};
ToDo
interface ToDo extends Block, Literal {
type: "to_do";
checked: boolean;
}
ToDo represents a To-do list
block in Notion.
Example:
<p align="left"><img height="32" src="images/todo-1.png"></p> <p align="left"><img height="32" src="images/todo-2.png"></p>Yields:
[
{
id: "8b3cfeed-c0da-451e-8f18-f7086c321979",
type: "to_do",
value: [["This is a "], ["todo", [["b"]]], [" item."]],
},
{
id: "8b3cfeed-c0da-451e-8f18-f7086c321979",
type: "to_do",
value: [["This is a "], ["todo", [["b"]]], [" item."]],
checked: true,
},
];
Heading1
interface Heading1 extends Block, Literal {
type: "header";
}
Heading1 represents a Heading 1
block in Notion.
Example:
<p align="left"><img height="48" src="images/h1-1.png"></p>Yields:
{
id: "f694bbd6-8fa4-44d4-b02c-ad05128fb277",
type: "header",
value: [["This is heading 1"]],
};
Heading2
interface Heading2 extends Block, Literal {
type: "sub_header";
}
Heading2 represents a Heading 2
block in Notion.
Example:
<p align="left"><img height="38" src="images/h2-1.png"></p>Yields:
{
id: "f694bbd6-8fa4-44d4-b02c-ad05128fb277",
type: "sub_header",
value: [["This is heading 2"]],
};
Heading3
interface Heading3 extends Block, Literal {
type: "sub_sub_header";
}
Heading3 represents a Heading 3
block in Notion.
Example:
<p align="left"><img height="28" src="images/h3-1.png"></p>Yields:
{
id: "f694bbd6-8fa4-44d4-b02c-ad05128fb277",
type: "sub_sub_header",
value: [["This is heading 3"]],
};
BulletedList
interface BulletedList extends Block, Literal, Parent {
type: "bulleted_list";
}
BulletedList represents a Bulleted list
block in
Notion. It can have children.
Example:
<p align="left"><img height="110" src="images/ul-1.png"></p>Yields:
[
{
id: "dd130b72-3d53-42ea-bf3b-45e95c8e8c2d",
type: "bulleted_list",
value: [
["Heading 1", [["c"]]],
[": The largest heading, can be easily added with shortcut "],
["/h1", [["c"]]],
["."],
],
children: [],
},
{
id: "093db819-617f-47b0-b776-48abf0ff2792",
type: "bulleted_list",
value: [
["Heading 2", [["c"]]],
[": The medium-sized heading, can be easily added with shortcut "],
["/h2", [["c"]]],
["."],
],
children: [],
},
{
id: "b7d35804-e262-4d99-b039-8372470262f6",
type: "bulleted_list",
value: [
["Heading 3", [["c"]]],
[": The smallest heading, can be easily added with shortcut "],
["/h3", [["c"]]],
["."],
],
children: [],
},
];
NumberedList
interface NumberedList extends Block, Literal, Parent {
type: "numbered_list";
}
NumberedList represents a Numbered list
block in
Notion. It can have children.
Example:
<p align="left"><img height="110" src="images/ol-1.png"></p>Yields:
[
{
id: "a405f18e-978e-4c80-9055-1def35f84b47",
type: "numbered_list",
value: [["This is an item"]],
children: [],
},
{
id: "385a10b8-f1fa-49b0-a704-02a109c92953",
type: "numbered_list",
value: [["This is the second item"]],
children: [],
},
{
id: "8c6225e1-78b1-4e8d-b658-adc6e2b045ea",
type: "numbered_list",
value: [["This is the third item"]],
children: [],
},
];
ToggleList
interface ToggleList extends Block, Literal, Parent {
type: "toggle";
}
ToggleList represents a Toggle list
block in
Notion. It can have children.
Example:
<p align="left"><img height="64" src="images/toggle-1.png"></p>Yields:
{
id: "edf810ae-1684-491d-a6c1-673ad2d3fc57",
type: "toggle",
value: [["This is a "], ["toggle", [["b"]]], [" "], ["list", [["i"]]]],
children: [
{
id: "689aa04d-d448-48b2-93fa-edbcc93c34d8",
type: "text",
value: [["This is a child block."]],
},
],
};
Quote
interface Quote extends Block, Literal {
type: "quote";
}
Quote represents a Quote
block in Notion.
Example:
<p align="left"><img height="32" src="images/quote-1.png"></p>Yields:
{
id: "d3a9da64-26e3-44b3-a22a-99a6b02880d3",
type: "quote",
value: [
[
'"The way to get started is to quit talking and begin doing." - Walt Disney',
],
],
};
Divider
interface Divider extends Block {
type: "divider";
}
Divider represents a Divider
block in Notion. It
has no content.
Yields:
{
id: "95ee567a-527f-4020-aa6a-e4c170de031c",
type: "divider",
};
LinkToPage
type LinkToPage = Page;
LinkToPage represents a Link to page
block in
Notion. It is an alias to Page.
Callout
interface Callout extends Block, Literal {
type: "callout";
icon: string;
color: Color;
}
Callout represents a Callout
block in Notion.
Example:
<p align="left"><img height="64" src="images/callout-1.png"></p>Yields:
{
id: "5cc11b17-3ee0-4f09-8cca-659e56851db7",
type: "callout",
value: [["Please read this first"]],
icon: "💡",
color: "gray_background",
};
Image
interface Image extends Block {
type: "image";
source: string[][];
}
Image represents a Image
block in Notion.
Example:
<p align="left"><img height="128" src="images/image-1.png"></p> <p align="left"><img height="128" src="images/image-2.png"></p>Yields:
[
{
id: "8b3cfeed-c0da-451e-8f18-f7086c321979",
type: "image",
source: [
[
"https://cdn.iconscout.com/icon/free/png-256/notion-1693557-1442598.png",
],
],
},
];
Content formats
Value
type Value = TextValue | ReferenceValue | EquationValue;
Value represents an inline literal in Notion, which can be either text, or reference, or equation.
TextValue
type TextValue = [string, TextFormat[]?];
type TextFormat =
| BoldFormat
| ItalicFormat
| StrikethroughFormat
| CodeFormat
| UnderlineFormat
| LinkFormat
| HighlightFormat;
type BoldFormat = ["b"];
type ItalicFormat = ["i"];
type StrikethroughFormat = ["s"];
type CodeFormat = ["c"];
type UnderlineFormat = ["_"];
type LinkFormat = ["a", string];
type HighlightFormat = ["h", Color];
type Color =
| "gray"
| "brown"
| "orange"
| "yellow"
| "teal"
| "blue"
| "purple"
| "pink"
| "red"
| "gray_background"
| "brown_background"
| "orange_background"
| "yellow_background"
| "teal_background"
| "blue_background"
| "purple_background"
| "pink_background"
| "red_background";
TextValue represents a text literal in Notion, which can have styling options.
Example:
<p align="left"><img height="64" src="images/format-0.png"></p>Yields:
[
["All the usual shortcuts apply, like "],
["cmd/ctrl", [["c"]]],
[" + "],
["b", [["c"]]],
[" for "],
["bold", [["b"]]],
[" and "],
["cmd/ctrl", [["c"]]],
[" + "],
["shift", [["c"]]],
[" + "],
["s", [["c"]]],
[" for "],
["strikethrough", [["s"]]],
[". Our shortcuts for writing live "],
[
"here",
[
[
"a",
"https://notion.so/notion/Keyboard-Markdown-Shortcuts-66e28cec810548c3a4061513126766b0",
],
["h", "red"],
],
],
[" ✂️ But we've thrown in a couple others."],
];
ReferenceValue
type ReferenceValue = ["‣", ReferenceFormat[]?];
type ReferenceFormat = UserFormat | PageFormat | DateFormat;
type UserFormat = ["u", string];
type PageFormat = ["p", string];
type DateFormat = [
"d",
{
type: "date" | "daterange";
start: string;
end?: string;
format?: string;
}
];
ReferenceValue represents a reference literal in Notion.
Example:
<p align="left"><img height="64" src="images/format-1.png"></p>Yields:
[
// Others...
[", page "],
["‣", [["p", "57dcb2ae-4528-4939-8207-9ed5d1e01809"]]],
[", user "],
["‣", [["u", "62e85506-1758-481a-92b1-73984a903451"]]],
[" and even date "],
[
"‣",
[
[
"d",
{
type: "date",
start_date: "2021-02-18",
date_format: "relative",
},
],
],
],
["."],
];
EquationValue
type EquationValue = ["⁍", EquationFormat[]?];
type EquationFormat = ["e", string];
EquationValue represent an equation literal in Notion.
Example:
<p align="left"><img height="64" src="images/format-1.png"></p>Yields:
[
["You can embed inline equation "],
["⁍", [["e", "e = mc^2"]]],
// Others...
];
Acknowledgements
ntast is created and maintained by the creator of Notion Tweet.
Notion Tweet is a tool that enables writing, scheduling, and automating your tweets 10x easier and faster, directly in Notion.
Special thanks to @wooorm for his work on unist, mdast, and unified, by which this project is heavily inspired.