mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-10-30 23:23:02 +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, | ||||||
| 	esprima = require("esprima"); |     Renderer = require("./Renderer.js").Renderer, | ||||||
|  |     Dependencies = require("./Dependencies.js").Dependencies, | ||||||
|  |     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) { | ||||||
| 	this.parsers[type] = parser; | 	if(type instanceof Array) { | ||||||
|  | 		for(var t=0; t<type.length; t++) { | ||||||
|  | 			this.parsers[type[t]] = parser; | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		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
	 Jeremy Ruston
					Jeremy Ruston