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
// Altered from https://github.com/ericclemmons/medium-to-markdown
const fetchJSON = async (url, startAt = 0) => {
const response = await fetch(url);
const text = await response.text();
const json = JSON.parse(text.slice(startAt));
return json;
};
export const mediumToMarkdown = async (mediumLink) => {
const raw = await fetchJSON(mediumLink + "?format=json", 16);
if (raw.error) {
throw new Error(raw.error);
}
const {
firstPublishedAt,
latestPublishedAt,
slug,
title,
} = raw.payload.value;
const { paragraphs, sections } = raw.payload.value.content.bodyModel;
const blocks = await Promise.all(
paragraphs.map(async (paragraph, i) => {
const { iframe, metadata, mixtapeMetadata, name, text, type } = paragraph;
// About to mutate this bia bia
let markups = JSON.parse(JSON.stringify(paragraph.markups));
markups.sort((a, b) => {
return a.start - b.start || a.end - b.end;
});
let formatted = text;
while (markups.length) {
const markup = markups.shift();
let prefix = "";
let suffix = "";
switch (markup.type) {
case 1:
prefix = "**";
suffix = "**";
break;
case 2:
prefix = "*";
suffix = "*";
break;
case 3:
prefix = `[`;
switch (markup.anchorType) {
case 0:
suffix = `](${markup.href})`;
break;
case 2:
suffix = `](https://medium.com/u/${markup.userId})`;
break;
default:
console.error(paragraph);
throw new Error(`Unsupported anchorType: ${markup.anchorType}`);
}
break;
case 10:
prefix = "`";
suffix = "`";
break;
default:
console.error(paragraph);
throw new Error(`Unsupported markup type: ${markup.type}`);
}
formatted = [
formatted.slice(0, markup.start),
prefix,
formatted.slice(markup.start, markup.end),
suffix,
formatted.slice(markup.end),
].join("");
markups.forEach((next) => {
// Markup before changes aren't shifted
if (next.end <= markup.start) {
return;
}
// Markup after changes is shifted by additional characters
if (next.start >= markup.end) {
next.start += prefix.length + suffix.length;
next.end += prefix.length + suffix.length;