You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

518 lines
16 KiB

// Generated by CoffeeScript 1.6.3
var CSON, DocumentModel, FileModel, TaskGroup, YAML, eachr, extendr, extractOptsAndCallback, mime, pathUtil, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
pathUtil = require('path');
extendr = require('extendr');
eachr = require('eachr');
TaskGroup = require('taskgroup').TaskGroup;
mime = require('mime');
extractOptsAndCallback = require('extract-opts').extractOptsAndCallback;
CSON = null;
YAML = null;
FileModel = require('./file');
DocumentModel = (function(_super) {
__extends(DocumentModel, _super);
function DocumentModel() {
_ref = DocumentModel.__super__.constructor.apply(this, arguments);
return _ref;
}
DocumentModel.prototype.klass = DocumentModel;
DocumentModel.prototype.type = 'document';
DocumentModel.prototype.defaults = {
referencesOthers: false,
header: null,
parser: null,
body: null,
rendered: false,
contentRendered: null,
contentRenderedWithoutLayouts: null,
dynamic: false,
tags: null,
renderSingleExtensions: false
};
DocumentModel.prototype.getOutContent = function() {
var content;
content = this.get('contentRendered') || this.getContent();
return content;
};
DocumentModel.prototype.referencesOthers = function(flag) {
if (flag == null) {
flag = true;
}
this.set({
referencesOthers: flag
});
return this;
};
DocumentModel.prototype.parse = function(opts, next) {
var buffer, key, meta, reset, value, _ref1, _ref2,
_this = this;
if (opts == null) {
opts = {};
}
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
buffer = this.getBuffer();
meta = this.getMeta();
reset = {};
_ref2 = meta.attributes;
for (key in _ref2) {
if (!__hasProp.call(_ref2, key)) continue;
value = _ref2[key];
reset[key] = this.defaults[key];
}
reset = extendr.dereference(reset);
this.set(reset);
meta.clear();
DocumentModel.__super__.parse.call(this, opts, function() {
var body, content, err, header, ignored, match, metaData, metaDate, metaUrl, metaUrls, parser, regex, seperator;
content = _this.get('content').replace(/\r\n?/gm, '\n');
regex = /^\s*(([^\s\d\w])\2{2,})(?:\x20*([a-z]+))?([\s\S]*?)\1/;
match = regex.exec(content);
metaData = {};
if (match) {
seperator = match[1];
parser = match[3] || 'yaml';
header = match[4].trim();
body = content.substring(match[0].length).trim();
try {
switch (parser) {
case 'cson':
case 'coffee':
case 'coffeescript':
case 'coffee-script':
if (!CSON) {
CSON = require('cson');
}
metaData = CSON.parseSync(header);
meta.set(metaData);
break;
case 'yaml':
if (!YAML) {
YAML = require('yamljs');
}
metaData = YAML.parse(header.replace(/\t/g, ' '));
meta.set(metaData);
break;
default:
err = new Error("Unknown meta parser: " + parser);
return next(err);
}
} catch (_error) {
err = _error;
return next(err);
}
} else {
body = content;
}
if (metaData.encoding && metaData.encoding !== _this.get('encoding')) {
_this.setMeta({
encoding: metaData.encoding
});
opts.reencode = true;
return _this.parse(opts, next);
}
body = body.replace(/^\n+/, '');
_this.set({
source: content,
content: body,
header: header,
body: body,
parser: parser,
name: _this.get('name') || _this.get('title') || _this.get('basename')
});
metaDate = meta.get('date');
if (metaDate) {
metaDate = new Date(metaDate);
meta.set({
date: metaDate
});
}
ignored = meta.get('ignored') || meta.get('ignore') || meta.get('skip') || meta.get('draft') || (meta.get('published') === false);
if (ignored) {
meta.set({
ignored: true
});
}
metaUrls = meta.get('urls');
metaUrl = meta.get('url');
if (metaUrls) {
_this.addUrl(metaUrls);
}
if (metaUrl) {
_this.addUrl(metaUrl);
}
_this.set(meta.toJSON());
return next();
});
return this;
};
DocumentModel.prototype.normalize = function(opts, next) {
var changes, extensions, filename, meta, outExtension, _ref1;
if (opts == null) {
opts = {};
}
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
changes = {};
meta = this.getMeta();
outExtension = opts.outExtension || meta.get('outExtension') || null;
filename = opts.filename || this.get('filename') || null;
extensions = this.getExtensions({
filename: filename
}) || null;
if (!outExtension) {
changes.outExtension = outExtension = extensions[0] || null;
}
DocumentModel.__super__.normalize.call(this, extendr.extend(opts, changes), next);
return this;
};
DocumentModel.prototype.contextualize = function(opts, next) {
var _ref1,
_this = this;
if (opts == null) {
opts = {};
}
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
this.getEve(function(err, eve) {
var changes, extensions, meta, outExtension, outFilename, outPath;
if (err) {
return next(err);
}
changes = {};
meta = _this.getMeta();
outFilename = opts.outFilename || meta.get('outFilename') || null;
outPath = opts.outPath || meta.get('outPath') || null;
outExtension = opts.outExtension || meta.get('outExtension') || null;
extensions = _this.getExtensions({
filename: outFilename
}) || null;
if (!outExtension) {
if (!outFilename && !outPath) {
if (eve != null) {
changes.outExtension = outExtension = eve.get('outExtension') || extensions[0] || null;
} else {
changes.outExtension = extensions[0] || null;
}
}
}
return _this.normalize(extendr.extend(opts, changes), next);
});
return this;
};
DocumentModel.prototype.hasLayout = function() {
return this.get('layout') != null;
};
DocumentModel.prototype.getLayout = function(next) {
var file, layoutSelector;
file = this;
layoutSelector = this.get('layout');
if (!layoutSelector) {
return next(null, null);
}
this.emit('getLayout', {
selector: layoutSelector
}, function(err, opts) {
var layout;
layout = opts.layout;
if (err) {
file.set({
'layoutId': null
});
return next(err);
} else if (!layout) {
file.set({
'layoutId': null
});
err = new Error("Could not find the specified layout: " + layoutSelector);
return next(err);
} else {
file.set({
'layoutId': layout.id
});
return next(null, layout);
}
});
return this;
};
DocumentModel.prototype.getEve = function(next) {
if (this.hasLayout()) {
this.getLayout(function(err, layout) {
if (err) {
return next(err, null);
} else {
return layout.getEve(next);
}
});
} else {
next(null, this);
}
return this;
};
DocumentModel.prototype.renderExtensions = function(opts, next) {
var content, extension, extensions, extensionsReversed, file, filename, renderSingleExtensions, result, tasks, templateData, _i, _len, _ref1;
file = this;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
content = opts.content, templateData = opts.templateData, renderSingleExtensions = opts.renderSingleExtensions;
extensions = this.get('extensions');
filename = this.get('filename');
if (content == null) {
content = this.get('body');
}
if (templateData == null) {
templateData = {};
}
if (renderSingleExtensions == null) {
renderSingleExtensions = this.get('renderSingleExtensions');
}
result = content;
extensionsReversed = [];
if (extensions.length === 0 && filename) {
extensionsReversed.push(filename);
}
for (_i = 0, _len = extensions.length; _i < _len; _i++) {
extension = extensions[_i];
extensionsReversed.unshift(extension);
}
if (renderSingleExtensions && extensionsReversed.length === 1) {
if (renderSingleExtensions !== 'auto' || filename.replace(/^\./, '') === extensionsReversed[0]) {
extensionsReversed.push(null);
}
}
if (extensionsReversed.length <= 1) {
return next(null, result);
}
tasks = new TaskGroup().once('complete', function(err) {
return next(err, result);
});
eachr(extensionsReversed.slice(1), function(extension, index) {
return tasks.addTask(function(complete) {
var eventData;
eventData = {
inExtension: extensionsReversed[index],
outExtension: extension,
templateData: templateData,
file: file,
content: result
};
return file.trigger('render', eventData, function(err) {
var message;
if (err) {
return complete(err);
}
if (result && result === eventData.content) {
message = "\n Rendering the extension \"" + eventData.inExtension + "\" to \"" + eventData.outExtension + "\" on \"" + file.attributes.relativePath + "\" didn't do anything.\n Explanation here: http://docpad.org/extension-not-rendering";
file.log('warn', message);
return complete();
}
result = eventData.content;
return complete();
});
});
});
tasks.run();
return this;
};
DocumentModel.prototype.renderDocument = function(opts, next) {
var content, eventData, extension, file, templateData, _ref1;
file = this;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
content = opts.content, templateData = opts.templateData;
extension = this.get('extensions')[0];
if (content == null) {
content = this.get('body');
}
if (templateData == null) {
templateData = {};
}
eventData = {
extension: extension,
templateData: templateData,
file: file,
content: content
};
file.trigger('renderDocument', eventData, function(err) {
return next(err, eventData.content);
});
return this;
};
DocumentModel.prototype.renderLayouts = function(opts, next) {
var content, file, templateData, _ref1;
file = this;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
content = opts.content, templateData = opts.templateData;
if (content == null) {
content = this.get('body');
}
if (templateData == null) {
templateData = {};
}
return file.getLayout(function(err, layout) {
if (err) {
return next(err, content);
}
if (layout) {
templateData.content = content;
return layout.render({
templateData: templateData
}, function(err, result) {
return next(err, result);
});
} else {
return next(null, content);
}
});
};
DocumentModel.prototype.render = function(opts, next) {
var contentRenderedWithoutLayouts, file, relativePath, tasks, _base, _base1, _ref1;
if (opts == null) {
opts = {};
}
file = this;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
opts = extendr.clone(opts || {});
if (opts.actions == null) {
opts.actions = ['renderExtensions', 'renderDocument', 'renderLayouts'];
}
contentRenderedWithoutLayouts = null;
relativePath = this.get('relativePath');
if (opts.content == null) {
opts.content = this.get('body');
}
opts.templateData = extendr.clone(opts.templateData || {});
if ((_base = opts.templateData).document == null) {
_base.document = file.toJSON();
}
if ((_base1 = opts.templateData).documentModel == null) {
_base1.documentModel = file;
}
file.log('debug', "Rendering the file: " + relativePath);
tasks = new TaskGroup().once('complete', function(err) {
var contentRendered, rendered;
if (err) {
file.log('warn', "Something went wrong while rendering: " + relativePath);
return next(err, opts.content, file);
}
contentRendered = opts.content;
if (contentRenderedWithoutLayouts == null) {
contentRenderedWithoutLayouts = contentRendered;
}
rendered = true;
file.set({
contentRendered: contentRendered,
contentRenderedWithoutLayouts: contentRenderedWithoutLayouts,
rendered: rendered
});
file.log('debug', "Rendering completed for: " + relativePath);
return next(null, opts.content, file);
});
if (__indexOf.call(opts.actions, 'renderExtensions') >= 0) {
tasks.addTask(function(complete) {
return file.renderExtensions(opts, function(err, result) {
if (err) {
return complete(err);
}
opts.content = result;
return complete();
});
});
}
if (__indexOf.call(opts.actions, 'renderDocument') >= 0) {
tasks.addTask(function(complete) {
return file.renderDocument(opts, function(err, result) {
if (err) {
return complete(err);
}
opts.content = result;
contentRenderedWithoutLayouts = result;
return complete();
});
});
}
if (__indexOf.call(opts.actions, 'renderLayouts') >= 0) {
tasks.addTask(function(complete) {
return file.renderLayouts(opts, function(err, result) {
if (err) {
return complete(err);
}
opts.content = result;
return complete();
});
});
}
tasks.run();
return this;
};
DocumentModel.prototype.writeRendered = function(opts, next) {
var file, _ref1;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
file = this;
opts.content || (opts.content = this.getOutContent());
opts.type || (opts.type = 'rendered document');
this.write(opts, next);
return this;
};
DocumentModel.prototype.writeSource = function(opts, next) {
var body, content, file, fullPath, header, meta, metaData, parser, seperator, source, _ref1;
file = this;
_ref1 = extractOptsAndCallback(opts, next), opts = _ref1[0], next = _ref1[1];
meta = this.getMeta();
if (!CSON) {
CSON = require('cson');
}
fullPath = this.get('fullPath');
content = (this.getContent() || '').toString();
parser = 'cson';
seperator = '---';
file.log('debug', "Writing the source file: " + fullPath);
metaData = meta.toJSON();
header = CSON.stringifySync(metaData);
content = body = content.replace(/^\s+/, '');
source = "" + seperator + " " + parser + "\n" + header + "\n" + seperator + "\n\n" + body;
this.set({
parser: parser,
header: header,
body: body,
content: content,
source: source
});
opts.path || (opts.path = fullPath);
opts.content || (opts.content = content);
opts.type || (opts.type = 'source document');
this.write(opts, next);
return this;
};
return DocumentModel;
})(FileModel);
module.exports = DocumentModel;