diff --git a/js/FileRetriever.js b/js/FileRetriever.js index f4bdfe3c7..bb1ea9d25 100644 --- a/js/FileRetriever.js +++ b/js/FileRetriever.js @@ -1,7 +1,7 @@ /*\ title: js/FileRetriever.js -FileRetriever can asynchronously retrieve files from HTTP URLs or the local file system +FileRetriever can asynchronously retrieve files from HTTP URLs or the local file system. Files are treated as utf-8 text or, if the filepath ends in one of the recognised binary extensions, as a base64 encoded binary string \*/ (function(){ @@ -18,13 +18,16 @@ var fs = require("fs"), var FileRetriever = exports; +// These are the file extensions that we'll recognise as binary. FileRetriever.binaryFileExtensions = [".jpg",".jpeg",".png",".gif"]; +// Retrieve a local file and invoke callback(err,data) in the usual way var fileRequest = function fileRequest(filepath,callback) { fs.readFile(filepath, function (err,data) { if(err) { callback(err); } else { + // Check if we need to base64 encode the file if(FileRetriever.binaryFileExtensions.indexOf(path.extname(filepath)) !== -1) { callback(err,data.toString("base64")); } else { @@ -34,6 +37,7 @@ var fileRequest = function fileRequest(filepath,callback) { }); }; +// Retrieve a file over HTTP and invoke callback(err,data) in the usual way var httpRequest = function(fileurl,callback) { var opts = url.parse(fileurl), httpLib = opts.protocol === "http:" ? http : https, diff --git a/js/Recipe.js b/js/Recipe.js index 301079b71..a97d1bdfc 100755 --- a/js/Recipe.js +++ b/js/Recipe.js @@ -1,8 +1,6 @@ /*\ title: js/Recipe.js -FileRetriever can asynchronously retrieve files from HTTP URLs or the local file system - Recipe processing is in four parts: 1) The recipe file is parsed and any subrecipe files loaded recursively into this structure: @@ -31,7 +29,7 @@ At this point tiddlers are placed in the store so that they can be referenced by ... } -4) Finally, the template is processed by replacing the markers with the text of the associated tiddlers +4) Finally, to actually cook the recipe, the template is processed by replacing the markers with the text of the associated tiddlers \*/ (function(){ @@ -47,6 +45,18 @@ var Tiddler = require("./Tiddler.js").Tiddler, util = require("util"), async = require("async"); +/* +Load a recipe file. Arguments are: + + options: See below + callback: Function to be called when the recipe has been loaded as callback(err), null === success + +Options include: + + filepath: The filepath of the recipe file to load. Can be a local path or an HTTP URL + store: Indicates the WikiStore to use to store the tiddlers (mandatory) + +*/ var Recipe = function(options,callback) { var me = this; this.filepath = options.filepath; @@ -54,6 +64,7 @@ var Recipe = function(options,callback) { this.callback = callback; this.recipe = []; this.markers = {}; + // A task queue for loading recipe files this.recipeQueue = async.queue(function(task,callback) { retrieveFile(task.filepath,task.contextPath,function(err,data) { if(err) { @@ -64,6 +75,7 @@ var Recipe = function(options,callback) { } }); },1); + // A task queue for loading tiddler files this.tiddlerQueue = async.queue(function(task,callback) { me.readTiddlerFile(task.filepath,task.contextPath,function(err,data) { if(err) { @@ -76,47 +88,87 @@ var Recipe = function(options,callback) { } } } - task.recipeLine.tiddlers = data; + if(!task.recipeLine.tiddlers) { + task.recipeLine.tiddlers = []; + } + Array.prototype.push.apply(task.recipeLine.tiddlers,data); callback(null); } }); },1); + // Called when all the recipes have been loaded this.recipeQueue.drain = function() { - me.loadTiddlerFiles(me.recipe); + // Initiate the loading of the tiddlers referenced by the recipe + for(var r=0; r