Browse Source

Add tokenizeSingle method

pull/14/head
Alex Kocharin 10 years ago
parent
commit
b492fa2cc2
  1. 21
      lib/lexer_inline.js
  2. 19
      lib/lexer_inline/emphasis.js
  3. 21
      lib/lexer_inline/links.js
  4. 2
      lib/lexer_inline/state_inline.js

21
lib/lexer_inline.js

@ -117,6 +117,23 @@ LexerInline.prototype.after = function (name, fn) {
}; };
// Generate single token;
// returns `true` if any rule reported success
//
LexerInline.prototype.tokenizeSingle = function (state) {
var ok, i,
rules = this.rules,
len = this.rules.length;
for (i = 0; i < len; i++) {
ok = rules[i](state);
if (ok) { break; }
}
return ok;
};
// Generate tokens for input range // Generate tokens for input range
// //
LexerInline.prototype.tokenize = function (state) { LexerInline.prototype.tokenize = function (state) {
@ -166,12 +183,12 @@ LexerInline.prototype.parse = function (str, options, env) {
// Parse link reference definition. // Parse link reference definition.
// //
LexerInline.prototype.parse_reference = function (str, options) { LexerInline.prototype.parse_reference = function (str, options, env) {
var state, labelEnd, pos, max, code, start, href, title; var state, labelEnd, pos, max, code, start, href, title;
if (str.charCodeAt(0) !== 0x5B/* [ */) { return null; } if (str.charCodeAt(0) !== 0x5B/* [ */) { return null; }
state = new StateInline(str, this, options); state = new StateInline(str, this, options, env);
labelEnd = links.parseLinkLabel(state, 0); labelEnd = links.parseLinkLabel(state, 0);
if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return null; } if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return null; }

19
lib/lexer_inline/emphasis.js

@ -97,13 +97,11 @@ module.exports = function emphasis(state/*, silent*/) {
count, count,
oldLength, oldLength,
oldPending, oldPending,
oldFlag,
found, found,
ok, ok,
i,
oldCount, oldCount,
newCount, newCount,
len,
rules,
stack, stack,
breakOutOfOuterLoop, breakOutOfOuterLoop,
max = state.posMax, max = state.posMax,
@ -113,6 +111,11 @@ module.exports = function emphasis(state/*, silent*/) {
if (marker !== 0x5F/* _ */ && marker !== 0x2A /* * */) { return false; } if (marker !== 0x5F/* _ */ && marker !== 0x2A /* * */) { return false; }
// skip emphasis in links because it has lower priority, compare:
// [foo *bar]()*
// [foo `bar]()`
if (state.validateInsideEm || state.validateInsideLink) { return false; }
startCount = parseStart(state, start); startCount = parseStart(state, start);
if (startCount < 0) { return false; } if (startCount < 0) { return false; }
if (startCount >= 4) { if (startCount >= 4) {
@ -123,11 +126,11 @@ module.exports = function emphasis(state/*, silent*/) {
oldLength = state.tokens.length; oldLength = state.tokens.length;
oldPending = state.pending; oldPending = state.pending;
oldFlag = state.validateInsideEm;
state.pos = start + startCount; state.pos = start + startCount;
stack = [ startCount ]; stack = [ startCount ];
rules = state.lexer.rules; state.validateInsideEm = true;
len = rules.length;
while (state.pos < max) { while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === marker && !haveLiteralAsterisk) { if (state.src.charCodeAt(state.pos) === marker && !haveLiteralAsterisk) {
@ -181,10 +184,7 @@ module.exports = function emphasis(state/*, silent*/) {
} }
} }
for (i = 0; i < len; i++) { ok = state.lexer.tokenizeSingle(state);
if (rules[i] !== emphasis) { ok = rules[i](state); }
if (ok) { break; }
}
if (ok) { if (ok) {
haveLiteralAsterisk = false; haveLiteralAsterisk = false;
@ -198,6 +198,7 @@ module.exports = function emphasis(state/*, silent*/) {
// restore old state // restore old state
state.tokens.length = oldLength; state.tokens.length = oldLength;
state.pending = oldPending; state.pending = oldPending;
state.validateInsideEm = oldFlag;
if (!found) { if (!found) {
// parser failed to find ending tag, so it's not valid emphasis // parser failed to find ending tag, so it's not valid emphasis

21
lib/lexer_inline/links.js

@ -9,17 +9,19 @@
// this function assumes that first character ("[") already matches; // this function assumes that first character ("[") already matches;
// returns the end of the label // returns the end of the label
function parseLinkLabel(state, start) { function parseLinkLabel(state, start) {
var level, rules, len, found, marker, i, ok, var level, found, marker, ok,
labelEnd = -1, labelEnd = -1,
max = state.posMax, max = state.posMax,
oldPos = state.pos, oldPos = state.pos,
oldLength = state.tokens.length, oldLength = state.tokens.length,
oldPending = state.pending; oldPending = state.pending,
oldFlag = state.validateInsideLink;
if (state.validateInsideLink) { return -1; }
state.pos = start + 1; state.pos = start + 1;
state.validateInsideLink = true;
level = 1; level = 1;
rules = state.lexer.rules;
len = rules.length;
while (state.pos < max) { while (state.pos < max) {
marker = state.src.charCodeAt(state.pos); marker = state.src.charCodeAt(state.pos);
@ -33,15 +35,7 @@ function parseLinkLabel(state, start) {
} }
} }
for (i = 0; i < len; i++) { ok = state.lexer.tokenizeSingle(state);
// skip emphasis because it has lower priority, compare:
// [foo *bar]()*
// [foo `bar]()`
if (rules[i].name !== 'emphasis' && rules[i].name !== 'links') {
ok = rules[i](state);
}
if (ok) { break; }
}
if (!ok) { state.pending += state.src[state.pos++]; } if (!ok) { state.pending += state.src[state.pos++]; }
} }
@ -52,6 +46,7 @@ function parseLinkLabel(state, start) {
state.pos = oldPos; state.pos = oldPos;
state.tokens.length = oldLength; state.tokens.length = oldLength;
state.pending = oldPending; state.pending = oldPending;
state.validateInsideLink = oldFlag;
return labelEnd; return labelEnd;
} }

2
lib/lexer_inline/state_inline.js

@ -12,6 +12,8 @@ function StateInline(src, lexer, options, env) {
this.pos = 0; this.pos = 0;
this.pending = ''; this.pending = '';
this.posMax = this.src.length; this.posMax = this.src.length;
this.validateInsideEm = false;
this.validateInsideLink = false;
} }

Loading…
Cancel
Save