forked from jdan/cleaver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcleaver.js
144 lines (114 loc) · 3.24 KB
/
cleaver.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
143
144
var fs = require('fs');
var Q = require('q');
var path = require('path');
var md = require('node-markdown').Markdown;
var yaml = require('js-yaml');
var mustache = require('mustache');
var helper = require('./helper');
function Cleaver(file) {
this.file = file
if (!file) throw "!! Please specify a file to parse";
// TODO: make these constants?
this.templates = {
main: 'layout.mustache',
author: 'author.mustache'
};
this.resources = {
style: 'default.css',
navigation: 'navigation.js'
};
this.external = {
document: file
};
this.metadata = null;
this.slides = [];
}
/**
* Renders the document
*/
Cleaver.prototype._parseDocument = function () {
var self = this;
return Q.all([
helper.load(this.external),
helper.load(this.templates, 'templates')
])
.then(function (data) {
var slices = self._slice(self.external.loaded.document);
self.metadata = yaml.safeLoad(slices[0]);
for (var i = 1; i < slices.length; i++) {
self.slides.push(md(slices[i]));
}
if (self.metadata.author) {
self.slides.push(self._renderAuthorSlide(self.metadata.author));
}
// maybe load an external stylesheet
if (self.metadata.style) {
return helper.loadSingle(self.metadata.style)
.then(function (data) {
self.external.loaded.style = data;
})
}
});
}
/**
* Loads the templates, default stylesheet, and any external stylesheets
* as defined by the user.
* @return {Promise.<Array.<Object>>}
*/
Cleaver.prototype._loadAssets = function () {
return Q.all([
helper.load(this.resources, 'resources')
]);
}
/**
* Renders the slideshow
*/
Cleaver.prototype._renderSlideshow = function () {
var putControls = this.metadata.controls || (this.metadata.controls === undefined);
var outputLocation = this.metadata.output || path.basename(this.file, '.md') + '-cleaver.html';
var title = this.metadata.title || 'Untitled';
var slideData = {
slides: this.slides,
title: title,
controls: putControls,
style: this.resources.loaded.style,
externalStyle: this.external.loaded.style,
// TODO: uglify navigation.js?
navigation: this.resources.loaded.navigation
};
return helper.save(outputLocation, mustache.render(this.templates.loaded.main, slideData));
}
/**
* Renders the author slide
* @param {string} authorData The author field of the slideshow metadata
* @return {string} The formatted author slide
*/
Cleaver.prototype._renderAuthorSlide = function (authorData) {
return mustache.render(this.templates.loaded.author, authorData);
}
/**
* Returns a chopped up document that's easy to parse
* @param {string} The full document
* @return {Array.<string>} A list of all slides
*/
Cleaver.prototype._slice = function(document) {
var cuts = document.split('\n--\n');
var slices = [];
for (var i = 0; i < cuts.length; i++) {
slices.push(cuts[i].trim());
}
return slices;
}
/**
* Method to run the whole show
*/
Cleaver.prototype.run = function () {
var self = this;
Q.all([this._parseDocument(), this._loadAssets()])
.then(self._renderSlideshow.bind(self))
.fail(function (err) {
throw err;
})
.done();
}
module.exports = Cleaver;