diff --git a/lib/rules_text/smartquotes.js b/lib/rules_text/smartquotes.js index 02bcbd0..3482412 100644 --- a/lib/rules_text/smartquotes.js +++ b/lib/rules_text/smartquotes.js @@ -16,19 +16,19 @@ function isLetter(str, pos) { } -function addQuote(obj, tokenId, posId, str) { - if (typeof obj[tokenId] === 'undefined') { obj[tokenId] = {}; } - obj[tokenId][posId] = str; +function replaceAt(str, index, ch) { + return str.substr(0, index) + ch + str.substr(index + 1); } +var stack = []; module.exports = function smartquotes(typographer, state) { /*eslint max-depth:0*/ - var i, token, text, t, pos, max, thisLevel, lastSpace, nextSpace, item, canOpen, canClose, j, isSingle, fn, chars, + var i, token, text, t, pos, max, thisLevel, lastSpace, nextSpace, item, canOpen, canClose, j, isSingle, chars, options = typographer.options, - replace = {}, - tokens = state.tokens, - stack = []; + tokens = state.tokens; + + stack.length = 0; for (i = 0; i < tokens.length; i++) { token = tokens[i]; @@ -46,20 +46,22 @@ module.exports = function smartquotes(typographer, state) { pos = 0; max = text.length; + /*eslint no-labels:0,block-scoped-var:0*/ + OUTER: while (pos < max) { QUOTE_RE.lastIndex = pos; t = QUOTE_RE.exec(text); if (!t) { break; } lastSpace = !isLetter(text, t.index - 1); - pos = t.index + t[0].length; - isSingle = t[0] === "'"; + pos = t.index + 1; + isSingle = (t[0] === "'"); nextSpace = !isLetter(text, pos); if (!nextSpace && !lastSpace) { - // middle word + // middle of word if (isSingle) { - addQuote(replace, i, t.index, APOSTROPHE); + token.content = replaceAt(token.content, t.index, APOSTROPHE); } continue; } @@ -76,12 +78,11 @@ module.exports = function smartquotes(typographer, state) { item = stack[j]; chars = isSingle ? options.singleQuotes : options.doubleQuotes; if (chars) { - addQuote(replace, item.token, item.start, chars[0]); - addQuote(replace, i, t.index, chars[1]); + tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, chars[0]); + token.content = replaceAt(token.content, t.index, chars[1]); } stack.length = j; - canOpen = false; // should be "continue OUTER;", but eslint refuses labels :( - break; + continue OUTER; } } } @@ -89,25 +90,13 @@ module.exports = function smartquotes(typographer, state) { if (canOpen) { stack.push({ token: i, - start: t.index, - end: pos, + pos: t.index, single: isSingle, level: thisLevel }); } else if (canClose && isSingle) { - addQuote(replace, i, t.index, APOSTROPHE); + token.content = replaceAt(token.content, t.index, APOSTROPHE); } } } - - fn = function(str, pos) { - if (typeof replace[i][pos] === 'undefined') { return str; } - return replace[i][pos]; - }; - - for (i = 0; i < tokens.length; i++) { - if (typeof replace[i] === 'undefined') { continue; } - QUOTE_RE.lastIndex = 0; - tokens[i].content = tokens[i].content.replace(QUOTE_RE, fn); - } };