1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-10-02 17:00:45 +00:00

Use the new esprima parser to display javascript modules as parse trees

This commit is contained in:
Jeremy Ruston 2012-03-01 23:59:46 +00:00
parent a274bad1a2
commit 8552f2f894
6 changed files with 54 additions and 130 deletions

View File

@ -15,7 +15,6 @@ var WikiStore = require("./WikiStore.js").WikiStore,
tiddlerOutput = require("./TiddlerOutput.js"),
Renderer = require("./Renderer.js").Renderer,
WikiTextParser = require("./WikiTextParser.js").WikiTextParser,
JSONParser = require("./JSONParser.js").JSONParser,
JavaScriptParser = require("./JavaScriptParser.js").JavaScriptParser,
ImageParser = require("./ImageParser.js").ImageParser;
@ -27,16 +26,8 @@ var App = function() {
this.store = new WikiStore();
// Register the parsers
this.store.registerParser("text/x-tiddlywiki",new WikiTextParser({store: this.store}));
this.store.registerParser("application/json",new JSONParser({store: this.store}));
var imageParser = new ImageParser({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);
this.store.registerParser(["image/svg+xml","image/jpg","image/jpeg","image/png","image/gif"],new ImageParser({store: this.store}));
this.store.registerParser(["application/json","application/javascript"],new JavaScriptParser({store: this.store}));
// Register the standard tiddler serializers and deserializers
tiddlerInput.register(this.store);
tiddlerOutput.register(this.store);

View File

@ -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;
})();

View File

@ -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;
})();

View File

@ -9,21 +9,49 @@ Parses JavaScript source code into a parse tree using PEGJS
/*jslint node: true */
"use strict";
var JavaScriptParseTree = require("./JavaScriptParseTree.js").JavaScriptParseTree,
esprima = require("esprima");
var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree,
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
var JavaScriptParser = function() {
var JavaScriptParser = function(options) {
this.store = options.store;
};
// Parse a string of JavaScript code and return the parse tree
JavaScriptParser.prototype.parse = function(code) {
return new JavaScriptParseTree(esprima.parse(code));
};
// Create a parse tree object from a raw tree
JavaScriptParser.prototype.createTree = function(tree) {
return new JavaScriptParseTree(tree);
// Parse a string of JavaScript code and return the parse tree as a wikitext parse tree
JavaScriptParser.prototype.parse = function(type,code) {
if(type === "application/json") {
code = "(" + code + ")";
}
return new WikiTextParseTree([
renderObject(esprima.parse(code))
],new Dependencies(),this.store);
};
exports.JavaScriptParser = JavaScriptParser;

View File

@ -11,7 +11,8 @@ Renderer objects
var utils = require("./Utils.js"),
ArgParser = require("./ArgParser.js").ArgParser,
Dependencies = require("./Dependencies.js").Dependencies;
Dependencies = require("./Dependencies.js").Dependencies,
esprima = require("esprima");
var Node = function(children) {
if(this instanceof Node) {
@ -79,12 +80,13 @@ MacroNode.prototype = new Node();
MacroNode.prototype.constructor = MacroNode;
MacroNode.prototype.parseMacroParamString = function(paramString) {
/*jslint evil: true */
var params = {},
args = new ArgParser(paramString,{defaultName: "anon", cascadeDefaults: this.macro.cascadeDefaults}),
self = this,
insertParam = function(name,arg) {
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",
"body": [
@ -112,7 +114,7 @@ MacroNode.prototype.parseMacroParamString = function(paramString) {
"body": [
{
"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 {
params[name] = arg.string;
}

View File

@ -39,7 +39,13 @@ var WikiStore = function WikiStore(options) {
};
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) {