mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-10 11:59:58 +00:00
Added command handling
The idea is that the same commands will work on the server or the client, and that the client will be able to remotely run commands on the server. Also includes abstraction of the version number of TW5.
This commit is contained in:
parent
12bf2b6fb9
commit
dac06537e5
@ -35,6 +35,9 @@ if(typeof(window) === "undefined" && !global.$tw) {
|
||||
global.$tw = {isBrowser: false};
|
||||
}
|
||||
|
||||
// Boot information
|
||||
$tw.boot = {};
|
||||
|
||||
// Modules store registers all the modules the system has seen
|
||||
$tw.modules = $tw.modules || {};
|
||||
$tw.modules.titles = $tw.modules.titles || {} // hashmap by module title of {fn:, exports:, moduleType:}
|
||||
@ -523,6 +526,8 @@ var fs = require("fs"),
|
||||
path = require("path"),
|
||||
vm = require("vm");
|
||||
|
||||
$tw.boot.bootPath = path.dirname(module.filename);
|
||||
|
||||
/*
|
||||
Load the tiddlers contained in a particular file (and optionally the accompanying .meta file)
|
||||
*/
|
||||
@ -574,6 +579,7 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
module: module,
|
||||
exports: {},
|
||||
console: console,
|
||||
process: process,
|
||||
$tw: $tw,
|
||||
require: function(title) {
|
||||
return $tw.modules.execute(title,name);
|
||||
@ -598,7 +604,7 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
|
||||
}
|
||||
|
||||
// Load plugins from the plugins directory
|
||||
$tw.plugins.loadPlugins(path.resolve(path.dirname(module.filename),$tw.config.pluginSubDir));
|
||||
$tw.plugins.loadPlugins(path.resolve($tw.boot.bootPath,$tw.config.pluginSubDir));
|
||||
|
||||
// End of if(!$tw.isBrowser)
|
||||
}
|
||||
|
93
rabbithole/core/modules/commander.js
Normal file
93
rabbithole/core/modules/commander.js
Normal file
@ -0,0 +1,93 @@
|
||||
/*\
|
||||
title: $:/core/commander.js
|
||||
type: application/javascript
|
||||
module-type: global
|
||||
|
||||
The $tw.Commander class is a command interpreter
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Parse a sequence of commands
|
||||
commandTokens: an array of command string tokens
|
||||
wiki: reference to the wiki store object
|
||||
streams: {output:, error:}, each of which has a write(string) method
|
||||
callback: a callback invoked as callback(err) where err is null if there was no error
|
||||
*/
|
||||
var Commander = function(commandTokens,callback,wiki,streams) {
|
||||
this.commandTokens = commandTokens;
|
||||
this.nextToken = 0;
|
||||
this.callback = callback;
|
||||
this.wiki = wiki;
|
||||
this.streams = streams;
|
||||
};
|
||||
|
||||
/*
|
||||
Execute the sequence of commands and invoke a callback on completion
|
||||
*/
|
||||
Commander.prototype.execute = function() {
|
||||
this.executeNextCommand();
|
||||
};
|
||||
|
||||
/*
|
||||
Execute the next command in the sequence
|
||||
*/
|
||||
Commander.prototype.executeNextCommand = function() {
|
||||
// Invoke the callback if there are no more commands
|
||||
if(this.nextToken >= this.commandTokens.length) {
|
||||
this.callback(null);
|
||||
} else {
|
||||
// Get and check the command token
|
||||
var commandName = this.commandTokens[this.nextToken++];
|
||||
if(commandName.substr(0,2) !== "--") {
|
||||
this.callback("Missing command");
|
||||
} else {
|
||||
commandName = commandName.substr(2); // Trim off the --
|
||||
// Accumulate the parameters to the command
|
||||
var params = [];
|
||||
while(this.nextToken < this.commandTokens.length &&
|
||||
this.commandTokens[this.nextToken].substr(0,2) !== "--") {
|
||||
params.push(this.commandTokens[this.nextToken++]);
|
||||
}
|
||||
// Get the command info
|
||||
var command = $tw.commands[commandName];
|
||||
if(!command) {
|
||||
this.callback("Unknown command: " + commandName);
|
||||
} else {
|
||||
if(command.info.synchronous) {
|
||||
var c = new command.Command(params,this);
|
||||
c.execute();
|
||||
this.executeNextCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Commander.initCommands = function(moduleType) {
|
||||
// Install the command modules
|
||||
moduleType = moduleType || "command";
|
||||
$tw.commands = {};
|
||||
var modules = $tw.plugins.moduleTypes[moduleType],
|
||||
n,m,f,c;
|
||||
if(modules) {
|
||||
for(n=0; n<modules.length; n++) {
|
||||
m = modules[n];
|
||||
$tw.commands[m.info.name] = {};
|
||||
c = $tw.commands[m.info.name];
|
||||
// Add the methods defined by the module
|
||||
for(f in m) {
|
||||
c[f] = m[f];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.Commander = Commander;
|
||||
|
||||
})();
|
30
rabbithole/core/modules/commands/version.js
Normal file
30
rabbithole/core/modules/commands/version.js
Normal file
@ -0,0 +1,30 @@
|
||||
/*\
|
||||
title: $:/core/commands/version.js
|
||||
type: application/javascript
|
||||
module-type: command
|
||||
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
"use strict";
|
||||
|
||||
exports.info = {
|
||||
name: "version",
|
||||
synchronous: true,
|
||||
params: {}
|
||||
}
|
||||
|
||||
var Command = function(params,commander) {
|
||||
this.params = params;
|
||||
this.commander = commander;
|
||||
};
|
||||
|
||||
Command.prototype.execute = function() {
|
||||
this.commander.streams.output.write($tw.utils.getVersionString() + "\n");
|
||||
}
|
||||
|
||||
exports.Command = Command;
|
||||
|
||||
})();
|
@ -16,7 +16,7 @@ exports.info = {
|
||||
}
|
||||
|
||||
exports.executeMacro = function() {
|
||||
return [$tw.Tree.Text("5.0.0")];
|
||||
return [$tw.Tree.Text($tw.utils.getVersionString())];
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -18,6 +18,7 @@ exports.startup = function() {
|
||||
// Wire up plugin modules
|
||||
$tw.plugins.applyMethods("config",$tw.config);
|
||||
$tw.plugins.applyMethods("utils",$tw.utils);
|
||||
$tw.version = $tw.utils.extractVersionInfo();
|
||||
$tw.plugins.applyMethods("tiddlermethod",$tw.Tiddler.prototype);
|
||||
$tw.plugins.applyMethods("wikimethod",$tw.Wiki.prototype);
|
||||
$tw.plugins.applyMethods("treeutils",$tw.Tree);
|
||||
@ -26,6 +27,8 @@ exports.startup = function() {
|
||||
$tw.wiki.initMacros();
|
||||
$tw.wiki.initEditors();
|
||||
$tw.wiki.initParsers();
|
||||
// Set up the command plugins
|
||||
$tw.Commander.initCommands();
|
||||
|
||||
if($tw.isBrowser) {
|
||||
var renderer = $tw.wiki.parseTiddler("PageTemplate");
|
||||
@ -36,7 +39,17 @@ if($tw.isBrowser) {
|
||||
});
|
||||
console.log("$tw",$tw);
|
||||
} else {
|
||||
console.log("$tw",require("util").inspect($tw,false,8));
|
||||
var commander = new $tw.Commander(
|
||||
Array.prototype.slice.call(process.argv,2),
|
||||
function(err) {
|
||||
if(err) {
|
||||
console.log("Error: " + err);
|
||||
}
|
||||
},
|
||||
$tw.wiki,
|
||||
{output: process.stdout, error: process.stderr}
|
||||
);
|
||||
commander.execute();
|
||||
}
|
||||
|
||||
|
||||
|
@ -219,4 +219,62 @@ exports.applyStyleSheet = function(id,css) {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Parse a version number string of the form "1.2.3", "1.2.3.a4", or "1.2.3.b4" into:
|
||||
{major: <number>, minor: <number>, revision: <number>, alpha: <number>, beta: <number>}
|
||||
*/
|
||||
exports.parseVersion = function(versionString) {
|
||||
versionString = versionString || "0.0.0";
|
||||
var components = versionString.split("."),
|
||||
version = {
|
||||
major: components[0] ? parseInt(components[0],10) : null,
|
||||
minor: components[1] ? parseInt(components[1],10) : null,
|
||||
revision: components[2] ? parseInt(components[2],10) : null
|
||||
};
|
||||
if(components[3]) {
|
||||
if(components[3].charAt(0) === "a") {
|
||||
version.alpha = parseInt(components[3].substr(1),10);
|
||||
} else if(components[3].charAt(0) === "b") {
|
||||
version.beta = parseInt(components[3].substr(1),10);
|
||||
}
|
||||
}
|
||||
return version;
|
||||
};
|
||||
|
||||
exports.getVersionString = function() {
|
||||
return ($tw.version.major || "0") + "." +
|
||||
($tw.version.minor || "0") + "." +
|
||||
($tw.version.revision || "0") +
|
||||
($tw.version.alpha ? ".a" + $tw.version.alpha : "") +
|
||||
($tw.version.beta ? ".b" + $tw.version.beta : "");
|
||||
};
|
||||
|
||||
/*
|
||||
Extract the version number from the meta tag or from the boot file
|
||||
*/
|
||||
|
||||
if($tw.isBrowser) {
|
||||
|
||||
// Browser version
|
||||
exports.extractVersionInfo = function() {
|
||||
var metatags = document.getElementsByTagName("meta");
|
||||
for(var t=0; t<metatags.length; t++) {
|
||||
var m = metatags[t];
|
||||
if(m.name === "tiddlywiki-version") {
|
||||
return $tw.utils.parseVersion(m.content);
|
||||
}
|
||||
}
|
||||
return $tw.utils.parseVersion();
|
||||
};
|
||||
|
||||
} else {
|
||||
|
||||
// Server version
|
||||
exports.extractVersionInfo = function() {
|
||||
var fs = require("fs");
|
||||
return $tw.utils.parseVersion(fs.readFileSync($tw.boot.bootPath + "/version.txt").toString("utf8"));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -252,6 +252,21 @@ exports.parseTiddler = function(title) {
|
||||
}) : null;
|
||||
};
|
||||
|
||||
/*
|
||||
Parse text in a specified format and render it into another format
|
||||
outputType: content type for the output
|
||||
textType: content type of the input text
|
||||
text: input text
|
||||
options: see below
|
||||
Options are:
|
||||
defaultType: Default MIME type to use if the specified one is unknown
|
||||
*/
|
||||
exports.renderText = function(outputType,textType,text,options) {
|
||||
var renderer = this.parseText(type,text,options);
|
||||
renderer.execute([]);
|
||||
return renderer.render(outputType);
|
||||
};
|
||||
|
||||
/*
|
||||
Install macro plugins into this wiki
|
||||
moduleType: Plugin type to install (defaults to "macro")
|
||||
|
1
rabbithole/core/version.txt
Normal file
1
rabbithole/core/version.txt
Normal file
@ -0,0 +1 @@
|
||||
5.0.0.a2
|
@ -57,6 +57,7 @@ The 'core' is the boot kernel plus the set of plugin modules that it loads. It c
|
||||
* `editor` - interactive editors for different types of content
|
||||
* `parser` - parsers for different types of content
|
||||
* `wikitextrule` - individual rules for the wikitext parser
|
||||
* `command` - individual commands for the `$tw.Commander` class
|
||||
|
||||
TiddlyWiki5 makes extensive use of JavaScript inheritance:
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
template: tiddlywiki5.template.html
|
||||
copyright: copyright.txt
|
||||
version: core/version.txt
|
||||
|
||||
jsbootstart: core/bootprefix.js
|
||||
jsbootend: core/boot.js
|
||||
|
||||
pluginmodule: core/modules/*.js
|
||||
pluginmodule: core/modules/commands/*.js
|
||||
pluginmodule: core/modules/macros/*.js
|
||||
pluginmodule: core/modules/macros/edit/*.js
|
||||
pluginmodule: core/modules/macros/edit/editors/*.js
|
||||
|
@ -1,6 +1,11 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="application-name" content="TiddlyWiki" />
|
||||
<meta name="generator" content="TiddlyWiki" />
|
||||
<meta name="tiddlywiki-version" content="
|
||||
<!--@@version@@-->
|
||||
" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
|
@ -4,4 +4,4 @@ tags: Introduction
|
||||
|
||||
Welcome to TiddlyWiki5, a reboot of TiddlyWiki, the venerable, reusable non-linear personal web notebook first released in 2004. It is a complete interactive wiki that can run from a single HTML file in the browser or as a powerful [[node.js application|What is node.js?]].
|
||||
|
||||
TiddlyWiki5 is currently in early beta, which is to say that it is useful but incomplete. You can try out the prototype at http://tiddlywiki.com/tiddlywiki5, get involved in the [[development on GitHub|https://github.com/Jermolene/TiddlyWiki5]] or the discussions on [[the TiddlyWikiDev Google Group|http://groups.google.com/group/TiddlyWikiDev]].
|
||||
TiddlyWiki5 is currently at version <<version>> and is under active development, which is to say that it is useful but incomplete. You can try out the prototype at http://tiddlywiki.com/tiddlywiki5, get involved in the [[development on GitHub|https://github.com/Jermolene/TiddlyWiki5]] or the discussions on [[the TiddlyWikiDev Google Group|http://groups.google.com/group/TiddlyWikiDev]].
|
||||
|
Loading…
Reference in New Issue
Block a user