Skip to content

Commit e087bd3

Browse files
committed
more generic implementation (though not perfect yet)
1 parent 41bde38 commit e087bd3

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

src/highlight.js

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ https://highlightjs.org/
108108
}
109109
}
110110

111-
function inherit(parent) { // inherit(parent, override_obj, override_obj, ...)
111+
var inherit = function(parent) { // inherit(parent, override_obj, override_obj, ...)
112112
var key;
113113
var result = {};
114114
var objects = Array.prototype.slice.call(arguments, 1);
@@ -122,6 +122,15 @@ https://highlightjs.org/
122122
return result;
123123
}
124124

125+
// ES2015 version (we would hope it's faster?)
126+
if (Object.assign) {
127+
inherit = function() {
128+
Array.prototype.unshift.call(arguments, {})
129+
return Object.assign.apply(null, arguments)
130+
}
131+
}
132+
133+
125134
/* Stream merging */
126135

127136
function nodeStream(node) {
@@ -418,15 +427,27 @@ https://highlightjs.org/
418427
for(var i = 0; i<match.length; i++) {
419428
if (match[i] != undefined && matchIndexes["" +i] != undefined ) {
420429
rule = matchIndexes[""+i];
430+
match.splice(0, i) // trim off the extra matches
421431
break;
422432
}
423433
}
424434

435+
// raw (but cooked slight, to fixed the indexes) match is passed to
436+
// callbacks as `raw` and avoids exposing too much of our internal
437+
// workings to callbacks
438+
439+
// we do this selectively with begin [performance], but for `end` because
440+
// we could potentially be matching a parent end rule we always
441+
// include a copy of the raw match
442+
425443
// illegal or end match
426444
if (typeof rule === "string") {
445+
match.raw = inherit(match)
427446
match.type = rule;
428447
match.extra = [mode.illegal, mode.terminator_end];
429448
} else {
449+
if (hasBeginCallbacks(rule))
450+
match.raw = inherit(match)
430451
match.type = "begin";
431452
match.rule = rule;
432453
}
@@ -436,6 +457,14 @@ https://highlightjs.org/
436457
return matcher;
437458
}
438459

460+
function hasBeginCallbacks(rule) {
461+
return !!rule.onBegin;
462+
}
463+
464+
function hasCallbacks(rule) {
465+
return rule.onBegin || rule.endWhen;
466+
}
467+
439468
function compileMode(mode, parent) {
440469
if (mode.compiled)
441470
return;
@@ -501,19 +530,16 @@ https://highlightjs.org/
501530
return new RegExp(value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'm');
502531
}
503532

504-
function endOfMode(mode, matchPlusRemainder, lexeme) {
533+
function endOfMode(mode, matchPlusRemainder) {
505534
var modeEnded = testRe(mode.endRe, matchPlusRemainder);
506-
if (modeEnded && mode.endFilter) {
507-
modeEnded = mode.endFilter(mode.beginValue, lexeme);
508-
}
509535
if (modeEnded) {
510536
while (mode.endsParent && mode.parent) {
511537
mode = mode.parent;
512538
}
513539
return mode;
514540
}
515541
if (mode.endsWithParent) {
516-
return endOfMode(mode.parent, matchPlusRemainder, lexeme);
542+
return endOfMode(mode.parent, matchPlusRemainder);
517543
}
518544
}
519545

@@ -591,13 +617,15 @@ https://highlightjs.org/
591617

592618
function startNewMode(mode, lexeme) {
593619
result += mode.className? buildSpan(mode.className, '', true): '';
594-
top = Object.create(mode, {parent: {value: top}, beginValue: {value: lexeme}});
620+
top = Object.create(mode, {parent: {value: top}, userState: {value: {}}})
621+
return top;
595622
}
596623

597624

598625
function doBeginMatch(match) {
599626
var lexeme = match[0];
600627
var new_mode = match.rule;
628+
var mode;
601629

602630
if (new_mode && new_mode.endSameAsBegin) {
603631
new_mode.endRe = escapeRe( lexeme );
@@ -614,16 +642,24 @@ https://highlightjs.org/
614642
mode_buffer = lexeme;
615643
}
616644
}
617-
startNewMode(new_mode, lexeme);
645+
mode = startNewMode(new_mode, lexeme);
646+
if (mode.onBegin) {
647+
mode.onBegin(match.raw, mode.userState)
648+
}
618649
return new_mode.returnBegin ? 0 : lexeme.length;
619650
}
620651

621652
function doEndMatch(match) {
622653
var lexeme = match[0];
623654
var matchPlusRemainder = value.substr(match.index);
624-
var end_mode = endOfMode(top, matchPlusRemainder, lexeme);
655+
var end_mode = endOfMode(top, matchPlusRemainder);
625656
if (!end_mode) { return; }
626657

658+
if (end_mode.endWhen) {
659+
var doEnd = end_mode.endWhen(match.raw, end_mode.userState)
660+
if (doEnd === false) { return; }
661+
}
662+
627663
var origin = top;
628664
if (origin.skip) {
629665
mode_buffer += lexeme;

src/languages/cpp.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,10 @@ function(hljs) {
2828
illegal: '.'
2929
},
3030
{
31-
begin: /(?:u8?|U|L)?R"[^()\\ ]{0,16}\(/,
32-
end: /\)[^()\\ ]{0,16}"/,
33-
endFilter: function(begin, end) {
34-
var quote = begin.indexOf('"');
35-
var beginDelimiter = begin.substring(quote + 1, begin.length - 1);
36-
var endDelimiter = end.substring(1, end.length - 1);
37-
return beginDelimiter == endDelimiter;
38-
},
31+
begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
32+
end: /\)([^()\\ ]{0,16})"/,
33+
onBegin: function(m, state) { state.heredoc = m[1] },
34+
endWhen: function(m, state) { return state.heredoc === m[1] },
3935
}
4036
]
4137
};

0 commit comments

Comments
 (0)