Skip to content

Commit

Permalink
renamed metadata -> options; reading options from the command line -
Browse files Browse the repository at this point in the history
fixes #94
  • Loading branch information
jdan committed Aug 27, 2014
1 parent 28197b8 commit e848dfb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 37 deletions.
42 changes: 37 additions & 5 deletions bin/cleaver
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ var Cleaver;
* Helper function to use the cleaver API to create and save a new
* presentation
*/
function createAndSave(file) {
function createAndSave(file, options) {
fs.readFile(file, 'utf-8', function (err, contents) {
var presentation = new Cleaver(contents, path.resolve(path.dirname(file)));
var presentation = new Cleaver(contents, options, path.resolve(path.dirname(file)));
var promise = presentation.run();

promise
.then(function (product) {
var outputFile = presentation.metadata.output || path.basename(file, '.md') + '-cleaver.html';
var outputFile = presentation.options.output || path.basename(file, '.md') + '-cleaver.html';
fs.writeFile(outputFile, product);
})
.fail(function (err) {
Expand All @@ -38,7 +38,7 @@ program
.description('Watch for changes on markdown file')
.action(function () {
var file = program.args[0];
createAndSave(file);
createAndSave(file, parsedOpts);

console.log('Watching for changes on ' + file + '. Ctrl-C to abort.');
fs.watchFile(file, { persistent: true, interval: 100 }, function () {
Expand All @@ -48,11 +48,43 @@ program
});

program
.option('--title <title>', 'The title of the rendered document ' +
'(default: Untitled')
// TODO: author options
.option('--theme <theme>', 'An theme to load')
.option('--style <css>', 'A particular stylesheet to load')
.option('--output <filename>', 'The filename of the rendered document ' +
'(default: [INPUT]-cleaver.html)')
.option('--controls', 'Whether or not to include simple navigation ' +
'controls in your presentation (default: true)')
.option('--progress', 'Option to display a small progress bar at the top ' +
'of your presentation (default: true)')
.option('--encoding <encoding>', 'Content encoding used for the rendered ' +
'document (default: utf-8)')
.option('--template <path>', 'URL or path to a mustache template used for ' +
'individual slides')
.option('--layout <path>', 'URL or path to a mustache template used to ' +
'render the entire presentation')
.option('--debug', 'Enable debug output');

program.parse(process.argv);

// TODO: a lot of code duplication here
var parsedOpts = {
title: program.title,
theme: program.theme,
style: program.style,
output: program.output,
controls: program.controls,
progress: program.progress,
encoding: program.encoding,
template: program.template,
layout: program.layout,
debug: program.debug
};

if (!program.args.length) {
// TODO: custom help screen
program.help();
} else {
/**
Expand All @@ -71,5 +103,5 @@ if (!program.args.length) {
// Load cleaver with the new ENV for debugging
// TODO: This seems a little janky, maybe handle this in lib/
Cleaver = require('../');
createAndSave(program.args[0]);
createAndSave(program.args[0], parsedOpts);
}
6 changes: 3 additions & 3 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ YAML format. A typical option setup resembles the following.

### title

The title of the slidshow.
The title of the rendered document.

**Default**: Untitled

Expand Down Expand Up @@ -90,13 +90,13 @@ Content encoding to use on the rendered document.

### template

URL or absolute/relative path to a mustache template used to render the slides.
URL or path to a mustache template used to render the slides.
See [default.mustache](https://github.com/jdan/cleaver/blob/master/templates/default.mustache)
for inspiration.

### layout

URL or absolute/relative path to a mustache template used to render the entire
URL or path to a mustache template used to render the entire
slideshow. See
[layout.mustache](https://github.com/jdan/cleaver/blob/master/templates/layout.mustache)
for inspiration.
69 changes: 40 additions & 29 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ var helper;
* include external dependencies (stylesheets, scripts, etc)
*
* @param {string} document The input document
* @param {!Object} options Optional settings object to overwrite the options
* listed in the cleaver document
* @param {!string} includePath Optional resource path (default: '.')
* @constructor
*/
function Cleaver(document, includePath) {
function Cleaver(document, options, includePath) {
this.document = document.toString();
this.options = options || {};
this.path = path.resolve(includePath || '.');
/**
* Require helper using `this.path` as a context for where to locate any
* specified assets
*/
helper = require('./helper')(this.path);

this.templates = {
Expand All @@ -37,7 +44,6 @@ function Cleaver(document, includePath) {
style: []
};

this.metadata = null;
this.slides = [];
this.override = false;

Expand Down Expand Up @@ -68,16 +74,21 @@ Cleaver.prototype.loadDocument = function () {


/**
* Parses the metadata and renders the slides.
* Parses the options and renders the slides.
*
* @return {Promise}
*/
Cleaver.prototype.renderSlides = function () {
var slices = this.slice(this.document);
var i;
var i, options;

this.metadata = yaml.safeLoad(slices[0].content) || {};
debug('parsed metadata');
options = yaml.safeLoad(slices[0].content) || {};
// Load any options that are not already present from the constructor
for (i in options) {
this.options[i] = this.options[i] || options[i];
}

debug('parsed options');

for (i = 1; i < slices.length; i++) {
this.slides.push({
Expand All @@ -89,16 +100,16 @@ Cleaver.prototype.renderSlides = function () {
}

// insert an author slide (if necessary) at the end
if (this.metadata.author) {
if (this.metadata.author.twitter &&
!this.metadata.author.twitter.match(/^@/)) {
this.metadata.author.twitter = '@' + this.metadata.author.twitter;
if (this.options.author) {
var twitter = this.options.author.twitter;
if (twitter && !twitter.match(/^@/)) {
this.options.author.twitter = '@' + this.options.author.twitter;
}

this.slides.push({
id: i,
hidden: true,
content: this.renderAuthorSlide(this.metadata.author)
content: this.renderAuthorSlide(this.options.author)
});
}

Expand All @@ -107,7 +118,7 @@ Cleaver.prototype.renderSlides = function () {


/**
* Populates `slides` and some extra loaded content, based on the metadata
* Populates `slides` and some extra loaded content, based on the options
* listed in the document.
*
* @return {Promise}
Expand All @@ -116,24 +127,24 @@ Cleaver.prototype.populateResources = function () {
var promises = [];

// maybe load an external stylesheet
if (this.metadata.style) {
promises.push(helper.populateSingle(this.metadata.style, this.external, 'style')
if (this.options.style) {
promises.push(helper.populateSingle(this.options.style, this.external, 'style')
.then(function () {
debug('loaded user stylesheet');
}));
}

// maybe load an external template
if (this.metadata.template) {
promises.push(helper.populateSingle(this.metadata.template, this.templates, 'slides')
if (this.options.template) {
promises.push(helper.populateSingle(this.options.template, this.templates, 'slides')
.then(function () {
debug('loaded user template');
}));
}

// maybe load an external layout
if (this.metadata.layout) {
promises.push(helper.populateSingle(this.metadata.layout, this.templates, 'layout')
if (this.options.layout) {
promises.push(helper.populateSingle(this.options.layout, this.templates, 'layout')
.then(function () {
debug('loaded user layout');
}));
Expand All @@ -150,8 +161,8 @@ Cleaver.prototype.populateResources = function () {
*/
Cleaver.prototype.populateThemeResources = function () {
// maybe load a theme
if (this.metadata.theme) {
return helper.loadTheme(this.metadata.theme, this).then(function () {
if (this.options.theme) {
return helper.loadTheme(this.options.theme, this).then(function () {
debug('loaded theme');
});
}
Expand Down Expand Up @@ -179,8 +190,8 @@ Cleaver.prototype.loadStaticAssets = function () {
* @return {Promise}
*/
Cleaver.prototype.renderSlideshow = function () {
var putControls = this.metadata.controls || (this.metadata.controls === undefined);
var putProgress = this.metadata.progress || (this.metadata.progress === undefined);
var putControls = this.options.controls || (this.options.controls === undefined);
var putProgress = this.options.progress || (this.options.progress === undefined);
var style, script, output;

// Render the slides in a template (maybe as specified by the user)
Expand All @@ -193,8 +204,8 @@ Cleaver.prototype.renderSlideshow = function () {
debug('rendered slides');

// TODO: handle defaults gracefully
var title = this.metadata.title || 'Untitled';
var encoding = this.metadata.encoding || 'utf-8';
var title = this.options.title || 'Untitled';
var encoding = this.options.encoding || 'utf-8';

if (this.override && this.external.loaded.style) {
style = this.external.loaded.style && this.external.loaded.style.join('\n');
Expand All @@ -221,9 +232,9 @@ Cleaver.prototype.renderSlideshow = function () {
title: title,
encoding: encoding,
style: style,
author: this.metadata.author,
author: this.options.author,
script: script,
metadata: this.metadata
options: this.options
};

/* Return the rendered slideshow */
Expand All @@ -249,7 +260,7 @@ Cleaver.prototype.renderSlide = function (content) {
/**
* Renders the author slide.
*
* @param {string} content The author field of the slideshow metadata
* @param {string} content The author field of the slideshow options
* @return {string} The formatted author slide
*/
Cleaver.prototype.renderAuthorSlide = function (content) {
Expand Down Expand Up @@ -282,7 +293,7 @@ Cleaver.prototype.slice = function(document) {

continue;
} else {
/* If we leave out metadata, add an empty slide at the beginning */
/* If we leave out options, add an empty slide at the beginning */
if (i === 0) {
slices.push({ content: '' });
}
Expand Down Expand Up @@ -319,7 +330,7 @@ Cleaver.prototype.slice = function(document) {
Cleaver.prototype.run = function () {
var self = this;

// Load document -> Parse Metadata / Render Slides -> Populate Resources
// Load document -> Parse options / Render Slides -> Populate Resources
var documentChain = this.loadDocument()
.then(self.renderSlides.bind(self))
.then(self.populateThemeResources.bind(self))
Expand Down

0 comments on commit e848dfb

Please sign in to comment.