This commit is contained in:
Christopher Jeffrey 2011-08-13 17:06:08 -05:00
parent a2cccfaf1d
commit 2ab86665a5

View File

@ -22,25 +22,44 @@ var rules = {
var keys = Object.keys(rules)
, len = keys.length;
/**
* Shared
*/
var links;
/**
* Lexer
*/
var lex_ = function lex(str, tokens, line) {
var i
, key
, rule;
var lex = function(str) {
var tokens = []
, links = {};
// normalize whitespace
str = str.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n');
str = str.replace(/\t/g, ' ');
//str = str.replace(/(^|\n) +(\n|$)/g, '$1$2');
// unfortunately, this is the most
// performant method of getting link
// definitions out of the way.
str = str.replace(
/^ {0,3}\[([^\]]+)\]: *([^ ]+)(?: +"([^"]+)")?/gm,
function(_, id, href, title) {
links[id] = {
href: href,
title: title
};
return '';
});
tokens.links = links;
return lex.token(str, tokens, 0);
};
lex.token = function lex(str, tokens, line) {
while (str.length)
for (i = 0; i < len; i++) {
key = keys[i];
rule = rules[key];
for (var i = 0; i < len; i++) {
var key = keys[i]
, rule = rules[key];
cap = rule.exec(str);
if (!cap) continue;
@ -109,7 +128,10 @@ var lex_ = function lex(str, tokens, line) {
type: 'list_item_start',
line: line
});
// recurse
lex(item, tokens, line);
tokens.push({
type: 'list_item_end',
line: line
@ -134,7 +156,10 @@ var lex_ = function lex(str, tokens, line) {
line: line
});
cap = cap[0].replace(/^ *>/gm, '');
// recurse
lex(cap, tokens, line);
tokens.push({
type: 'blockquote_end',
line: line
@ -143,34 +168,6 @@ var lex_ = function lex(str, tokens, line) {
}
break;
}
};
var lex = function(str) {
var tokens = []
, line = 0;
// normalize whitespace
str = str.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n');
str = str.replace(/\t/g, ' ');
//str = str.replace(/(^|\n) +(\n|$)/g, '$1$2');
// unfortunately, this is the most
// performant method of getting link
// definitions out of the way.
links = {};
str = str.replace(
/^ {0,3}\[([^\]]+)\]: *([^ ]+)(?: +"([^"]+)")?/gm,
function(_, id, href, title) {
links[id] = {
href: href,
title: title
};
return '';
});
lex_(str, tokens, line);
return tokens;
};
@ -207,8 +204,8 @@ var inline = function(str) {
// reference-style link.
str = str.replace(
/\[([^\]]+)\]\[([^\]]+)\]/g,
function(_, text, id) {
var link = links[id];
function(__, text, id) {
var link = tokens.links[id];
return '<a href="'
+ link.href + '"'
+ (link.title
@ -216,12 +213,13 @@ var inline = function(str) {
+ link.title + '"'
: '')
+ '>' + text + '</a>';
});
}
);
// for <http://hello.world/> links
str = str.replace(
/(?:<|&lt;)([^<>:\/ ]+:(?:\/\/)?[^>\n]+?|[^<>\n]+?(@)[^<>\n]+?)(?:&gt;|>)/g,
function(_, href, at) {
function(__, href, at) {
if (at) {
// according to the markdown "spec"
// we need to mangle email addresses
@ -230,7 +228,8 @@ var inline = function(str) {
return '<a href="' + mail + '">' + href + '</a>';
}
return '<a href="' + href + '">' + href + '</a>';
});
}
);
// strong
str = str.replace(/__([^_]+)__/g, '<strong>$1</strong>');
@ -241,7 +240,7 @@ var inline = function(str) {
str = str.replace(/\*([^*]+)\*/g, '<em>$1</em>');
// code
str = str.replace(/`([^`]+)`/g, function(_, s) {
str = str.replace(/`([^`]+)`/g, function(__, s) {
return '<code>' + escape(s) + '</code>';
});
@ -255,7 +254,8 @@ var inline = function(str) {
* Parsing
*/
var tokens;
var tokens
, token;
var next = function() {
return token = tokens.pop();
@ -330,7 +330,6 @@ var parse = function(src) {
tokens = null;
token = null;
links = null;
return out.join(' ');
};