From c8fa672cecc65c2b0c66c93a376bd931f3f93d8f Mon Sep 17 00:00:00 2001 From: Alex Kocharin Date: Mon, 6 Oct 2014 12:26:57 +0400 Subject: [PATCH] Move parse_reference to its own file + change its signature --- lib/lexer_block/paragraph.js | 13 ++++---- lib/lexer_inline.js | 58 -------------------------------- lib/parse_ref.js | 65 ++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 64 deletions(-) create mode 100644 lib/parse_ref.js diff --git a/lib/lexer_block/paragraph.js b/lib/lexer_block/paragraph.js index dc1d4a2..261e001 100644 --- a/lib/lexer_block/paragraph.js +++ b/lib/lexer_block/paragraph.js @@ -5,10 +5,11 @@ var isEmpty = require('../helpers').isEmpty; var getLines = require('../helpers').getLines; +var parseRef = require('../parse_ref'); module.exports = function paragraph(state, startLine/*, endLine*/) { - var endLine, content, ref, t, + var endLine, content, pos, nextLine = startLine + 1, rules_named = state.lexer.rules_named; @@ -36,13 +37,13 @@ module.exports = function paragraph(state, startLine/*, endLine*/) { content = getLines(state, startLine, nextLine, state.blkIndent, false).trim(); - while ((ref = state.lexer.inline.parse_reference(content, state.options, state.env))) { - t = state.env.references; - t[ref.label] = t[ref.label] || { title: ref.title, href: ref.href }; - content = ref.remaining.trim(); + while (content.length) { + pos = parseRef(content, state.lexer.inline, state.options, state.env); + if (pos < 0) { break; } + content = content.slice(pos).trim(); } - if (content) { + if (content.length) { state.tokens.push({ type: 'paragraph_open', level: state.level }); state.tokens.push({ type: 'inline', diff --git a/lib/lexer_inline.js b/lib/lexer_inline.js index 428273e..f0f3f90 100644 --- a/lib/lexer_inline.js +++ b/lib/lexer_inline.js @@ -4,8 +4,6 @@ var StateInline = require('./lexer_inline/state_inline'); -var links = require('./lexer_inline/links'); -var skipSpaces = require('./helpers').skipSpaces; //////////////////////////////////////////////////////////////////////////////// // Lexer rules @@ -179,61 +177,5 @@ LexerInline.prototype.parse = function (str, options, env) { return state.tokens; }; -// Parse link reference definition. -// -LexerInline.prototype.parse_reference = function (str, options, env) { - var state, labelEnd, pos, max, code, start, href, title; - - if (str.charCodeAt(0) !== 0x5B/* [ */) { return null; } - - state = new StateInline(str, this, options, env); - labelEnd = links.parseLinkLabel(state, 0); - - if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return null; } - - max = state.posMax; - - // [label]: destination 'title' - // ^^^ skip optional whitespace here - for (pos = labelEnd + 2; pos < max; pos++) { - code = state.src.charCodeAt(pos); - if (code !== 0x20 && code !== 0x0A) { break; } - } - - // [label]: destination 'title' - // ^^^^^^^^^^^ parse this - href = links.parseLinkDestination(state, pos); - if (href === null) { return null; } - pos = state.pos; - - // [label]: destination 'title' - // ^^^ skipping those spaces - start = pos; - for (pos = pos + 1; pos < max; pos++) { - code = state.src.charCodeAt(pos); - if (code !== 0x20 && code !== 0x0A) { break; } - } - - // [label]: destination 'title' - // ^^^^^^^ parse this - if (pos < max && start !== pos && (title = links.parseLinkTitle(state, pos)) !== null) { - pos = state.pos; - } else { - title = ''; - pos = start; - } - - // ensure that the end of the line is empty - pos = skipSpaces(state, pos); - if (pos < max && state.src.charCodeAt(pos) !== 0x0A) { return null; } - - return { - label: links.normalizeReference(str.slice(1, labelEnd)), - title: title, - href: href, - remaining: str.slice(pos) - }; -}; - module.exports = LexerInline; diff --git a/lib/parse_ref.js b/lib/parse_ref.js new file mode 100644 index 0000000..fdc7101 --- /dev/null +++ b/lib/parse_ref.js @@ -0,0 +1,65 @@ + +'use strict'; + + +var StateInline = require('./lexer_inline/state_inline'); +var links = require('./lexer_inline/links'); +var skipSpaces = require('./helpers').skipSpaces; + + +// Parse link reference definition. +// +module.exports = function parse_reference(str, lexer, options, env) { + var state, labelEnd, pos, max, code, start, href, title, label; + + if (str.charCodeAt(0) !== 0x5B/* [ */) { return -1; } + + // TODO: benchmark this + if (str.indexOf(']:') === -1) { return -1; } + + state = new StateInline(str, lexer, options, env); + labelEnd = links.parseLinkLabel(state, 0); + + if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; } + + max = state.posMax; + + // [label]: destination 'title' + // ^^^ skip optional whitespace here + for (pos = labelEnd + 2; pos < max; pos++) { + code = state.src.charCodeAt(pos); + if (code !== 0x20 && code !== 0x0A) { break; } + } + + // [label]: destination 'title' + // ^^^^^^^^^^^ parse this + href = links.parseLinkDestination(state, pos); + if (href === null) { return -1; } + pos = state.pos; + + // [label]: destination 'title' + // ^^^ skipping those spaces + start = pos; + for (pos = pos + 1; pos < max; pos++) { + code = state.src.charCodeAt(pos); + if (code !== 0x20 && code !== 0x0A) { break; } + } + + // [label]: destination 'title' + // ^^^^^^^ parse this + if (pos < max && start !== pos && (title = links.parseLinkTitle(state, pos)) !== null) { + pos = state.pos; + } else { + title = ''; + pos = start; + } + + // ensure that the end of the line is empty + pos = skipSpaces(state, pos); + if (pos < max && state.src.charCodeAt(pos) !== 0x0A) { return -1; } + + label = links.normalizeReference(str.slice(1, labelEnd)); + env.references[label] = env.references[label] || { title: title, href: href }; + + return pos; +};