tangled
alpha
login
or
join now
shreyanjain.net
/
atblog
4
fork
atom
atproto-based blog in ruby
4
fork
atom
overview
issues
pulls
pipelines
json to md + syntax highlighting
shreyanjain.net
10 months ago
e4229284
59583fc7
+124
-1
2 changed files
expand all
collapse all
unified
split
public
to_md.html
views
layout.haml
+116
public/to_md.html
···
1
1
+
<!DOCTYPE html>
2
2
+
<html lang="en">
3
3
+
<head>
4
4
+
<meta charset="UTF-8">
5
5
+
<title>JSON to Markdown</title>
6
6
+
<style>
7
7
+
body {
8
8
+
font-family: sans-serif;
9
9
+
margin: 2rem;
10
10
+
display: flex;
11
11
+
flex-direction: column;
12
12
+
gap: 1rem;
13
13
+
}
14
14
+
textarea {
15
15
+
width: 100%;
16
16
+
height: 200px;
17
17
+
font-family: monospace;
18
18
+
padding: 1rem;
19
19
+
border-radius: 8px;
20
20
+
border: 1px solid #ccc;
21
21
+
}
22
22
+
button {
23
23
+
padding: 0.5rem 1rem;
24
24
+
font-size: 1rem;
25
25
+
border: none;
26
26
+
background: #0070f3;
27
27
+
color: white;
28
28
+
border-radius: 6px;
29
29
+
cursor: pointer;
30
30
+
align-self: start;
31
31
+
}
32
32
+
button:hover {
33
33
+
background: #0059c9;
34
34
+
}
35
35
+
</style>
36
36
+
</head>
37
37
+
<body>
38
38
+
<h1>🌀 JSON to Markdown</h1>
39
39
+
40
40
+
<label for="json-input">Paste Blog Post JSON:</label>
41
41
+
<textarea id="json-input" placeholder="Paste your JSON here..."></textarea>
42
42
+
43
43
+
<button onclick="convertToMarkdown()">Convert</button>
44
44
+
45
45
+
<label for="markdown-output">Markdown Output:</label>
46
46
+
<textarea id="markdown-output" readonly></textarea>
47
47
+
48
48
+
<script>
49
49
+
function convertToMarkdown() {
50
50
+
const input = document.getElementById('json-input').value;
51
51
+
let output = '';
52
52
+
53
53
+
try {
54
54
+
const data = JSON.parse(input);
55
55
+
const blocks = data.content || [];
56
56
+
57
57
+
const formatSpan = (text, formatting) => {
58
58
+
if (!formatting) return text;
59
59
+
formatting.forEach(f => {
60
60
+
const type = f["$type"];
61
61
+
switch (type) {
62
62
+
case "net.shreyanjain.richtext.formatting#bold":
63
63
+
text = `**${text}**`;
64
64
+
break;
65
65
+
case "net.shreyanjain.richtext.formatting#italic":
66
66
+
text = `*${text}*`;
67
67
+
break;
68
68
+
case "net.shreyanjain.richtext.formatting#underline":
69
69
+
text = `<u>${text}</u>`; // Markdown has no native underline
70
70
+
break;
71
71
+
case "net.shreyanjain.richtext.formatting#code":
72
72
+
text = `\`${text}\``;
73
73
+
break;
74
74
+
case "net.shreyanjain.richtext.formatting#link":
75
75
+
text = `[${text}](${f.href})`;
76
76
+
break;
77
77
+
}
78
78
+
});
79
79
+
return text;
80
80
+
};
81
81
+
82
82
+
blocks.forEach(block => {
83
83
+
switch (block["$type"]) {
84
84
+
case "net.shreyanjain.richtext.block#heading":
85
85
+
output += `# ${block.text}\n\n`;
86
86
+
break;
87
87
+
case "net.shreyanjain.richtext.block#subheading":
88
88
+
output += `## ${block.text}\n\n`;
89
89
+
break;
90
90
+
case "net.shreyanjain.richtext.block#paragraph":
91
91
+
output += block.text.map(span => formatSpan(span.content, span.formatting)).join('') + '\n\n';
92
92
+
break;
93
93
+
case "net.shreyanjain.richtext.block#code":
94
94
+
output += `\`\`\`\n${block.text}\n\`\`\`\n\n`;
95
95
+
break;
96
96
+
case "net.shreyanjain.richtext.block#list":
97
97
+
block.text.forEach(item => {
98
98
+
const line = item.map(span => formatSpan(span.content, span.formatting)).join('');
99
99
+
output += `- ${line}\n`;
100
100
+
});
101
101
+
output += '\n';
102
102
+
break;
103
103
+
default:
104
104
+
// Skip unknown block types
105
105
+
break;
106
106
+
}
107
107
+
});
108
108
+
109
109
+
document.getElementById('markdown-output').value = output.trim();
110
110
+
} catch (err) {
111
111
+
document.getElementById('markdown-output').value = `Error: ${err.message}`;
112
112
+
}
113
113
+
}
114
114
+
</script>
115
115
+
</body>
116
116
+
</html>
+8
-1
views/layout.haml
···
1
1
%html
2
2
%head
3
3
-
%link{ :rel => "stylesheet", :href => "/style.css" }
3
3
+
%link{ rel: "stylesheet", href: "/style.css" }
4
4
%title= @title
5
5
+
-# JS for code syntax highlighting
6
6
+
%link{ rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" }
7
7
+
%script{ src: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" }
8
8
+
%script
9
9
+
hljs.highlightAll();
10
10
+
11
11
+
5
12
6
13
!= yield
7
14