This repository has been archived by the owner on Sep 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
changelog-rss.ts
94 lines (75 loc) · 2.83 KB
/
changelog-rss.ts
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
import { Marked } from "https://deno.land/x/[email protected]/mod.ts";
import { Language, minify } from "https://deno.land/x/[email protected]/mod.ts";
import { Feed } from "https://cdn.skypack.dev/feed?dts";
import { ensureDir } from "https://deno.land/[email protected]/fs/mod.ts";
import { dirname } from "https://deno.land/[email protected]/path/mod.ts";
if (Deno.args.length < 2) {
console.log("changelog-rss.ts <title> <markdown path>");
Deno.exit(1);
}
const [title, markdownPath] = Deno.args;
if (!markdownPath.startsWith("docs/")) {
console.log("Markdown path must starts with docs/");
Deno.exit(1);
}
const urlPath = markdownPath.replace(/^[^]*docs\//, "/").replace(/\.md$/, "");
const outputPath = markdownPath
.replace(/^[^]*docs\//, "public/")
.replace(/\.md$/, ".xml");
const changelog = await Deno.readTextFile(markdownPath);
const posts = changelog.replace(/\r\n/g, "\n").split(/## /g);
posts.shift(); // remove everything above last release
const feed = new Feed({
title: "Tivoli Cloud VR - " + title,
description: "Tivoli Cloud VR - " + title,
id: "https://tivolicloud.github.io/docs" + urlPath,
link: "https://tivolicloud.github.io/docs" + urlPath,
language: "en",
image: "https://tivolicloud.github.io/docs/assets/favicon.png",
copyright:
"Copyright © " +
new Date().getFullYear() +
" Tivoli Cloud VR, Inc. All rights reserved.",
});
// https://github.com/Python-Markdown/markdown/blob/7cff3bd5af4a3ebea608b9fc7c48327d67147db0/markdown/extensions/toc.py#L26
const getSlugFromTitle = (title: string) =>
title
.replace(/[^\w\s-]/g, "")
.toLowerCase()
.trim()
.replace(/[-\s]+/g, "-");
function getDateFromTitle(title: string) {
title = title.toLowerCase();
let month = -1;
const months = "jan feb mar apr may jun jul aug sep oct nov dec".split(" ");
for (const i in months) {
if (title.includes(months[i])) {
month = parseInt(i);
break;
}
}
if (month == -1) throw new Error("Month not found: " + title);
const afterMonth = title.split(months[month])[1];
const date = parseInt(afterMonth.match(/ ([0-9]{1,2})/)![1]);
if (Number.isNaN(date)) throw new Error("Date not found: " + title);
const year = parseInt(afterMonth.match(/ ([0-9]{4})/)![1]);
if (Number.isNaN(year)) throw new Error("Year not found: " + title);
return new Date(year, month, date, 0, 0, 0);
}
for (const post of posts) {
const title = (post.match(/^([^]+?)\n/) ?? [])[1];
const contentMd = (post.match(/\n([^]+?)$/) ?? [])[1].trim();
const contentHtml = Marked.parse(contentMd).content;
const contentHtmlMin = minify(Language.HTML, contentHtml);
const slug = getSlugFromTitle(title);
const date = getDateFromTitle(title);
feed.addItem({
title,
id: slug,
link: "https://docs.tivolicloud.com" + urlPath + "/#" + slug,
content: contentHtmlMin,
date,
});
}
await ensureDir(dirname(outputPath));
await Deno.writeTextFile(outputPath, feed.rss2());