diff options
-rwxr-xr-x | js/stmd.js | 106 |
1 files changed, 64 insertions, 42 deletions
@@ -2137,6 +2137,22 @@ zwj: '', zwnj: '' }; + // Constants for character codes: + + var C_NEWLINE = 10; + var C_SPACE = 32; + var C_ASTERISK = 42; + var C_UNDERSCORE = 95; + var C_BACKTICK = 96; + var C_OPEN_BRACKET = 91; + var C_CLOSE_BRACKET = 93; + var C_LESSTHAN = 60; + var C_BANG = 33; + var C_BACKSLASH = 92; + var C_AMPERSAND = 38; + var C_OPEN_PAREN = 40; + var C_COLON = 58; + // Some regexps used in inline parser: var ESCAPABLE = '[!"#$%&\'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]'; @@ -2286,10 +2302,14 @@ } }; - // Returns the character at the current subject position, or null if + // Returns the code for the character at the current subject position, or -1 // there are no more characters. var peek = function() { - return this.subject.charAt(this.pos) || null; + if (this.pos < this.subject.length) { + return this.subject.charCodeAt(this.pos); + } else { + return -1; + } }; // Parse zero or more space characters, including at most one newline @@ -2377,29 +2397,34 @@ } }; - // Scan a sequence of characters == c, and return information about + // Scan a sequence of characters with code cc, and return information about // the number of delimiters and whether they are positioned such that // they can open and/or close emphasis or strong emphasis. A utility // function for strong/emph parsing. - var scanDelims = function(c) { + var scanDelims = function(cc) { var numdelims = 0; var first_close_delims = 0; - var char_before, char_after; + var char_before, char_after, cc_after; var startpos = this.pos; char_before = this.pos === 0 ? '\n' : this.subject.charAt(this.pos - 1); - while (this.peek() === c) { + while (this.peek() === cc) { numdelims++; this.pos++; } - char_after = this.peek() || '\n'; + cc_after = this.peek(); + if (cc_after === -1) { + char_after = '\n'; + } else { + char_after = String.fromCharCode(cc_after); + } var can_open = numdelims > 0 && numdelims <= 3 && !(/\s/.test(char_after)); var can_close = numdelims > 0 && numdelims <= 3 && !(/\s/.test(char_before)); - if (c === '_') { + if (cc === C_UNDERSCORE) { can_open = can_open && !((/[a-z0-9]/i).test(char_before)); can_close = can_close && !((/[a-z0-9]/i).test(char_after)); } @@ -2422,21 +2447,18 @@ } // Attempt to parse emphasis or strong emphasis. - var parseEmphasis = function() { + var parseEmphasis = function(cc) { var startpos = this.pos; var c ; var first_close = 0; - c = this.peek(); - if (!(c === '*' || c === '_')) { - return null; - } + c = String.fromCharCode(cc); var numdelims; var delimpos; var inlines = []; // Get opening delimiters. - res = this.scanDelims(c); + res = this.scanDelims(cc); numdelims = res.numdelims; if (numdelims === 0) { @@ -2472,10 +2494,10 @@ } while (true) { - if (this.last_emphasis_closer[c] < this.pos) { + if (this.last_emphasis_closer[cc] < this.pos) { break; } - res = this.scanDelims(c); + res = this.scanDelims(cc); if (res) { numdelims = res.numdelims; @@ -2615,7 +2637,7 @@ // we didn't match emphasis: fallback this.pos = fallbackpos; if (last_emphasis_closer) { - this.last_emphasis_closer[c] = last_emphasis_closer; + this.last_emphasis_closer[cc] = last_emphasis_closer; } return [fallback]; @@ -2651,7 +2673,7 @@ // Attempt to parse a link label, returning number of characters parsed. var parseLinkLabel = function() { - if (this.peek() != '[') { + if (this.peek() != C_OPEN_BRACKET) { return 0; } var startpos = this.pos; @@ -2668,36 +2690,36 @@ } this.pos++; // advance past [ var c; - while ((c = this.peek()) && (c != ']' || nest_level > 0)) { + while ((c = this.peek()) && c != -1 && (c != C_CLOSE_BRACKET || nest_level > 0)) { switch (c) { - case '`': + case C_BACKTICK: this.parseBackticks(); break; - case '<': + case C_LESSTHAN: this.parseAutolink() || this.parseHtmlTag() || this.pos++; break; - case '[': // nested [] + case C_OPEN_BRACKET: // nested [] nest_level++; this.pos++; break; - case ']': // nested [] + case C_CLOSE_BRACKET: // nested [] nest_level--; this.pos++; break; - case '\\': + case C_BACKSLASH: this.parseBackslash(); break; default: this.parseString(); } } - if (c === ']') { + if (c === C_CLOSE_BRACKET) { this.label_nest_level = 0; this.pos++; // advance past ] return this.pos - startpos; } else { - if (!c) { + if (c === -1) { this.label_nest_level = nest_level; } this.pos = startpos; @@ -2730,7 +2752,7 @@ // if we got this far, we've parsed a label. // Try to parse an explicit link: [label](url "title") - if (this.peek() == '(') { + if (this.peek() == C_OPEN_PAREN) { this.pos++; if (this.spnl() && ((dest = this.parseLinkDestination()) !== null) && @@ -2851,7 +2873,7 @@ } // colon: - if (this.peek() === ':') { + if (this.peek() === C_COLON) { this.pos++; } else { this.pos = startpos; @@ -2902,35 +2924,35 @@ } var c = this.peek(); - if (!c) { + if (c === -1) { return null; } var res; switch(c) { - case '\n': - case ' ': + case C_NEWLINE: + case C_SPACE: res = this.parseNewline(); break; - case '\\': + case C_BACKSLASH: res = this.parseBackslash(); break; - case '`': + case C_BACKTICK: res = this.parseBackticks(); break; - case '*': - case '_': - res = this.parseEmphasis(); + case C_ASTERISK: + case C_UNDERSCORE: + res = this.parseEmphasis(c); break; - case '[': + case C_OPEN_BRACKET: res = this.parseLink(); break; - case '!': + case C_BANG: res = this.parseImage(); break; - case '<': + case C_LESSTHAN: res = this.parseAutolink() || this.parseHtmlTag(); break; - case '&': + case C_AMPERSAND: res = this.parseEntity(); break; default: @@ -2939,7 +2961,7 @@ } if (res === null) { this.pos += 1; - res = [{t: 'Str', c: c}]; + res = [{t: 'Str', c: String.fromCharCode(c)}]; } if (res && memoize) { @@ -2956,7 +2978,7 @@ this.pos = 0; this.refmap = refmap || {}; this.memo = {}; - this.last_emphasis_closer = { '*': s.length, '_': s.length }; + this.last_emphasis_closer = { C_ASTERISK: s.length, C_UNDERSCORE: s.length }; var inlines = []; var next_inline; while ((next_inline = this.parseInline())) { |