Skip to content

Instantly share code, notes, and snippets.

@rogal111
Created December 1, 2013 21:51
Show Gist options
  • Select an option

  • Save rogal111/7741315 to your computer and use it in GitHub Desktop.

Select an option

Save rogal111/7741315 to your computer and use it in GitHub Desktop.
Custom parser for Codemirror for presell seo articles
Array.prototype.last = function() {
return this[this.length-1];
}
Array.prototype.random = function () {
return this[Math.floor(Math.random()*this.length)];
}
String.prototype.sample = function(start,end) {
res="";
var maxl=(typeof(end)=='undefined' ? this.length : end+1);
for(i=(typeof(start)=='undefined' ? 0 : start);i<maxl;i++)
{
ch=this[i];
if(ch=='{')
{
tmp=this.sampleParse(i);
res+=tmp.res;
i=tmp.pos;
}
else
res+=ch;
}
return res;
}
String.prototype.sampleParse = function(start){
var options=[];
var optionVal='';
maxl=this.length;
i=0;
for(i=start+1;i<maxl;i++){
ch=this[i];
if(ch=='{')
{
tmp=this.sampleParse(i);
optionVal+=tmp.res;
i=tmp.pos;
}
else if(ch=='|')
{
options.push(optionVal);
optionVal='';
}
else if(ch=='}')
{
options.push(optionVal);
return {res:options.random(),pos:i};
}
else { optionVal+=ch; }
}
return {res:'ERROR',pos:i};
}
CodeMirror.seoRangeFinder = function(cm, start) {
var line = start.line, lineText = cm.getLine(line);
var at = lineText.length, startChar, tokenType;
for (;;) {
var found = lineText.lastIndexOf("{", at);
if (found < start.ch) break;
startChar = found;
}
if (startChar == null) return;
var count = 1, lastLine = cm.lineCount(), end, endCh;
outer: for (var i = line; i < lastLine; ++i) {
var text = cm.getLine(i), pos = (i==line ? startChar:0);
for (;;) {
var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
if (nextOpen < 0) nextOpen = text.length;
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (pos == nextOpen) ++count;
else if (!--count) { end = i; endCh = pos; break outer; }
++pos;
}
}
if (end == null) return;
return {from: CodeMirror.Pos(line, startChar),
to: CodeMirror.Pos(end, endCh+1)};
};
Array.prototype.setLast = function(val) {
this[this.length-1]=val;
}
CodeMirror.defineMode("seo", function() {
function tokenBase (stream, state ) {
var styles=[];
var ch = stream.next();
var start=false;
var level=state.level;
var currentOption=state.optionNR.last();
if(ch==' ' && ((state.befores.last()==' ' && state.option_start)||state.last_char==' '))
styles.push('double-space');
else if(!/\s/.test(ch) && ch!='}' && ch!='{' && ch!='|' && ((/[,.]/.test(state.befores.last()) && state.option_start)||/[,.]/.test(state.last_char)))
{
styles.push('missing-space');
}
if(/[a-zżźćńółęąś]/.test(ch) && ((/[.]/.test(state.befores_nowhite.last()) && state.option_start)||/[.]/.test(state.last_nowhite_char)))
styles.push('upcase-mistake');
if (ch == '}') {
if(level==0)
styles.push('unexpected-token');
else
{
state.befores.pop();
state.optionNR.pop();
state.befores_nowhite.pop();
styles.push("tag"+level);
state.last_char=undefined;
state.last_nowhite_char=undefined;
state.level--;
}
}
else if (ch == "{") {
start=true;
state.befores.push(state.last_char==undefined ? state.befores.last() : state.last_char);
state.befores_nowhite.push(state.last_nowhite_char==undefined ? state.befores_nowhite.last() : state.last_nowhite_char);
styles.push("tag"+(level+1));
state.optionNR.push(0);
state.level++;
if(state.level==1)
state.groupId++;
}
else if (ch == "|") {
if(level==0)
styles.push('unexpected-token');
else
{
start=true;
state.optionNR.setLast(currentOption+1);
styles.push("tag"+level);
state.last_char=undefined;
state.last_nowhite_char=undefined;
}
}
else
{
styles.push("keyword"+level);
if(typeof(currentOption)=="number")
styles.push("option"+currentOption);
state.last_char=(stream.eol() ? "\n":ch);
if(!/\s/.test(ch))
state.last_nowhite_char=ch;
}
if(state.level>0 || ch=='}')
styles.push("group"+state.groupId);
state.option_start=start;
return styles.join(' ');
}
return {
startState: function () {
return {tokenize: tokenBase,option_start:false,level:0,groupStart:undefined,groupEnd:undefined,groupId:0,last_nowhite_char:undefined,last_char:undefined,befores:[],optionNR:[],befores_nowhite:[]};
},
token: function (stream, state) {
return state.tokenize(stream, state);
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment