/* TiddlyWiki command line interface */ /*global require: false, exports: false, process: false */ "use strict"; var WikiStore = require("./js/WikiStore.js").WikiStore, Tiddler = require("./js/Tiddler.js").Tiddler, Recipe = require("./js/Recipe.js").Recipe, Tiddler = require("./js/Tiddler.js").Tiddler, tiddlerOutput = require("./js/TiddlerOutput.js"), tiddlerInput = require("./js/TiddlerInput.js"), util = require("util"), fs = require("fs"), url = require("url"), path = require("path"), aync = require("async"), http = require("http"); var parseOptions = function(args,defaultSwitch) { var result = [], a = 0, switchRegExp = /^--([\S]+)$/gi; while(a < args.length) { switchRegExp.lastIndex = 0; var m = switchRegExp.exec(args[a]); if(m) { a++; var switchArgs = []; switchRegExp.lastIndex = 0; while(a < args.length && !switchRegExp.test(args[a])) { switchArgs.push(args[a++]); switchRegExp.lastIndex = 0; } result.push({switch: m[1], args: switchArgs}); } else { result.push({switch: defaultSwitch, args: [args[a++]]}); } } return result; }; var switches = parseOptions(Array.prototype.slice.call(process.argv,2),"dummy"), store = new WikiStore(), recipe = null, lastRecipeFilepath = null, currSwitch = 0; // Add the shadow tiddlers that are built into TiddlyWiki var shadowShadowStore = new WikiStore(null), shadowShadows = [ {title: "StyleSheet", text: ""}, {title: "MarkupPreHead", text: ""}, {title: "MarkupPostHead", text: ""}, {title: "MarkupPreBody", text: ""}, {title: "MarkupPostBody", text: ""}, {title: "TabTimeline", text: "<>"}, {title: "TabAll", text: "<>"}, {title: "TabTags", text: "<>"}, {title: "TabMoreMissing", text: "<>"}, {title: "TabMoreOrphans", text: "<>"}, {title: "TabMoreShadowed", text: "<>"}, {title: "AdvancedOptions", text: "<>"}, {title: "PluginManager", text: "<>"}, {title: "SystemSettings", text: ""}, {title: "ToolbarCommands", text: "|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|"}, {title: "WindowTitle", text: "<> - <>"}, {title: "DefaultTiddlers", text: "[[GettingStarted]]"}, {title: "MainMenu", text: "[[GettingStarted]]"}, {title: "SiteTitle", text: "My TiddlyWiki"}, {title: "SiteSubtitle", text: "a reusable non-linear personal web notebook"}, {title: "SiteUrl", text: ""}, {title: "SideBarOptions", text: '<><><><><><><>'}, {title: "SideBarTabs", text: '<>'}, {title: "TabMore", text: '<>'} ]; store.shadows.shadows = shadowShadowStore; for(var t=0; t csw.args.max) { throw "Command line switch --" + s.switch + " should have a maximum of " + csw.args.max + " arguments" } csw.handler(s.args,function (err) { if(err) { throw err; } process.nextTick(processNextSwitch); }); } }; process.nextTick(processNextSwitch); /* Each command line switch is represented by a function that takes a string array of arguments and a callback to be invoked when the switch processing has completed. The only argument to the callback is an error code, or null for success. */ var commandLineSwitches = { recipe: { args: {min: 1, max: 1}, handler: function(args,callback) { if(recipe) { callback("--recipe: Cannot process more than one recipe file"); } else { lastRecipeFilepath = args[0]; recipe = new Recipe(store,args[0],function() { callback(null); }); } } }, dumpstore: { args: {min: 0, max: 0}, handler: function(args,callback) { console.log("Store is:\n%s",util.inspect(store,false,10)); process.nextTick(function() {callback(null);}); } }, load: { args: {min: 1, max: 1}, handler: function(args,callback) { fs.readFile(args[0],"utf8",function(err,data) { if(err) { callback(err); } else { var fields = {title: args[0]}, extname = path.extname(args[0]), type = extname === ".html" ? "application/x-tiddlywiki" : extname; var tiddlers = tiddlerInput.parseTiddlerFile(data,type,fields); for(var t=0; t 0 ? args[0] : 8000; // Dumbly, this implementation wastes the recipe processing that happened on the --recipe switch http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/html"}); store = new WikiStore(); recipe = new Recipe(store,lastRecipeFilepath,function() { response.end(recipe.cook(), "utf8"); }); }).listen(port); } }, servetiddlers: { args: {min: 0, max: 1}, handler: function(args,callback) { var port = args.length > 0 ? args[0] : 8000; http.createServer(function (request, response) { var title = decodeURIComponent(url.parse(request.url).pathname.substr(1)), tiddler = store.getTiddler(title); if(tiddler) { response.writeHead(200, {"Content-Type": "text/html"}); response.end(tiddler.getParseTree().render("text/html"),"utf8"); } else { response.writeHead(404); response.end(); } }).listen(port); } }, verbose: { args: {min: 0, max: 0}, handler: function(args,callback) { process.nextTick(function() {callback(null);}); } } };