This repository was archived by the owner on Feb 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 131
/
Copy pathmdx.js
100 lines (94 loc) · 2.94 KB
/
mdx.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { DOCS_CONTENT_URL } from "helpers/documentation";
export const extractTextFromAst = (ast) =>
ast.children
.flatMap(handleNode)
.join("")
.trim();
const handleNode = (astNode) => {
const children = astNode.children
? astNode.children.flatMap(handleNode).join("")
: "";
switch (astNode.type) {
case "text":
return astNode.value;
case "paragraph":
return `${children} `;
case "heading":
return "";
default:
return children;
}
};
const DESCRIPTION_LENGTH = 160;
export const getDescriptionFromAst = (ast) => {
// slice the string at the description length + some padding, so we're not
// processing a massive amount of text we know won't be used.
// We want to truncate at a word boundary, so split the string and
// concatenate until we go over the limit. If the last word is SUPER long (like
// a URL) we'll end up blowing the limit by a lot, but most of the time it'll
// be fine.
const bodyText = extractTextFromAst(ast).slice(0, DESCRIPTION_LENGTH * 1.5);
const bodyWords = bodyText.split(" ");
return bodyWords.reduce((accum, word) => {
if (accum.length > DESCRIPTION_LENGTH) {
return accum;
}
const newDescription = `${accum} ${word}`;
if (newDescription.length > DESCRIPTION_LENGTH) {
return `${newDescription}…`;
}
return newDescription;
}, "");
};
/**
*
* @param {object} node a Gatsby MDX node.
* @param {string} node.id MDX id
* @param {object} node.frontmatter frontmatter
* @param {string} node.frontmatter.order order
* @param {string} node.frontmatter.title title
* @param {string} node.body body
* @param {object} node.parent parent
* @param {string} node.parent.relativeDirectory relativeDirectory
* @param {string} [node.parent.relativePath] relativePath
* @param {object} [node.parent.fields] fields
* @param {object} [node.parent.fields.metadata.data.order] order
* @param {object} [node.parent.fields.metadata.data.title] title
*
* @returns {object} An object with the below keys. Any missing fields on the
* input will produce `undefined`. on the output.
* id
* order
* title
* githubLink
* body
* directory
* currentDirectory
* folder: {
* order
* title
* }
* ...node
*/
export const normalizeMdx = (node) => {
const { id, frontmatter = {}, body, parent = {} } = node;
const metadata = parent.fields?.metadata.data || {};
const parentRelativeDirSplit = parent.relativeDirectory?.split("/");
const mdxLink = parent.relativePath && DOCS_CONTENT_URL + parent.relativePath;
return {
...node,
id,
order: frontmatter.order,
title: frontmatter.title,
githubLink: mdxLink,
body,
// paths always start with `docs` or `api` which isn't useful. Strip it.
directory: parentRelativeDirSplit?.slice(1).join("/"),
currentDirectory:
parentRelativeDirSplit?.[parentRelativeDirSplit.length - 1],
folder: {
order: metadata.order,
title: metadata.title,
},
};
};