Skip to content

Commit 5323184

Browse files
committed
fix: use remark to transform changelogs better
1 parent f09563d commit 5323184

File tree

3 files changed

+115
-19
lines changed

3 files changed

+115
-19
lines changed

apify-docs-theme/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"babel-loader": "^9.1.3",
2727
"docusaurus-gtm-plugin": "^0.0.2",
2828
"postcss-preset-env": "^9.3.0",
29-
"prism-react-renderer": "^2.0.6"
29+
"prism-react-renderer": "^2.0.6",
30+
"remark": "^15.0.1"
3031
},
3132
"peerDependencies": {
3233
"clsx": "*",

apify-docs-theme/src/markdown.js

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,102 @@
1+
const { remark } = require('remark');
2+
13
function updateChangelog(changelog) {
4+
const tree = remark.parse(changelog);
5+
6+
bumpHeadingsLevels(tree);
7+
linkifyUserTags(tree);
8+
prettifyPRLinks(tree);
9+
10+
changelog = remark.stringify(tree);
211
changelog = addFrontmatter(changelog);
3-
changelog = pushHeadings(changelog);
4-
changelog = fixUserLinks(changelog);
5-
changelog = fixPRLinks(changelog);
612
changelog = escapeMDXCharacters(changelog);
713
return changelog;
814
}
915

10-
function addFrontmatter(changelog, header = 'Changelog') {
11-
return `---
12-
title: ${header}
13-
sidebar_label: ${header}
14-
toc_max_heading_level: 2
15-
---
16-
${changelog}`;
16+
function bumpHeadingsLevels(tree) {
17+
tree.children?.forEach((child) => {
18+
if (child.type === 'heading') {
19+
child.depth += 1;
20+
}
21+
22+
bumpHeadingsLevels(child);
23+
});
1724
}
1825

19-
function pushHeadings(changelog) {
20-
return changelog.replaceAll(/\n#[^#]/g, '\n## ');
26+
function linkifyUserTags(tree) {
27+
for (let i = 0; i < tree.children?.length; i++) {
28+
const child = tree.children[i];
29+
if (child.type === 'text') {
30+
const userTagRegex = /@([a-zA-Z0-9-]+)(\s|$)/g;
31+
const match = userTagRegex.exec(child.value);
32+
33+
if (match) {
34+
const [_, username, ending] = match;
35+
const before = child.value.slice(0, match.index);
36+
const after = child.value.slice(userTagRegex.lastIndex);
37+
38+
const link = {
39+
type: 'link',
40+
url: `https://github.com/${username}`,
41+
children: [{ type: 'text', value: `@${username}` }],
42+
};
43+
child.value = before;
44+
45+
tree.children.splice(i + 1, 0, link);
46+
47+
if (after) {
48+
tree.children.splice(i + 2, 0, { type: 'text', value: `${ending}${after}` });
49+
}
50+
51+
i += 2;
52+
}
53+
}
54+
55+
linkifyUserTags(child);
56+
}
2157
}
2258

23-
function fixUserLinks(changelog) {
24-
return changelog.replaceAll(/by @([a-zA-Z0-9-]+)/g, 'by [@$1](https://github.com/$1)');
59+
// If there is a PR URL (https://github.com/**/**/pull/number) in the text body, split the body, and replace the URL with a link to the PR (the text should be the PR number).
60+
function prettifyPRLinks(tree) {
61+
for (let i = 0; i < tree.children?.length; i++) {
62+
const child = tree.children[i];
63+
if (child.type === 'text') {
64+
const prLinkRegex = /https:\/\/github.com\/.*\/pull\/(\d+)/g;
65+
const match = prLinkRegex.exec(child.value);
66+
67+
if (match) {
68+
const [_, prNumber] = match;
69+
const before = child.value.slice(0, match.index);
70+
const after = child.value.slice(prLinkRegex.lastIndex);
71+
72+
const link = {
73+
type: 'link',
74+
url: match[0],
75+
children: [{ type: 'text', value: `#${prNumber}` }],
76+
};
77+
child.value = before;
78+
79+
tree.children.splice(i + 1, 0, link);
80+
81+
if (after) {
82+
tree.children.splice(i + 2, 0, { type: 'text', value: after });
83+
}
84+
85+
i += 2;
86+
}
87+
}
88+
89+
prettifyPRLinks(child);
90+
}
2591
}
2692

27-
function fixPRLinks(changelog) {
28-
return changelog.replaceAll(/(((https?:\/\/)?(www.)?)?github.com\/[^\s]*?\/pull\/([0-9]+))/g, '[#$5]($1)');
93+
function addFrontmatter(changelog, header = 'Changelog') {
94+
return `---
95+
title: ${header}
96+
sidebar_label: ${header}
97+
toc_max_heading_level: 3
98+
---
99+
${changelog}`;
29100
}
30101

31102
function escapeMDXCharacters(changelog) {

package-lock.json

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)