2014-10-19 3 views
0

Я пытаюсь разработать простой режим для codemirror. Этот режим будет окрасить абзацы альтернативно синим и зеленым. Разделение между абзацем - это пустая строка или строка, содержащая только пробелы.Новый режим для codemirror: Обнаружение пустой строки в потоке

Вот вариант кода, который работает, но с большой проблемой, что пустые строки не обнаружено:

CodeMirror.defineMode("rt", function() { 
    return { 
    startState: function() {return {state1: true};}, 
    token: function(stream, state) { 
    if (stream.match(/\s\s*/)!=null){ # this fails to detect empty lines 
     state.state1 = !state.state1; 
    } 
    stream.skipToEnd(); 
    if (state.state1) { return "status1"; } 
    return "status2"; 
    } 
    }; 
}); 

если применить его к следующему тексту:

line 1 
line 2 # the next line is just a backspace and is not detected 

line 3 
line 4 # the next line is a few spaces followed by a backspace, it is detected 

line 5 
line 6 

его цвета от строки 1 до строки 4 в одном цвете и строки 5 до строки 6 в другой, что ожидается.

Я пытаюсь найти способ обновить свой код, чтобы он обнаружил пустую строку между строкой 2 и линией 3. Любой способ сделать это?

ответ

1

Документация CodeMirror говорит:

По умолчанию пустые строки просто перескакивает когда tokenizing документ. Для языков, имеющих значительные пустые строки, вы можете определить пустую строку (состояние) в режиме, который будет вызываться, когда пустая строка передается, чтобы она могла обновить состояние анализатора.

(http://codemirror.net/doc/manual.html#modeapi)

Следующий код работает (blankLine добавлена ​​функция):

CodeMirror.defineMode("rt", function() { 
    return { 
    startState: function() {return {state1: true};}, 
    blankLine: function (state){ state.state1 = !state.state1; }, 
    token: function(stream, state) { 
    console.log(stream) 
    if (stream.match(/^\s*$/)!=null){ 
     state.state1 = !state.state1; 
    } 
    stream.skipToEnd(); 
    if (state.state1) { return "status1"; } 
    return "status2"; 
    } 
    }; 
}); 
2

Вы можете обнаружить забой с [\b] в JavaScript регулярное выражение: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

BTW /\s\s*/ может быть упрощено до /\s+/ Однако, если вы хотите, чтобы обнаружить «пустую строку или строку, содержащую только пробелы», вы можете использовать /\s*/.

Кроме того, если вы не заботитесь о фактическом результатах массиве регулярного выражения, вы можете использовать вместо test(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test

Вы можете использовать ^, чтобы указать начало строки и $ на конце линии.

Поэтому код будет примерно так:

CodeMirror.defineMode("rt", function() { 
    return { 
    startState: function() { 
     return { 
     state1: true 
     }; 
    }, 
    token: function(stream, state) { 
     if (/^\s*$/m.test(stream)) { 
     state.state1 = !state.state1; 
     } 
     stream.skipToEnd(); 
     return state.state1 ? "status1" : "status2"; 
    } 
    }; 
}); 

Флаг м используется для указания того, что многострочный входной строки следует рассматривать как несколько строк. Если используется флаг m,^и $ соответствуют началу или концу любой строки внутри входной строки вместо начала или конца всей строки. Пример: http://www.w3schools.com/jsref/jsref_regexp_m.asp

+0

Я боюсь, что это приводит к линии чередуя цвета, а не пункты ^^; – Vince

+0

О, извините, я забыл '^' и '$' из регулярного выражения. Можете ли вы попробовать этот? – AlexStack

+0

все еще нет успеха. «Пустые строки», похоже, вообще не проходят через функцию, как будто codemirror каким-то образом пропускает их перед началом функции ... – Vince