This commit is contained in:
Christopher Jeffrey 2011-08-14 01:04:35 -05:00
parent 68157a29b4
commit ea1a4043a4

View File

@ -136,10 +136,7 @@ block.token = function lex(str, tokens, line) {
var scan = function() { var scan = function() {
if (!str) return; if (!str) return;
for (var i = 0; i < len; i++) {
var i = 0;
for (; i < len; i++) {
key = keys[i]; key = keys[i];
if (cap = rules[key].exec(str)) { if (cap = rules[key].exec(str)) {
str = str.substring(cap[0].length); str = str.substring(cap[0].length);
@ -148,107 +145,108 @@ block.token = function lex(str, tokens, line) {
} }
}; };
while (scan()) while (scan()) {
switch (key) { switch (key) {
case 'newline': case 'newline':
line++; line++;
break; break;
case 'hr': case 'hr':
tokens.push({
type: 'hr',
line: line
});
break;
case 'lheading':
tokens.push({
type: 'heading',
depth: cap[2] === '=' ? 1 : 2,
text: cap[1],
line: line
});
break;
case 'heading':
tokens.push({
type: 'heading',
depth: cap[1].length,
text: cap[2],
line: line
});
break;
case 'block':
cap = cap[0].replace(/^ {4}/gm, '');
tokens.push({
type: 'block',
text: cap,
line: line
});
break;
case 'list':
tokens.push({
type: 'list_start',
ordered: isFinite(cap[2]),
line: line
});
// get each top-level
// item in the list
cap = cap[0].match(
/^( *)(\*|\+|-|\d+\.)[^\n]+(?:\n(?:\1 )+[^\n]+)*/gm
);
cap.forEach(function(item) {
// remove the list items sigil
// so its seen as the next token
item = item.replace(/^ *(\*|\+|-|\d+\.) */, '');
// outdent whatever the
// list item contains, hacky
var len = /\n( +)/.exec(item);
if (len) {
len = len[1].length;
item = item.replace(
new RegExp('^ {' + len + '}', 'gm'),
''
);
}
tokens.push({ tokens.push({
type: 'list_item_start', type: 'hr',
line: line line: line
}); });
break;
case 'lheading':
tokens.push({
type: 'heading',
depth: cap[2] === '=' ? 1 : 2,
text: cap[1],
line: line
});
break;
case 'heading':
tokens.push({
type: 'heading',
depth: cap[1].length,
text: cap[2],
line: line
});
break;
case 'block':
cap = cap[0].replace(/^ {4}/gm, '');
tokens.push({
type: 'block',
text: cap,
line: line
});
break;
case 'list':
tokens.push({
type: 'list_start',
ordered: isFinite(cap[2]),
line: line
});
// get each top-level
// item in the list
cap = cap[0].match(
/^( *)(\*|\+|-|\d+\.)[^\n]+(?:\n(?:\1 )+[^\n]+)*/gm
);
cap.forEach(function(item) {
// remove the list items sigil
// so its seen as the next token
item = item.replace(/^ *(\*|\+|-|\d+\.) */, '');
// outdent whatever the
// list item contains, hacky
var len = /\n( +)/.exec(item);
if (len) {
len = len[1].length;
item = item.replace(
new RegExp('^ {' + len + '}', 'gm'),
''
);
}
tokens.push({
type: 'list_item_start',
line: line
});
// recurse
lex(item, tokens, line);
tokens.push({
type: 'list_item_end',
line: line
});
});
tokens.push({
type: 'list_end',
line: line
});
break;
case 'html':
case 'text':
tokens.push({
type: key,
text: cap[0],
line: line
});
break;
case 'blockquote':
tokens.push({
type: 'blockquote_start',
line: line
});
cap = cap[0].replace(/^ *>/gm, '');
// recurse // recurse
lex(item, tokens, line); lex(cap, tokens, line);
tokens.push({ tokens.push({
type: 'list_item_end', type: 'blockquote_end',
line: line line: line
}); });
}); break;
tokens.push({ }
type: 'list_end',
line: line
});
break;
case 'html':
case 'text':
tokens.push({
type: key,
text: cap[0],
line: line
});
break;
case 'blockquote':
tokens.push({
type: 'blockquote_start',
line: line
});
cap = cap[0].replace(/^ *>/gm, '');
// recurse
lex(cap, tokens, line);
tokens.push({
type: 'blockquote_end',
line: line
});
break;
} }
return tokens; return tokens;
@ -302,10 +300,7 @@ inline.lexer = function(str) {
var scan = function() { var scan = function() {
if (!str) return; if (!str) return;
for (var i = 0; i < len; i++) {
var i = 0;
for (; i < len; i++) {
key = keys[i]; key = keys[i];
if (cap = rules[key].exec(str)) { if (cap = rules[key].exec(str)) {
str = str.substring(cap[0].length); str = str.substring(cap[0].length);
@ -314,70 +309,71 @@ inline.lexer = function(str) {
} }
}; };
while (scan()) while (scan()) {
switch (key) { switch (key) {
case 'tag': case 'tag':
out += cap[0]; out += cap[0];
break; break;
case 'img': case 'img':
out += '<img src="' out += '<img src="'
+ escape(cap[2]) + escape(cap[2])
+ '" alt="' + escape(cap[1]) + '" alt="' + escape(cap[1])
+ '"' + '"'
+ (cap[3] + (cap[3]
? ' title="' ? ' title="'
+ escape(cap[3]) + escape(cap[3])
+ '"' + '"'
: '') : '')
+ '>'; + '>';
break; break;
case 'link': case 'link':
case 'reflink': case 'reflink':
link = links[cap[2]] || ''; link = links[cap[2]] || '';
out += '<a href="' out += '<a href="'
+ escape(link.href || cap[2]) + escape(link.href || cap[2])
+ '"' + '"'
+ (link.title + (link.title
? ' title="' ? ' title="'
+ escape(link.title) + escape(link.title)
+ '"' + '"'
: '') : '')
+ '>' + '>'
+ inline.lexer(cap[1]) + inline.lexer(cap[1])
+ '</a>'; + '</a>';
break; break;
case 'autolink': case 'autolink':
if (cap[2] === '@') { if (cap[2] === '@') {
text = mangle(cap[1]); text = mangle(cap[1]);
href = mangle('mailto:') + text; href = mangle('mailto:') + text;
} else { } else {
text = escape(cap[1]); text = escape(cap[1]);
href = text; href = text;
} }
out += '<a href="' + href + '">' out += '<a href="' + href + '">'
+ text + text
+ '</a>'; + '</a>';
break; break;
case 'strong': case 'strong':
out += '<strong>' out += '<strong>'
+ inline.lexer(cap[2] || cap[1]) + inline.lexer(cap[2] || cap[1])
+ '</strong>'; + '</strong>';
break; break;
case 'em': case 'em':
out += '<em>' out += '<em>'
+ inline.lexer(cap[2] || cap[1]) + inline.lexer(cap[2] || cap[1])
+ '</em>'; + '</em>';
break; break;
case 'escape': case 'escape':
out += '<code>' out += '<code>'
+ escape(cap[2] || cap[1]) + escape(cap[2] || cap[1])
+ '</code>'; + '</code>';
break; break;
case 'text': case 'text':
out += escape(cap[1]); out += escape(cap[1]);
break; break;
default: default:
break; break;
}
} }
return out; return out;