Browse Source

Perf: smartquotes logic cleanup

pull/14/head
Vitaly Puzrin 10 years ago
parent
commit
4d7c3a717d
  1. 47
      lib/rules_text/smartquotes.js

47
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);
}
};

Loading…
Cancel
Save