diff --git a/README.md b/README.md index 61e47f3..ac3e6c1 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ the following fields. * **style**: An optional stylesheet to load * **output**: A location to save the rendered document (default: *FILENAME-cleaver.html*) * **controls**: A boolean representing whether or not arrow buttons should be included (default: *true*) +* **agenda**: A boolean representing whether or not to create an agenda slide after the title (default: *false*). These will be generated based on the titles of your other slides. If author is included, the following slide will be automatically inserted at the end of your presentation: @@ -131,6 +132,13 @@ Or click the buttons * Fork it * Clone it +* Install dependencies if you don't have them already + + npm install q + npm install node-markdown + npm install js-yaml + npm install mustache + * Checkout a release branch (`git checkout -b feature/cool-wordart`) * Make changes, commit, and push * Open a pull request! diff --git a/examples/basic.md b/examples/basic.md index c97ca58..2b39ed2 100644 --- a/examples/basic.md +++ b/examples/basic.md @@ -4,6 +4,7 @@ author: twitter: "@jdan" url: "http://jordanscales.com" output: basic.html +agenda: true -- @@ -27,3 +28,11 @@ This will be in a separate paragraph * Item gamma No need for multiple templates! + +-- + +#### A fourth level title + +So that you know that the agenda will be properly generated and it will consider your changes of title levels accordingly. + +All of them will be at the same level to generate a simple-looking agenda. \ No newline at end of file diff --git a/lib/cleaver.js b/lib/cleaver.js index 2280ecc..115859f 100644 --- a/lib/cleaver.js +++ b/lib/cleaver.js @@ -14,7 +14,8 @@ function Cleaver(file) { // TODO: make these constants? this.templates = { main: 'layout.mustache', - author: 'author.mustache' + author: 'author.mustache', + agenda: 'agenda.mustache' }; this.resources = { @@ -53,6 +54,11 @@ Cleaver.prototype._parseDocument = function () { self.slides.push(self._renderAuthorSlide(self.metadata.author)); } + // insert agenda after title (lets make this the second slide) + if (self.metadata.agenda) { + self.slides.splice(1, 0, self._renderAgendaSlide(slices)); + } + // maybe load an external stylesheet if (self.metadata.style) { return helper.loadSingle(self.metadata.style) @@ -108,6 +114,29 @@ Cleaver.prototype._renderAuthorSlide = function (authorData) { return mustache.render(this.templates.loaded.author, authorData); } +/* + * Renders the agenda slide + * @param {string} slices The set of slices that had been loaded from the input file + * @return {string} The formatted agenda slide + */ +Cleaver.prototype._renderAgendaSlide = function (slices) { + var titles = []; + + for (var i = 0; i < slices.length; i++) { // for each slice + var firstLine = slices[i].split(/(\n|\r)+/)[0]; // get our first line of text + var matches = /^(#+)\s+(.+)$/.exec(firstLine); // parse the level and the title + + if (!matches // if we didn't parse anything + || matches.length != 3 // we didn't find all capture groups + || matches[1].length <= 2 // this title is a major title or a subtitle + ) continue; // then this is not a title to work with + + var titleText = matches[2]; + titles.push(titleText); + } // for each slice + + return mustache.render(this.templates.loaded.agenda, titles); +} /** * Returns a chopped up document that's easy to parse diff --git a/templates/agenda.mustache b/templates/agenda.mustache new file mode 100644 index 0000000..14844f4 --- /dev/null +++ b/templates/agenda.mustache @@ -0,0 +1,6 @@ +

Agenda

+ \ No newline at end of file