-
Notifications
You must be signed in to change notification settings - Fork 0
/
gem2html.js
109 lines (105 loc) · 4.15 KB
/
gem2html.js
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
101
102
103
104
105
106
107
108
109
let mimeparse = require("./mimeparse");
const _ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
function _rand_n() {
return Math.floor(Math.random()*(2**32));
}
function rand_id() {
let n = _rand_n();
let tmp = 0;
let id = "";
while (n>0) {
tmp = Math.floor(n/36);
id = _ALPHABET[n%36]+id;
n = tmp;
}
return id;
}
function gem2html(gemtext,charset) {
//console.log(gemtext, charset);
charset = charset || "utf8";
let text = gemtext.toString(charset);
//console.log(text);
let lines = text.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/);
//console.log(lines.length,"line(s)");
let pre = false;
let pre_alt = false;
let output = "<html><head><style>p, h1, h2, h3 {margin-top: 0; margin-bottom: 0;} blockquote {margin-inline-start: 1.5em; padding: .75em; border-inline-start: 2px solid #999;}</style></head><body>";
let used_ids = new Array();
for (let i=0;i<lines.length;i++) {
let line = lines[i];
if (pre) {
if (line.slice(0,3)=="```") {
output+="</pre>";
pre = false;
if (pre_alt) {
output+="\n</figure>";
pre_alt=false;
}
} else {
output+=line.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
}
} else {
if (line.slice(0,3)=="```") {
if (line.length>3) {
let id = rand_id();
while (used_ids.indexOf(id)!==-1) id = rand_id();
output+="<figure role='img' aria-captioned-by='"+id+"'><figcaption id='"+id+"' style='clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;'>"+line.slice(3)+"</figcaption>\n";
pre_alt=true;
}
pre=true;
output+="<pre>";
} else if (line.slice(0,2)=="=>" && line.length>2) {
let parts = line.slice(2).replace(/^\s+/,"").split(/\s+(.+)/,2);
if (parts.length==1) {
// just the path/url, so just use that
output+="<p><a href='"+parts[0]+"'>"+parts[0].replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</a></p>";
} else {
// we have a link name
output+="<p><a href='"+parts[0]+"'>"+parts[1].replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</a></p>";
}
} else if (line.slice(0,2)=="=:" && line.length>2) {
// this is the spartan-specific input link
let parts = line.slice(2).replace(/^\s+/,"").split(/\s+(.+)/,2);
let path, name;
if (parts.length==1) {
path = parts[0];
name = "Submit input to path "+parts[0];
} else {
path = parts[0];
name = parts[1];
}
output+="<form action=\""+path+"\" method=\"POST\" enctype=\"multipart/form-data\"><p>"+name.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</p><p><label for='textinput'>Text input: </label><textarea rows=5 cols=80 name='textinput'></textarea></p><p><button type='submit'>Submit</button></p></form>";
} else if (line[0]==">") {
output+="<blockquote><p>"+line.slice(1).replace(/^\s+/,"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</p></blockquote>";
} else if (line[0]=="#") {
let level = 1;
if (line.slice(0,2)=="##") level=2;
if (line.slice(0,3)=="###") level=3;
output+="<h"+level+">"+line.slice(level).replace(/^\s+/,"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</h"+level+">";
} else if (line.slice(0,2)=="* ") {
output+="<ul>\n<li>"+line.slice(2).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</li>\n</ul>"
} else {
if (line.length>0) {
output+="<p>"+line.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")+"</p>";
} else {
output+="<p><br></p>";
}
}
}
output+="\n"
}
output+="</body></html>";
output = output.replace(/<\/ul>\n<ul>\n/g,"");
//console.log(output);
return Buffer.from(output);
}
function getCharset(mimetype) {
let parsed = mimeparse(mimetype);
if (parsed[2].hasOwnProperty("charset")) {
return parsed[2].charset;
}
}
module.exports = {
gem2html: gem2html,
getCharset: getCharset
}