Browse Source

Move parse_reference to its own file

+ change its signature
pull/14/head
Alex Kocharin 10 years ago
parent
commit
c8fa672cec
  1. 13
      lib/lexer_block/paragraph.js
  2. 58
      lib/lexer_inline.js
  3. 65
      lib/parse_ref.js

13
lib/lexer_block/paragraph.js

@ -5,10 +5,11 @@
var isEmpty = require('../helpers').isEmpty; var isEmpty = require('../helpers').isEmpty;
var getLines = require('../helpers').getLines; var getLines = require('../helpers').getLines;
var parseRef = require('../parse_ref');
module.exports = function paragraph(state, startLine/*, endLine*/) { module.exports = function paragraph(state, startLine/*, endLine*/) {
var endLine, content, ref, t, var endLine, content, pos,
nextLine = startLine + 1, nextLine = startLine + 1,
rules_named = state.lexer.rules_named; 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(); content = getLines(state, startLine, nextLine, state.blkIndent, false).trim();
while ((ref = state.lexer.inline.parse_reference(content, state.options, state.env))) { while (content.length) {
t = state.env.references; pos = parseRef(content, state.lexer.inline, state.options, state.env);
t[ref.label] = t[ref.label] || { title: ref.title, href: ref.href }; if (pos < 0) { break; }
content = ref.remaining.trim(); content = content.slice(pos).trim();
} }
if (content) { if (content.length) {
state.tokens.push({ type: 'paragraph_open', level: state.level }); state.tokens.push({ type: 'paragraph_open', level: state.level });
state.tokens.push({ state.tokens.push({
type: 'inline', type: 'inline',

58
lib/lexer_inline.js

@ -4,8 +4,6 @@
var StateInline = require('./lexer_inline/state_inline'); var StateInline = require('./lexer_inline/state_inline');
var links = require('./lexer_inline/links');
var skipSpaces = require('./helpers').skipSpaces;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Lexer rules // Lexer rules
@ -179,61 +177,5 @@ LexerInline.prototype.parse = function (str, options, env) {
return state.tokens; 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; module.exports = LexerInline;

65
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;
};
Loading…
Cancel
Save