-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
142 lines (125 loc) · 4.28 KB
/
index.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const katexOptions = {
output: "html",
macros: {
"\\frag": "\\htmlClass{fragment}",
"\\fragIdx": '\\htmlAttr{class=fragment, data-fragment-index=#1}{#2}',
},
trust: true,
strict: false
};
const markdownItOptions = {
html: true,
typographer: true,
};
// get command line parameters
const argv = require('minimist')(process.argv.slice(2));
if (argv['h']) {
console.log("Usage: md2html [-n] [-s name=value] [-t template_file] [-i input_file] [-o output_file]");
console.log(" Convert markdown into reveal.js HTML slides");
console.log("Options:");
console.log(" -n: Generate notes not slides");
console.log(" -s name=value: Substitute {{name}} with value")
console.log(" -t template_file: HTML template file to use");
console.log(" -i input_file: Markdown input file (default: stdin)");
console.log(" -o output_file: HTML output file (default: stdout)");
process.exit(1);
}
let input_file = argv['i'];
let template_file = argv['t'];
// setup markdown parser
const MarkdownIt = require('markdown-it');
const mdParser = new MarkdownIt(markdownItOptions);
mdParser.use(require('markdown-it-attrs'));
if (argv['n']) { // syntax highlight for notes
mdParser.use(require('markdown-it-highlightjs'));
}
mdParser.use(require('./markdown-it-email'));
mdParser.use(require('./markdown-it-katex'), katexOptions);
function renderSlide(markdown)
{
let cls = (markdown.match(/(^|\n)# [^\n]*\n[ \t]*\n/)) ? ' class="title-slide"': '';
return `<section${cls}>${mdParser.render(markdown)}</section>`;
}
function renderNote(markdown)
{
return mdParser.render(markdown);
}
const fs = require('fs');
// read markdown input
try {
var markdown = fs.readFileSync(input_file ? input_file : process.stdin.fd, 'utf8');
} catch (err) {
console.error(err);
process.exit(1);
}
// read HTML template
try {
var html = fs.readFileSync(template_file, 'utf8');
} catch (err) {
html = `<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>TITLE</title>
<link rel="stylesheet" href="/libs/css/highlight-theme/atom-one-light.css" id="highlight-theme">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css" integrity="sha384-Um5gpz1odJg5Z4HAmzPtgZKdTBHZdw8S29IecapCSB31ligYPhHQZMIlWLYQGVoc" crossorigin="anonymous">
</head>
<body>
<!-- MARKDOWN_NOTES -->
<!-- MARKDOWN_SLIDES -->
</body>
</html>`;
}
// perform variable substitution in the markdown input
if (argv['s']) {
let regex = /([a-zA-Z][a-zA-Z0-9_\-]*)=(.*)/;
substitutions = (argv['s'] instanceof Array) ? argv['s'] : [ argv['s'] ];
for (let substitution of substitutions) {
let match = regex.exec(substitution);
if (match !== null) {
markdown = markdown.replaceAll(`{{${match[1]}}}`, match[2]);
}
}
}
let output = "";
if (argv['n']) {
// insert rendered notes to the HTML template
output = html.replace('<!-- MARKDOWN_NOTES -->', renderNote(markdown));
} else {
//
// we need to do a bit more for slides than notes
//
// update the name of the annotation json file
let jsonFilename = "";
if (input_file) {
jsonFilename = input_file.replace(/^.*[\\\/]/, '').replace(/\.[^\.]*$/, '') + ".json";
}
output = html.replace('__SLIDES-JSON__.json', jsonFilename);
// split markdown into individual slides and render them to HTML
let frags = markdown.split(/\n\s*\n(##[^\n]*\n[ \t]*\n)/)
let slides = []
if (frags.length > 0) {
slides.push(renderSlide(frags[0]))
for (let i = 1; i < frags.length - 1; i += 2) {
slides.push(renderSlide(frags[i]+frags[i+1]));
}
}
// insert rendered slides to the output
output = output.replace('<!-- MARKDOWN_SLIDES -->', slides.join('\n'));
}
// replace HTML title with the content of <h1>
let match = /<h1[^>]*>(.*)<\/h1>/.exec(output);
if (match) {
output = output.replace('<title>TITLE</title>', `<title>${match[1]}</title>`);
}
// produce output
if (argv['o']) {
try {
fs.writeFileSync(argv['o'], output);
} catch (err) {
console.error(err)
}
} else {
console.log(output);
}