Skip to content

Commit

Permalink
Merge pull request #1095 from zeitgeist87/FixGreedy
Browse files Browse the repository at this point in the history
Fix corner cases for the greedy flag
  • Loading branch information
zeitgeist87 committed May 8, 2017
2 parents 62cdaf8 + e13fdfa commit 6530709
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 39 deletions.
54 changes: 37 additions & 17 deletions components/prism-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,26 +255,18 @@ var _ = _self.Prism = {
return Token.stringify(_.util.encode(tokens), language);
},

tokenize: function(text, grammar, language) {
matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
var Token = _.Token;

var strarr = [text];

var rest = grammar.rest;

if (rest) {
for (var token in rest) {
grammar[token] = rest[token];
}

delete grammar.rest;
}

tokenloop: for (var token in grammar) {
for (var token in grammar) {
if(!grammar.hasOwnProperty(token) || !grammar[token]) {
continue;
}

if (token == target) {
return;
}

var patterns = grammar[token];
patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];

Expand All @@ -295,13 +287,13 @@ var _ = _self.Prism = {
pattern = pattern.pattern || pattern;

// Don’t cache length as it changes during the loop
for (var i=0, pos = 0; i<strarr.length; pos += strarr[i].length, ++i) {
for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {

var str = strarr[i];

if (strarr.length > text.length) {
// Something went terribly wrong, ABORT, ABORT!
break tokenloop;
return;
}

if (str instanceof Token) {
Expand All @@ -326,7 +318,7 @@ var _ = _self.Prism = {
k = i,
p = pos;

for (var len = strarr.length; k < len && p < to; ++k) {
for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
p += strarr[k].length;
// Move the index i to the element in strarr that is closest to from
if (from >= p) {
Expand All @@ -350,6 +342,10 @@ var _ = _self.Prism = {
}

if (!match) {
if (oneshot) {
break;
}

continue;
}

Expand All @@ -366,6 +362,8 @@ var _ = _self.Prism = {
var args = [i, delNum];

if (before) {
++i;
pos += before.length;
args.push(before);
}

Expand All @@ -378,9 +376,31 @@ var _ = _self.Prism = {
}

Array.prototype.splice.apply(strarr, args);

if (delNum != 1)
_.matchGrammar(text, strarr, grammar, i, pos, true, token);

if (oneshot)
break;
}
}
}
},

tokenize: function(text, grammar, language) {
var strarr = [text];

var rest = grammar.rest;

if (rest) {
for (var token in rest) {
grammar[token] = rest[token];
}

delete grammar.rest;
}

_.matchGrammar(text, strarr, grammar, 0, 0, false);

return strarr;
},
Expand Down
2 changes: 1 addition & 1 deletion components/prism-core.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 37 additions & 17 deletions prism.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,26 +260,18 @@ var _ = _self.Prism = {
return Token.stringify(_.util.encode(tokens), language);
},

tokenize: function(text, grammar, language) {
matchGrammar: function (text, strarr, grammar, index, startPos, oneshot, target) {
var Token = _.Token;

var strarr = [text];

var rest = grammar.rest;

if (rest) {
for (var token in rest) {
grammar[token] = rest[token];
}

delete grammar.rest;
}

tokenloop: for (var token in grammar) {
for (var token in grammar) {
if(!grammar.hasOwnProperty(token) || !grammar[token]) {
continue;
}

if (token == target) {
return;
}

var patterns = grammar[token];
patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];

Expand All @@ -300,13 +292,13 @@ var _ = _self.Prism = {
pattern = pattern.pattern || pattern;

// Don’t cache length as it changes during the loop
for (var i=0, pos = 0; i<strarr.length; pos += strarr[i].length, ++i) {
for (var i = index, pos = startPos; i < strarr.length; pos += strarr[i].length, ++i) {

var str = strarr[i];

if (strarr.length > text.length) {
// Something went terribly wrong, ABORT, ABORT!
break tokenloop;
return;
}

if (str instanceof Token) {
Expand All @@ -331,7 +323,7 @@ var _ = _self.Prism = {
k = i,
p = pos;

for (var len = strarr.length; k < len && p < to; ++k) {
for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) {
p += strarr[k].length;
// Move the index i to the element in strarr that is closest to from
if (from >= p) {
Expand All @@ -355,6 +347,10 @@ var _ = _self.Prism = {
}

if (!match) {
if (oneshot) {
break;
}

continue;
}

Expand All @@ -371,6 +367,8 @@ var _ = _self.Prism = {
var args = [i, delNum];

if (before) {
++i;
pos += before.length;
args.push(before);
}

Expand All @@ -383,9 +381,31 @@ var _ = _self.Prism = {
}

Array.prototype.splice.apply(strarr, args);

if (delNum != 1)
_.matchGrammar(text, strarr, grammar, i, pos, true, token);

if (oneshot)
break;
}
}
}
},

tokenize: function(text, grammar, language) {
var strarr = [text];

var rest = grammar.rest;

if (rest) {
for (var token in rest) {
grammar[token] = rest[token];
}

delete grammar.rest;
}

_.matchGrammar(text, strarr, grammar, 0, 0, false);

return strarr;
},
Expand Down
5 changes: 4 additions & 1 deletion tests/languages/clike/string_feature.test
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ bar"
bar'
"foo /* comment */ bar"
'foo // bar'
'foo // bar' //comment

----------------------------------------------------

Expand All @@ -19,7 +20,9 @@ bar'
["string", "\"foo\\\r\nbar\""],
["string", "'foo\\\r\nbar'"],
["string", "\"foo /* comment */ bar\""],
["string", "'foo // bar'"]
["string", "'foo // bar'"],
["string", "'foo // bar'"],
["comment", "//comment"]
]

----------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion tests/languages/css/string_feature.test
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
bar"
'foo\
bar'
"foo /* bar" /* and out */

----------------------------------------------------

[
["string", "\"f\\\"oo\""],
["string", "'f\\'oo'"],
["string", "\"foo\\\r\nbar\""],
["string", "'foo\\\r\nbar'"]
["string", "'foo\\\r\nbar'"],
["string", "\"foo /* bar\""],
["comment", "/* and out */"]
]

----------------------------------------------------
Expand Down
7 changes: 6 additions & 1 deletion tests/languages/javascript/template-string_feature.test
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ bar`
`40+2=${40+2}`
`${foo()}`
"foo `a` `b` `c` `d` bar"
"test // test" `template`

----------------------------------------------------

Expand Down Expand Up @@ -36,7 +37,11 @@ bar`
]],
["string", "`"]
]],
["string", "\"foo `a` `b` `c` `d` bar\""]
["string", "\"foo `a` `b` `c` `d` bar\""],
["string", "\"test // test\""],
["template-string", [
["string", "`template`"]
]]
]

----------------------------------------------------
Expand Down
5 changes: 4 additions & 1 deletion tests/languages/lolcode/string_feature.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"fo:"o"
"foo:)bar:>baz"
"foo:{bar}baz"
"foo BTW bar" BTW and out

----------------------------------------------------

Expand All @@ -25,7 +26,9 @@
"\"foo",
["variable", ":{bar}"],
"baz\""
]]
]],
["string", ["\"foo BTW bar\""]],
["comment", "BTW and out"]
]

----------------------------------------------------
Expand Down

0 comments on commit 6530709

Please sign in to comment.