From a2cccfaf1d2b1dfecd4d2d8b974d75d78ccaa139 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sat, 13 Aug 2011 16:53:15 -0500 Subject: [PATCH] better recursion? --- lib/marked.js | 226 +++++++++++++++++++++++++------------------------- 1 file changed, 114 insertions(+), 112 deletions(-) diff --git a/lib/marked.js b/lib/marked.js index 054f3df9..b4bf0087 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -32,6 +32,119 @@ var links; * Lexer */ +var lex_ = function lex(str, tokens, line) { + var i + , key + , rule; + + while (str.length) + for (i = 0; i < len; i++) { + key = keys[i]; + rule = rules[key]; + + cap = rule.exec(str); + if (!cap) continue; + str = str.substring(cap[0].length); + + switch (key) { + case 'newline': + line++; + break; + 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({ + type: 'list_item_start', + line: line + }); + 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, ''); + lex(cap, tokens, line); + tokens.push({ + type: 'blockquote_end', + line: line + }); + break; + } + break; + } +}; + var lex = function(str) { var tokens = [] , line = 0; @@ -57,118 +170,7 @@ var lex = function(str) { return ''; }); - (function lex(str) { - var i - , key - , rule; - - while (str.length) - for (i = 0; i < len; i++) { - key = keys[i]; - rule = rules[key]; - - cap = rule.exec(str); - if (!cap) continue; - str = str.substring(cap[0].length); - - switch (key) { - case 'newline': - line++; - break; - 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({ - type: 'list_item_start', - line: line - }); - lex(item, tokens); - 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, ''); - lex(cap, tokens); - tokens.push({ - type: 'blockquote_end', - line: line - }); - break; - } - break; - } - })(str); + lex_(str, tokens, line); return tokens; };