Skip to content

Commit

Permalink
* First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
joehewitt committed Jul 9, 2011
0 parents commit c6fcd24
Show file tree
Hide file tree
Showing 24 changed files with 6,015 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
node_modules
build*
*.o
.dropbox
13 changes: 13 additions & 0 deletions LICENSE
@@ -0,0 +1,13 @@
Copyright 2011 Joe Hewitt

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
6 changes: 6 additions & 0 deletions Makefile
@@ -0,0 +1,6 @@
default: test

test:
vows test/*-test.js

.PHONY: test
26 changes: 26 additions & 0 deletions README.md
@@ -0,0 +1,26 @@
markdom
========

A Markdown parser than can create and transform a DOM before generating HTML.

Installation
------------

$ npm install markdom

License
-------

Copyright 2011 Joe Hewitt

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
124 changes: 124 additions & 0 deletions lib/NodeHandler.js
@@ -0,0 +1,124 @@

var NodeTypes = require('./nodes');

// *************************************************************************************************

function NodeHandler(context) {
this.nodes = {};
this.nodeCount = 0;
this.context = context;
this.embeds = [];
}
exports.NodeHandler = NodeHandler;

NodeHandler.prototype = {
header: function(level, content) {
return this.createNode(new NodeTypes.Header(level, this.getNodes(content)));
},

paragraph: function(content) {
return this.createNode(new NodeTypes.Paragraph(this.getNodes(content)));
},

blockquote: function(content) {
return this.createNode(new NodeTypes.Blockquote(this.getNodes(content)));
},

blockCode: function(lang, text) {
return this.createNode(new NodeTypes.BlockCode(lang, text));
},

blockHTML: function(text) {
return this.createNode(new NodeTypes.BlockHTML(text));
},

list: function(level, content) {
return this.createNode(new NodeTypes.List(level, this.getNodes(content)));
},

listItem: function(content) {
return this.createNode(new NodeTypes.ListItem(this.getNodes(content)));
},

table: function(header, body) {
return this.createNode(new NodeTypes.Table(this.getNodes(header), this.getNodes(body)));
},

tableRow: function(cells) {
return this.createNode(new NodeTypes.TableRow(this.getNodes(cells)));
},

tableCell: function(content, align) {
return this.createNode(new NodeTypes.TableCell(this.getNodes(content), align));
},

hrule: function() {
return this.createNode(new NodeTypes.HRule());
},

lineBreak: function() {
return this.createNode(new NodeTypes.LineBreak());
},

emphasis: function(depth, content) {
return this.createNode(new NodeTypes.Emphasis(depth, this.getNodes(content)));
},

strikethrough: function(content) {
return this.createNode(new NodeTypes.Strikethrough(this.getNodes(content)));
},

codeSpan: function(text) {
return this.createNode(new NodeTypes.CodeSpan(text));
},

link: function(url, title, content) {
return this.createNode(new NodeTypes.Link(url, title, this.getNodes(content)));
},

autolink: function(url, type) {
return this.createNode(new NodeTypes.Link(url, '',
new NodeTypes.NodeSet([new NodeTypes.Text(url)])));
},

image: function(url, title, alt) {
var id = this.createNode(new NodeTypes.Image(url, title, alt));
if (id > 0) {
// Don't blame me for this hack, I am just replicating what Upskirt already does
// in markdown.c. Yes, it actually goes back in the buffer and erases the ! before
// the image syntax.
var prev = this.nodes[id-1];
if (prev instanceof NodeTypes.Text) {
prev.text = prev.text.slice(0, prev.text.length-1);
}
}
return id;
},

text: function(text) {
return this.createNode(new NodeTypes.Text(text));
},

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

createNode: function(node) {
var nodeId = this.nodeCount++;
this.nodes[nodeId] = node;
return nodeId;
},

getNodes: function(ids) {
var nodes = [];
if (ids) {
var idns = ids.split(',');
for (var i = 0; i < idns.length; ++i) {
var id = idns[i];
var node = this.nodes[id];
if (node) {
nodes.push(node);
}
}
}
return new NodeTypes.NodeSet(nodes);
}
};
133 changes: 133 additions & 0 deletions lib/NodeTransformer.js
@@ -0,0 +1,133 @@

var NodeTypes = require('./nodes');

// *************************************************************************************************

function NodeTransformer() {

}

NodeTransformer.prototype = {
visit: function(node) {
node.visit(this);
if (node instanceof NodeTypes.NodeSet) {
return this.nodeSet(node);
} else if (node instanceof NodeTypes.Header) {
return this.header(node);
} else if (node instanceof NodeTypes.Paragraph) {
return this.paragraph(node);
} else if (node instanceof NodeTypes.List) {
return this.list(node);
} else if (node instanceof NodeTypes.ListItem) {
return this.listItem(node);
} else if (node instanceof NodeTypes.Table) {
return this.table(node);
} else if (node instanceof NodeTypes.TableRow) {
return this.tableRow(node);
} else if (node instanceof NodeTypes.TableCell) {
return this.tableCell(node);
} else if (node instanceof NodeTypes.Blockquote) {
return this.blockquote(node);
} else if (node instanceof NodeTypes.BlockCode) {
return this.blockcode(node);
} else if (node instanceof NodeTypes.BlockHTML) {
return this.blockHTML(node);
} else if (node instanceof NodeTypes.HRule) {
return this.hrule(node);
} else if (node instanceof NodeTypes.LineBreak) {
return this.lineBreak(node);
} else if (node instanceof NodeTypes.Emphasis) {
return this.emphasis(node);
} else if (node instanceof NodeTypes.Strikethrough) {
return this.strikethrough(node);
} else if (node instanceof NodeTypes.CodeSpan) {
return this.codeSpan(node);
} else if (node instanceof NodeTypes.Link) {
return this.link(node);
} else if (node instanceof NodeTypes.Image) {
return this.image(node);
} else if (node instanceof NodeTypes.Text) {
return this.text(node);
} else {
return node;
}
},

nodeSet: function(node) {
return node;
},

header: function(node) {
return node;
},

paragraph: function(node) {
return node;
},

list: function(node) {
return node;
},

listItem: function(node) {
return node;
},

table: function(node) {
return node;
},

tableRow: function(node) {
return node;
},

tableCell: function(node) {
return node;
},

blockquote: function(node) {
return node;
},

blockCode: function(node) {
return node;
},

blockHTML: function(node) {
return node;
},

hrule: function(node) {
return node;
},

lineBreak: function(node) {
return node;
},

emphasis: function(node) {
return node;
},

strikethrough: function(node) {
return node;
},

codeSpan: function(node) {
return node;
},

link: function(node) {
return node;
},

image: function(node) {
return node;
},

text: function(node) {
return node;
},
};

exports.NodeTransformer = NodeTransformer;
34 changes: 34 additions & 0 deletions lib/markdom.js
@@ -0,0 +1,34 @@

var _markdom = require('../build/default/_markdom');
var NodeTypes = require('./nodes');
var NodeHandler = require('./NodeHandler').NodeHandler;
var NodeTransformer = require('./NodeTransformer').NodeTransformer;

// *************************************************************************************************

exports.toDOM = function(source, options, transformer) {
var handler = new NodeHandler();

var ids = _markdom.toDOM(source, handler, options || {});
var rootNodes = handler.getNodes(ids);
if (transformer) {
transformer.visit(rootNodes);
}
return rootNodes;
}

exports.toHTML = function(source, options, app) {
if (source instanceof NodeTypes.Node) {
return source.toHTML();
} else {
if (app) {
var nodes = exports.toDOM(source, options, app);
return nodes.toHTML();
} else {
return _markdom.toHTML(source, options || {});
}
}
}

exports.nodeTypes = NodeTypes;
exports.NodeTransformer = NodeTransformer;

0 comments on commit c6fcd24

Please sign in to comment.