Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 32 additions & 31 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var extend = require('extend');
var fs = require('fs');
var path = require('path');
var async = require('async');
var iconv = require('iconv-lite');


var syntaxReg = /<!--#([^\r\n]+?)-->/mg;
Expand All @@ -42,15 +43,15 @@ var endifReg = /<!--#\s*endif\s*-->/;
* @since 0.1.0
* @version 0.1.2
*/
function resolve(tpl) {
function resolve (tpl) {
//resolve set/echo/if
var fnStr = 'var _r="";\nwith(__data){\n';
var matches, key, val, pat, eq;

var start = 0,
lastMatches;

var resolveLine = function(str) {
var resolveLine = function (str) {
//This is stupid but works for "\r\b\f\u\v\n".
//Here we assume line break is "\n"
return str.replace(/\r/mg, '').replace(/\\/mg, '\\\\').replace(/"/mg, '\\"').replace(/\n/mg, '\\n\\\n');
Expand Down Expand Up @@ -122,7 +123,7 @@ function resolve(tpl) {
* @since 0.1.0
* @version 0.1.0
*/
var SSI = function(initOptions) {
var SSI = function (initOptions) {
this.options = extend({
baseDir: '.',
encoding: 'utf-8',
Expand All @@ -144,7 +145,7 @@ SSI.prototype = {
*
* @param {Object} config
*/
setDefaultOptions: function(options) {
setDefaultOptions: function (options) {
return extend(this.options, options || {});
},
/**
Expand All @@ -165,7 +166,7 @@ SSI.prototype = {
* @param {Object} options
* @param {Function} callback
*/
compile: function(content, options, callback) {
compile: function (content, options, callback) {
var func;

if (arguments.length < 3) {
Expand All @@ -175,8 +176,8 @@ SSI.prototype = {

options = extend({}, this.options, options || {});

this.resolveIncludes(content, options, function(err, content) {
if(err) {
this.resolveIncludes(content, options, function (err, content) {
if (err) {
return callback(err);
}

Expand All @@ -196,46 +197,45 @@ SSI.prototype = {
* @param options
* @param callback
*/
resolveIncludes: function(content, options, callback) {
resolveIncludes: function (content, options, callback) {
var matches, seg, isVirtual, basePath, tpath, subOptions, ssi = this;

async.whilst( // https://www.npmjs.org/package/async#whilst-test-fn-callback-
function test() {return !!(matches = includeFileReg.exec(content)); },
function insertInclude(next) {
function test () { return !!(matches = includeFileReg.exec(content)); },
function insertInclude (next) {
seg = matches[0];
isVirtual = RegExp.$1 == 'virtual';
basePath = (isVirtual && options.dirname && RegExp.$3.charAt(0) !== '/')? options.dirname : options.baseDir;
basePath = (isVirtual && options.dirname && RegExp.$3.charAt(0) !== '/') ? options.dirname : options.baseDir;
tpath = path.join(basePath, RegExp.$3);
fs.lstat(tpath,
function(err, stats) {
function (err, stats) {
if (err) {
return next(err);
}
if (stats.isDirectory()) {
tpath = tpath.replace(/(\/)?$/, '/index.html');
}
fs.readFile(tpath, {
encoding: options.encoding
}, function(err, innerContentRaw) {
fs.readFile(tpath, function (err, innerContentRaw) {
if (err) {
return next(err);
}
innerContentRaw = iconv.decode(innerContentRaw, options.encoding);
// ensure that included files can include other files with relative paths
subOptions = extend({}, options, { dirname: path.dirname(tpath) });
ssi.resolveIncludes(innerContentRaw, subOptions, function (err, innerContent) {
if (err) {
return next(err);
}
// ensure that included files can include other files with relative paths
subOptions = extend({}, options, {dirname: path.dirname(tpath)});
ssi.resolveIncludes(innerContentRaw, subOptions, function(err, innerContent) {
if (err) {
return next(err);
}
content = content.slice(0, matches.index) + innerContent + content.slice(matches.index + seg.length);
next(null, content);
});
}
content = content.slice(0, matches.index) + innerContent + content.slice(matches.index + seg.length);
next(null, content);
});
}
);
}
);

},
function includesComplete(err) {
function includesComplete (err) {
if (err) {
return callback(err);
}
Expand All @@ -249,7 +249,7 @@ SSI.prototype = {
* @param {Object} options
* @param {Function} callback
*/
compileFile: function(filepath, options, callback) {
compileFile: function (filepath, options, callback) {

if (arguments.length < 3) {
callback = options;
Expand All @@ -261,12 +261,13 @@ SSI.prototype = {

var ssi = this;

return fs.readFile(filepath, {
encoding: options.encoding
}, function(err, content) {
return fs.readFile(filepath, function (err, content) {
if (err) {
return callback(err);
} else return ssi.compile(content, options, callback);
} else {
content = iconv.decode(content, options.encoding);
return ssi.compile(content, options, callback);
}
});
}
};
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-ssi",
"version": "0.3.2",
"version": "0.3.3",
"description": "A SSI parser",
"main": "index.js",
"scripts": {
Expand All @@ -27,6 +27,7 @@
},
"dependencies": {
"async": "~1.4.2",
"extend": "~3.0.0"
"extend": "~3.0.0",
"iconv-lite": "^0.4.19"
}
}
}