@apify/docs-theme 1.0.147 → 1.0.149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +6 -2
  2. package/src/markdown.js +118 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apify/docs-theme",
3
- "version": "1.0.147",
3
+ "version": "1.0.149",
4
4
  "description": "",
5
5
  "main": "./src/index.js",
6
6
  "files": [
@@ -26,7 +26,11 @@
26
26
  "babel-loader": "^9.1.3",
27
27
  "docusaurus-gtm-plugin": "^0.0.2",
28
28
  "postcss-preset-env": "^9.3.0",
29
- "prism-react-renderer": "^2.0.6"
29
+ "prism-react-renderer": "^2.0.6",
30
+ "remark-parse": "^11.0.0",
31
+ "remark-stringify": "^11.0.0",
32
+ "unified": "^11.0.5",
33
+ "unist-util-visit-parents": "^6.0.0"
30
34
  },
31
35
  "peerDependencies": {
32
36
  "clsx": "*",
package/src/markdown.js CHANGED
@@ -1,33 +1,132 @@
1
+ const remarkParse = require('remark-parse');
2
+ const remarkStringify = require('remark-stringify');
3
+ const { unified } = require('unified');
4
+ const visitParents = require('unist-util-visit-parents');
5
+
6
+ /**
7
+ * Updates the markdown content for better UX and compatibility with Docusaurus v3.
8
+ * @param {string} changelog The markdown content.
9
+ * @returns {string} The updated markdown content.
10
+ */
1
11
  function updateChangelog(changelog) {
12
+ const pipeline = unified()
13
+ .use(remarkParse)
14
+ .use(incrementHeadingLevels)
15
+ .use(prettifyPRLinks)
16
+ .use(linkifyUserTags)
17
+ .use(remarkStringify);
18
+
19
+ changelog = pipeline.processSync(changelog).toString();
2
20
  changelog = addFrontmatter(changelog);
3
- changelog = pushHeadings(changelog);
4
- changelog = fixUserLinks(changelog);
5
- changelog = fixPRLinks(changelog);
6
21
  changelog = escapeMDXCharacters(changelog);
7
22
  return changelog;
8
23
  }
9
24
 
10
- function addFrontmatter(changelog, header = 'Changelog') {
11
- return `---
12
- title: ${header}
13
- sidebar_label: ${header}
14
- toc_max_heading_level: 2
15
- ---
16
- ${changelog}`;
17
- }
25
+ /**
26
+ * Bumps the headings levels in the markdown content. This function increases the depth
27
+ * of all headings in the content by 1. This is useful when the content is included in
28
+ * another markdown file with a higher-level heading.
29
+ * @param {*} tree Remark AST tree.
30
+ * @returns {void} Nothing. This function modifies the tree in place.
31
+ */
32
+ const incrementHeadingLevels = () => (tree) => {
33
+ visitParents(tree, 'heading', (node) => {
34
+ node.depth += 1;
35
+ });
36
+ };
18
37
 
19
- function pushHeadings(changelog) {
20
- return changelog.replaceAll(/\n#[^#]/g, '\n## ');
21
- }
38
+ /**
39
+ * Links user tags in the markdown content. This function replaces the user tags
40
+ * (e.g. `@username`) with a link to the user's GitHub profile (just like GitHub's UI).
41
+ * @param {*} tree Remark AST tree.
42
+ * @returns {void} Nothing. This function modifies the tree in place.
43
+ */
44
+ const linkifyUserTags = () => (tree) => {
45
+ visitParents(tree, 'text', (node, parents) => {
46
+ const userTagRegex = /@([a-zA-Z0-9-]+)(\s|$)/g;
47
+ const match = userTagRegex.exec(node.value);
22
48
 
23
- function fixUserLinks(changelog) {
24
- return changelog.replaceAll(/by @([a-zA-Z0-9-]+)/g, 'by [@$1](https://github.com/$1)');
25
- }
49
+ if (!match) return;
50
+
51
+ const directParent = parents[parents.length - 1];
52
+ const nodeIndexInParent = directParent.children.findIndex((x) => x === node);
53
+
54
+ const username = match[1];
55
+ const ending = match[2] === ' ' ? ' ' : '';
56
+ const before = node.value.slice(0, match.index);
57
+ const after = node.value.slice(userTagRegex.lastIndex);
26
58
 
27
- function fixPRLinks(changelog) {
28
- return changelog.replaceAll(/(((https?:\/\/)?(www.)?)?github.com\/[^\s]*?\/pull\/([0-9]+))/g, '[#$5]($1)');
59
+ const link = {
60
+ type: 'link',
61
+ url: `https://github.com/${username}`,
62
+ children: [{ type: 'text', value: `@${username}` }],
63
+ };
64
+ node.value = before;
65
+ directParent.children.splice(nodeIndexInParent + 1, 0, link);
66
+
67
+ if (!after) return nodeIndexInParent + 2;
68
+
69
+ directParent.children.splice(nodeIndexInParent + 2, 0, { type: 'text', value: `${ending}${after}` });
70
+ return nodeIndexInParent + 3;
71
+ });
72
+ };
73
+
74
+ /**
75
+ * Prettifies PR links in the markdown content. Just like GitHub's UI, this function
76
+ * replaces the full PR URL with a link represented by the PR number (prefixed by a hashtag).
77
+ * @param {*} tree Remark AST tree.
78
+ * @returns {void} Nothing. This function modifies the tree in place.
79
+ */
80
+ const prettifyPRLinks = () => (tree) => {
81
+ visitParents(tree, 'text', (node, parents) => {
82
+ const prLinkRegex = /https:\/\/github.com\/[^\s]+\/pull\/(\d+)/g;
83
+ const match = prLinkRegex.exec(node.value);
84
+
85
+ if (!match) return;
86
+
87
+ const directParent = parents[parents.length - 1];
88
+ const nodeIndexInParent = directParent.children.findIndex((x) => x === node);
89
+
90
+ const prNumber = match[1];
91
+ const before = node.value.slice(0, match.index);
92
+ const after = node.value.slice(prLinkRegex.lastIndex);
93
+
94
+ const link = {
95
+ type: 'link',
96
+ url: match[0],
97
+ children: [{ type: 'text', value: `#${prNumber}` }],
98
+ };
99
+ node.value = before;
100
+
101
+ directParent.children.splice(nodeIndexInParent + 1, 0, link);
102
+ if (!after) return nodeIndexInParent + 1;
103
+
104
+ directParent.children.splice(nodeIndexInParent + 2, 0, { type: 'text', value: after });
105
+ return nodeIndexInParent + 2;
106
+ });
107
+ };
108
+
109
+ /**
110
+ * Adds frontmatter to the markdown content.
111
+ * @param {string} changelog The markdown content.
112
+ * @param {string} title The frontmatter title.
113
+ * @returns {string} The markdown content with frontmatter.
114
+ */
115
+ function addFrontmatter(changelog, title = 'Changelog') {
116
+ return `---
117
+ title: ${title}
118
+ sidebar_label: ${title}
119
+ toc_max_heading_level: 3
120
+ ---
121
+ ${changelog}`;
29
122
  }
30
123
 
124
+ /**
125
+ * Escapes the MDX-related characters in the markdown content.
126
+ * This is required by Docusaurus v3 and its dependencies (see the v3 [migration guide](https://docusaurus.io/docs/migration/v3#common-mdx-problems)).
127
+ * @param {string} changelog The markdown content.
128
+ * @returns {string} The markdown content with escaped MDX characters.
129
+ */
31
130
  function escapeMDXCharacters(changelog) {
32
131
  return changelog.replaceAll(/<|>/g, (match) => {
33
132
  return match === '<' ? '&lt;' : '&gt;';