mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-11-04 09:33:00 +00:00 
			
		
		
		
	Use the new esprima parser to display javascript modules as parse trees
This commit is contained in:
		
							
								
								
									
										13
									
								
								js/App.js
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								js/App.js
									
									
									
									
									
								
							@@ -15,7 +15,6 @@ var WikiStore = require("./WikiStore.js").WikiStore,
 | 
				
			|||||||
	tiddlerOutput = require("./TiddlerOutput.js"),
 | 
						tiddlerOutput = require("./TiddlerOutput.js"),
 | 
				
			||||||
	Renderer = require("./Renderer.js").Renderer,
 | 
						Renderer = require("./Renderer.js").Renderer,
 | 
				
			||||||
	WikiTextParser = require("./WikiTextParser.js").WikiTextParser,
 | 
						WikiTextParser = require("./WikiTextParser.js").WikiTextParser,
 | 
				
			||||||
	JSONParser = require("./JSONParser.js").JSONParser,
 | 
					 | 
				
			||||||
	JavaScriptParser = require("./JavaScriptParser.js").JavaScriptParser,
 | 
						JavaScriptParser = require("./JavaScriptParser.js").JavaScriptParser,
 | 
				
			||||||
	ImageParser = require("./ImageParser.js").ImageParser;
 | 
						ImageParser = require("./ImageParser.js").ImageParser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,16 +26,8 @@ var App = function() {
 | 
				
			|||||||
	this.store = new WikiStore();	
 | 
						this.store = new WikiStore();	
 | 
				
			||||||
	// Register the parsers
 | 
						// Register the parsers
 | 
				
			||||||
	this.store.registerParser("text/x-tiddlywiki",new WikiTextParser({store: this.store}));
 | 
						this.store.registerParser("text/x-tiddlywiki",new WikiTextParser({store: this.store}));
 | 
				
			||||||
	this.store.registerParser("application/json",new JSONParser({store: this.store}));
 | 
						this.store.registerParser(["image/svg+xml","image/jpg","image/jpeg","image/png","image/gif"],new ImageParser({store: this.store}));
 | 
				
			||||||
	var imageParser = new ImageParser({store: this.store});
 | 
						this.store.registerParser(["application/json","application/javascript"],new JavaScriptParser({store: this.store}));
 | 
				
			||||||
	this.store.registerParser("image/svg+xml",imageParser);
 | 
					 | 
				
			||||||
	this.store.registerParser("image/jpg",imageParser);
 | 
					 | 
				
			||||||
	this.store.registerParser("image/jpeg",imageParser);
 | 
					 | 
				
			||||||
	this.store.registerParser("image/png",imageParser);
 | 
					 | 
				
			||||||
	this.store.registerParser("image/gif",imageParser);
 | 
					 | 
				
			||||||
	// Set up the JavaScript parser
 | 
					 | 
				
			||||||
	this.store.jsParser = new JavaScriptParser();
 | 
					 | 
				
			||||||
	this.store.registerParser("application/javascript",this.store.jsParser);
 | 
					 | 
				
			||||||
	// Register the standard tiddler serializers and deserializers
 | 
						// Register the standard tiddler serializers and deserializers
 | 
				
			||||||
	tiddlerInput.register(this.store);
 | 
						tiddlerInput.register(this.store);
 | 
				
			||||||
	tiddlerOutput.register(this.store);
 | 
						tiddlerOutput.register(this.store);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,52 +0,0 @@
 | 
				
			|||||||
/*\
 | 
					 | 
				
			||||||
title: js/JSONParser.js
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Compiles JSON objects into JavaScript functions that render them in HTML and plain text
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
\*/
 | 
					 | 
				
			||||||
(function(){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*jslint node: true */
 | 
					 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree,
 | 
					 | 
				
			||||||
    Renderer = require("./Renderer.js").Renderer,
 | 
					 | 
				
			||||||
    Dependencies = require("./Dependencies.js").Dependencies,
 | 
					 | 
				
			||||||
    utils = require("./Utils.js");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var renderObject = function(obj) {
 | 
					 | 
				
			||||||
    var children = [],t;
 | 
					 | 
				
			||||||
    if(obj instanceof Array) {
 | 
					 | 
				
			||||||
        for(t=0; t<obj.length; t++) {
 | 
					 | 
				
			||||||
            children.push(Renderer.ElementNode("li",{
 | 
					 | 
				
			||||||
                "class": ["jsonArrayMember"]
 | 
					 | 
				
			||||||
            },[renderObject(obj[t])]));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return Renderer.ElementNode("ul",{
 | 
					 | 
				
			||||||
            "class": ["jsonArray"]
 | 
					 | 
				
			||||||
        },children);
 | 
					 | 
				
			||||||
    } else if(typeof obj === "object") {
 | 
					 | 
				
			||||||
        for(t in obj) {
 | 
					 | 
				
			||||||
            children.push(Renderer.ElementNode("li",{
 | 
					 | 
				
			||||||
                "class": ["jsonObjectMember"]
 | 
					 | 
				
			||||||
            },[Renderer.SplitLabelNode("JSON",[Renderer.TextNode(t)],[renderObject(obj[t])])]));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return Renderer.ElementNode("ul",{
 | 
					 | 
				
			||||||
            "class": ["jsonObject"]
 | 
					 | 
				
			||||||
        },children);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        return Renderer.LabelNode("JSON" + (typeof obj),[Renderer.TextNode(JSON.stringify(obj))],["jsonValue"]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var JSONParser = function(options) {
 | 
					 | 
				
			||||||
    this.store = options.store;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
JSONParser.prototype.parse = function(type,text) {
 | 
					 | 
				
			||||||
	return new WikiTextParseTree([renderObject(JSON.parse(text))],new Dependencies(),this.store);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exports.JSONParser = JSONParser;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
})();
 | 
					 | 
				
			||||||
@@ -1,51 +0,0 @@
 | 
				
			|||||||
/*\
 | 
					 | 
				
			||||||
title: js/JavaScriptParseTree.js
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This object stores a JavaScript parse tree in the format produced by the pegjs JavaScript parser.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The parse tree represents the syntactical structure of a JavaScript program, represented as a tree
 | 
					 | 
				
			||||||
structure built from JavaScript arrays and objects. The nodes of the tree are objects with a "type"
 | 
					 | 
				
			||||||
field that indicates the type of the node (see the function compileNode() for a list of the types).
 | 
					 | 
				
			||||||
Depending on the type, other fields provide further details about the node.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The pegjs parser uses "StringLiteral" nodes to represent individual string literals. TiddlyWiki adds
 | 
					 | 
				
			||||||
support for nodes of type "StringLiterals" that represent a contiguous sequence of string constants.
 | 
					 | 
				
			||||||
This simplifies coalescing adjacent constants into a single string.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
\*/
 | 
					 | 
				
			||||||
(function(){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*jslint node: true */
 | 
					 | 
				
			||||||
"use strict";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var esprima = require("esprima"),
 | 
					 | 
				
			||||||
	utils = require("./Utils.js");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Create a new JavaScript tree object
 | 
					 | 
				
			||||||
var JavaScriptParseTree = function(tree) {
 | 
					 | 
				
			||||||
	this.tree = tree;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
JavaScriptParseTree.prototype.compile = function(targetType) {
 | 
					 | 
				
			||||||
	if(targetType === "application/javascript") {
 | 
					 | 
				
			||||||
		return this.compileJS();
 | 
					 | 
				
			||||||
	} else if(targetType === "text/html") {
 | 
					 | 
				
			||||||
		return {render: this.toString};
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		return null;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
JavaScriptParseTree.prototype.toString = function() {
 | 
					 | 
				
			||||||
	return JSON.stringify(this.tree);	
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Compile the entire JavaScript tree object to a renderer object
 | 
					 | 
				
			||||||
JavaScriptParseTree.prototype.compileJS = function() {
 | 
					 | 
				
			||||||
	/*jslint evil: true */
 | 
					 | 
				
			||||||
	return {render: eval(esprima.generate(this.tree))};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exports.JavaScriptParseTree = JavaScriptParseTree;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
})();
 | 
					 | 
				
			||||||
@@ -9,21 +9,49 @@ Parses JavaScript source code into a parse tree using PEGJS
 | 
				
			|||||||
/*jslint node: true */
 | 
					/*jslint node: true */
 | 
				
			||||||
"use strict";
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var JavaScriptParseTree = require("./JavaScriptParseTree.js").JavaScriptParseTree,
 | 
					var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree,
 | 
				
			||||||
 | 
					    Renderer = require("./Renderer.js").Renderer,
 | 
				
			||||||
 | 
					    Dependencies = require("./Dependencies.js").Dependencies,
 | 
				
			||||||
    esprima = require("esprima");
 | 
					    esprima = require("esprima");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var renderObject = function(obj) {
 | 
				
			||||||
 | 
					    var children = [],t;
 | 
				
			||||||
 | 
					    if(obj instanceof Array) {
 | 
				
			||||||
 | 
					        for(t=0; t<obj.length; t++) {
 | 
				
			||||||
 | 
					            children.push(Renderer.ElementNode("li",{
 | 
				
			||||||
 | 
					                "class": ["jsonArrayMember"]
 | 
				
			||||||
 | 
					            },[renderObject(obj[t])]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return Renderer.ElementNode("ul",{
 | 
				
			||||||
 | 
					            "class": ["jsonArray"]
 | 
				
			||||||
 | 
					        },children);
 | 
				
			||||||
 | 
					    } else if(typeof obj === "object") {
 | 
				
			||||||
 | 
					        for(t in obj) {
 | 
				
			||||||
 | 
					            children.push(Renderer.ElementNode("li",{
 | 
				
			||||||
 | 
					                "class": ["jsonObjectMember"]
 | 
				
			||||||
 | 
					            },[Renderer.SplitLabelNode("JSON",[Renderer.TextNode(t)],[renderObject(obj[t])])]));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return Renderer.ElementNode("ul",{
 | 
				
			||||||
 | 
					            "class": ["jsonObject"]
 | 
				
			||||||
 | 
					        },children);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        return Renderer.LabelNode("JSON" + (typeof obj),[Renderer.TextNode(JSON.stringify(obj))],["jsonValue"]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Initialise the parser
 | 
					// Initialise the parser
 | 
				
			||||||
var JavaScriptParser = function() {
 | 
					var JavaScriptParser = function(options) {
 | 
				
			||||||
 | 
					    this.store = options.store;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Parse a string of JavaScript code and return the parse tree
 | 
					// Parse a string of JavaScript code and return the parse tree as a wikitext parse tree
 | 
				
			||||||
JavaScriptParser.prototype.parse = function(code) {
 | 
					JavaScriptParser.prototype.parse = function(type,code) {
 | 
				
			||||||
	return new JavaScriptParseTree(esprima.parse(code));
 | 
						if(type === "application/json") {
 | 
				
			||||||
};
 | 
							code = "(" + code + ")";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
// Create a parse tree object from a raw tree
 | 
						return new WikiTextParseTree([
 | 
				
			||||||
JavaScriptParser.prototype.createTree = function(tree) {
 | 
							renderObject(esprima.parse(code))
 | 
				
			||||||
	return new JavaScriptParseTree(tree);
 | 
						],new Dependencies(),this.store);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exports.JavaScriptParser = JavaScriptParser;
 | 
					exports.JavaScriptParser = JavaScriptParser;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,8 @@ Renderer objects
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var utils = require("./Utils.js"),
 | 
					var utils = require("./Utils.js"),
 | 
				
			||||||
	ArgParser = require("./ArgParser.js").ArgParser,
 | 
						ArgParser = require("./ArgParser.js").ArgParser,
 | 
				
			||||||
	Dependencies = require("./Dependencies.js").Dependencies;
 | 
						Dependencies = require("./Dependencies.js").Dependencies,
 | 
				
			||||||
 | 
						esprima = require("esprima");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Node = function(children) {
 | 
					var Node = function(children) {
 | 
				
			||||||
	if(this instanceof Node) {
 | 
						if(this instanceof Node) {
 | 
				
			||||||
@@ -79,12 +80,13 @@ MacroNode.prototype = new Node();
 | 
				
			|||||||
MacroNode.prototype.constructor = MacroNode;
 | 
					MacroNode.prototype.constructor = MacroNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MacroNode.prototype.parseMacroParamString = function(paramString) {
 | 
					MacroNode.prototype.parseMacroParamString = function(paramString) {
 | 
				
			||||||
 | 
						/*jslint evil: true */
 | 
				
			||||||
	var params = {},
 | 
						var params = {},
 | 
				
			||||||
		args = new ArgParser(paramString,{defaultName: "anon", cascadeDefaults: this.macro.cascadeDefaults}),
 | 
							args = new ArgParser(paramString,{defaultName: "anon", cascadeDefaults: this.macro.cascadeDefaults}),
 | 
				
			||||||
		self = this,
 | 
							self = this,
 | 
				
			||||||
		insertParam = function(name,arg) {
 | 
							insertParam = function(name,arg) {
 | 
				
			||||||
			if(arg.evaluated) {
 | 
								if(arg.evaluated) {
 | 
				
			||||||
				params[name] = self.store.jsParser.createTree( // (function(tiddler,store,utils) {return {paramOne: 1};})
 | 
									params[name] = eval(esprima.generate( // (function(tiddler,store,utils) {return {paramOne: 1};})
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						"type": "Program",
 | 
											"type": "Program",
 | 
				
			||||||
						"body": [
 | 
											"body": [
 | 
				
			||||||
@@ -112,7 +114,7 @@ MacroNode.prototype.parseMacroParamString = function(paramString) {
 | 
				
			|||||||
										"body": [
 | 
															"body": [
 | 
				
			||||||
											{
 | 
																{
 | 
				
			||||||
												"type": "ReturnStatement",
 | 
																	"type": "ReturnStatement",
 | 
				
			||||||
												"argument": self.store.jsParser.parse("(" + arg.string + ")").tree.body[0].expression
 | 
																	"argument": esprima.parse("(" + arg.string + ")").body[0].expression
 | 
				
			||||||
											}
 | 
																}
 | 
				
			||||||
										]
 | 
															]
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
@@ -120,7 +122,7 @@ MacroNode.prototype.parseMacroParamString = function(paramString) {
 | 
				
			|||||||
							}
 | 
												}
 | 
				
			||||||
						]
 | 
											]
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				).compile("application/javascript").render;
 | 
									));
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				params[name] = arg.string;
 | 
									params[name] = arg.string;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,13 @@ var WikiStore = function WikiStore(options) {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WikiStore.prototype.registerParser = function(type,parser) {
 | 
					WikiStore.prototype.registerParser = function(type,parser) {
 | 
				
			||||||
 | 
						if(type instanceof Array) {
 | 
				
			||||||
 | 
							for(var t=0; t<type.length; t++) {
 | 
				
			||||||
 | 
								this.parsers[type[t]] = parser;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		this.parsers[type] = parser;
 | 
							this.parsers[type] = parser;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WikiStore.prototype.registerTiddlerSerializer = function(extension,mimeType,serializer) {
 | 
					WikiStore.prototype.registerTiddlerSerializer = function(extension,mimeType,serializer) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user