-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b6f3de5
commit fd39ec6
Showing
22 changed files
with
1,810 additions
and
5,053 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,63 @@ | ||
{ | ||
"name": "package_name", | ||
"version": "0.0.0", | ||
"description": "package_description", | ||
"keywords": [ | ||
"typescript", | ||
"prismic" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "ssh://git@github.com/github_org_slash_github_repo.git" | ||
}, | ||
"license": "Apache-2.0", | ||
"author": "Prismic <contact@prismic.io> (https://prismic.io)", | ||
"type": "module", | ||
"exports": { | ||
".": { | ||
"require": "./dist/index.cjs", | ||
"import": "./dist/index.mjs" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"scripts": { | ||
"build": "siroc build", | ||
"dev": "siroc build --watch", | ||
"format": "prettier --write .", | ||
"prepare": "npm run build", | ||
"release": "yarn build && yarn test && standard-version && git push --follow-tags && yarn build && npm publish", | ||
"release:dry": "standard-version --dry-run", | ||
"release:alpha": "yarn build && yarn test && standard-version --release-as major --prerelease alpha && git push --follow-tags && yarn build && npm publish --tag alpha", | ||
"release:alpha:dry": "standard-version --release-as major --prerelease alpha --dry-run", | ||
"lint": "eslint --ext .js,.ts .", | ||
"unit": "nyc --reporter=lcovonly --reporter=text --exclude-after-remap=false ava", | ||
"test": "yarn lint && yarn unit" | ||
}, | ||
"devDependencies": { | ||
"@typescript-eslint/eslint-plugin": "^4.26.1", | ||
"@typescript-eslint/parser": "^4.26.1", | ||
"ava": "^3.15.0", | ||
"eslint": "^7.28.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.3.1", | ||
"siroc": "^0.11.0", | ||
"standard-version": "^9.3.0", | ||
"ts-eager": "^2.0.2", | ||
"typescript": "^4.3.2" | ||
}, | ||
"engines": { | ||
"node": ">=12.7.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
"name": "@prismicio/richtext", | ||
"version": "0.0.0", | ||
"description": "Convert Rich Text raw data to a generic tree for serialization", | ||
"keywords": [ | ||
"typescript", | ||
"prismic" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "ssh://git@github.com/prismicio/prismic-richtext.git" | ||
}, | ||
"license": "Apache-2.0", | ||
"author": "Prismic <contact@prismic.io> (https://prismic.io)", | ||
"type": "module", | ||
"exports": { | ||
".": { | ||
"require": "./dist/index.cjs", | ||
"import": "./dist/index.mjs" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"scripts": { | ||
"build": "siroc build", | ||
"dev": "siroc build --watch", | ||
"format": "prettier --write .", | ||
"prepare": "npm run build", | ||
"release": "npm run build && npm run test && standard-version && git push --follow-tags && npm run build && npm publish", | ||
"release:dry": "standard-version --dry-run", | ||
"release:alpha": "npm run build && npm run test && standard-version --release-as major --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha", | ||
"release:alpha:dry": "standard-version --release-as major --prerelease alpha --dry-run", | ||
"lint": "eslint --ext .js,.ts .", | ||
"unit": "nyc --reporter=lcovonly --reporter=text --exclude-after-remap=false ava", | ||
"test": "npm run lint && npm run unit" | ||
}, | ||
"devDependencies": { | ||
"@typescript-eslint/eslint-plugin": "^4.26.1", | ||
"@typescript-eslint/parser": "^4.26.1", | ||
"ava": "^3.15.0", | ||
"eslint": "^7.28.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.3.1", | ||
"siroc": "^0.11.0", | ||
"standard-version": "^9.3.0", | ||
"ts-eager": "^2.0.2", | ||
"typescript": "^4.3.2" | ||
}, | ||
"engines": { | ||
"node": ">=12.7.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { RTNode } from "./types"; | ||
|
||
export function asText(nodes: RTNode[], separator = " "): string { | ||
return nodes | ||
.map((node) => { | ||
if ("text" in node) { | ||
return node.text; | ||
} | ||
}) | ||
.filter(Boolean) | ||
.join(separator); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,198 +1,7 @@ | ||
import { uuid } from "./lib/uuid"; | ||
import { | ||
NodeType, | ||
RTListGroupItemNode, | ||
RTNode, | ||
RTSpanNode, | ||
RTTextNode, | ||
Tree, | ||
TreeNode, | ||
} from "./types"; | ||
export { asText } from "./asText"; | ||
export { toTree } from "./toTree"; | ||
|
||
function textNodeSpansToTreeNodeChildren( | ||
spans: RTSpanNode[] = [], | ||
node: RTTextNode, | ||
parentSpan?: RTSpanNode, | ||
): TreeNode[] { | ||
if (spans.length < 1) { | ||
return [createTextTreeNode(node.text)]; | ||
} | ||
export { serialize } from "./serialize"; | ||
export type { Serializer } from "./serialize"; | ||
|
||
const children: TreeNode[] = []; | ||
|
||
for (let i = 0; i < spans.length; i++) { | ||
const span = spans[i]; | ||
const spanStart = span.start - (parentSpan?.start || 0); | ||
const spanEnd = span.end - (parentSpan?.start || 0); | ||
|
||
const childSpans: RTSpanNode[] = []; | ||
for (let j = 0; j < spans.length; j++) { | ||
const siblingSpan = spans[j]; | ||
|
||
if ( | ||
siblingSpan !== span && | ||
siblingSpan.start >= span.start && | ||
siblingSpan.end <= span.end | ||
) { | ||
childSpans.push(siblingSpan); | ||
spans.splice(j, 1); | ||
j = -1; | ||
} | ||
} | ||
|
||
if (i === 0 && spanStart > 0) { | ||
children.push(createTextTreeNode(node.text.slice(0, spanStart))); | ||
} | ||
|
||
children.push( | ||
createTreeNode( | ||
span, | ||
textNodeSpansToTreeNodeChildren( | ||
childSpans, | ||
{ | ||
...node, | ||
text: node.text.slice(spanStart, spanEnd), | ||
}, | ||
span, | ||
), | ||
), | ||
); | ||
|
||
if (spanEnd < node.text.length) { | ||
const nextSpan: RTSpanNode | undefined = spans[i + 1]; | ||
|
||
if (nextSpan) { | ||
const nextSpanStart = nextSpan.start - (parentSpan?.start || 0); | ||
children.push( | ||
createTextTreeNode(node.text.slice(spanEnd, nextSpanStart)), | ||
); | ||
} else { | ||
children.push(createTextTreeNode(node.text.slice(spanEnd))); | ||
} | ||
} | ||
} | ||
|
||
return children; | ||
} | ||
|
||
function nodeToTreeNode(node: RTNode): TreeNode { | ||
if ("text" in node) { | ||
return createTreeNode( | ||
node, | ||
textNodeSpansToTreeNodeChildren(node.spans, node), | ||
); | ||
} | ||
|
||
if ("listItems" in node) { | ||
return createTreeNode(node, node.listItems.map(nodeToTreeNode)); | ||
} | ||
|
||
return createTreeNode(node); | ||
} | ||
|
||
function prepareNodes(nodes: RTNode[]): RTNode[] { | ||
const mutNodes = [...nodes]; | ||
|
||
for (let i = 0; i < mutNodes.length; i++) { | ||
const node = mutNodes[i]; | ||
|
||
if ( | ||
node.type === NodeType.LIST_ITEM || | ||
node.type === NodeType.ORDERED_LIST_ITEM | ||
) { | ||
const childItems: RTListGroupItemNode[] = [node as RTListGroupItemNode]; | ||
|
||
while ( | ||
mutNodes[i + 1] && | ||
(mutNodes[i + 1].type === NodeType.LIST_ITEM || | ||
mutNodes[i + 1].type === NodeType.ORDERED_LIST_ITEM) | ||
) { | ||
childItems.push(mutNodes[i + 1] as RTListGroupItemNode); | ||
mutNodes.splice(i, 1); | ||
} | ||
|
||
mutNodes[i] = { | ||
type: | ||
node.type === NodeType.LIST_ITEM | ||
? NodeType.LIST | ||
: NodeType.ORDERED_LIST, | ||
listItems: childItems, | ||
}; | ||
} | ||
} | ||
|
||
return mutNodes; | ||
} | ||
|
||
export function toTree(nodes: RTNode[]): Tree { | ||
const preparedNodes = prepareNodes(nodes); | ||
|
||
return { | ||
key: uuid(), | ||
children: preparedNodes.map((node) => nodeToTreeNode(node)), | ||
}; | ||
} | ||
|
||
function createTreeNode( | ||
node: RTNode | RTSpanNode, | ||
children: TreeNode[] = [], | ||
): TreeNode { | ||
return { | ||
key: uuid(), | ||
type: node.type, | ||
text: "text" in node ? node.text : undefined, | ||
node, | ||
children, | ||
}; | ||
} | ||
|
||
function createTextTreeNode(text: string): TreeNode { | ||
return createTreeNode({ | ||
type: NodeType.SPAN, | ||
text, | ||
}); | ||
} | ||
|
||
export function asText(nodes: RTNode[]): string { | ||
return nodes | ||
.map((node) => { | ||
if ("text" in node) { | ||
return node.text; | ||
} | ||
}) | ||
.filter(Boolean) | ||
.join("\n"); | ||
} | ||
|
||
export type Serializer<T> = ( | ||
type: NodeType, | ||
node: RTNode | RTSpanNode, | ||
text: string | undefined, | ||
children: T[], | ||
key: string, | ||
) => T; | ||
|
||
export function serialize<T>(nodes: RTNode[], serializer: Serializer<T>): T[] { | ||
const tree = toTree(nodes); | ||
|
||
return serializeTreeNodes(tree.children, serializer); | ||
} | ||
|
||
function serializeTreeNodes<T>( | ||
nodes: TreeNode[], | ||
serializer: Serializer<T>, | ||
): T[] { | ||
return nodes.map((node) => { | ||
return serializeTreeNode(node, serializer); | ||
}); | ||
} | ||
|
||
function serializeTreeNode<T>(node: TreeNode, serializer: Serializer<T>): T { | ||
return serializer( | ||
node.type, | ||
node.node, | ||
node.text, | ||
serializeTreeNodes(node.children, serializer), | ||
node.key, | ||
); | ||
} | ||
export { NodeType, HyperlinkType, HyperlinkMediaKind } from "./types"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,5 @@ interface UUIDFn { | |
export const uuid: UUIDFn = (): string => { | ||
return (++uuid.i).toString(); | ||
}; | ||
|
||
uuid.i = 0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { NodeType, RTNode, RTSpanNode, TreeNode } from "./types"; | ||
import { toTree } from "./toTree"; | ||
|
||
export type Serializer<T> = ( | ||
type: NodeType, | ||
node: RTNode | RTSpanNode, | ||
text: string | undefined, | ||
children: T[], | ||
key: string, | ||
) => T; | ||
|
||
export function serialize<T>(nodes: RTNode[], serializer: Serializer<T>): T[] { | ||
const tree = toTree(nodes); | ||
|
||
return serializeTreeNodes(tree.children, serializer); | ||
} | ||
|
||
function serializeTreeNodes<T>( | ||
nodes: TreeNode[], | ||
serializer: Serializer<T>, | ||
): T[] { | ||
return nodes.map((node) => { | ||
return serializeTreeNode(node, serializer); | ||
}); | ||
} | ||
|
||
function serializeTreeNode<T>(node: TreeNode, serializer: Serializer<T>): T { | ||
return serializer( | ||
node.type, | ||
node.node, | ||
node.text, | ||
serializeTreeNodes(node.children, serializer), | ||
node.key, | ||
); | ||
} |
Oops, something went wrong.