X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=to-be-integrated%2Fthird-party%2Fcodemirror-3.15%2Fmode%2Fsass%2Fsass.js;fp=to-be-integrated%2Fthird-party%2Fcodemirror-3.15%2Fmode%2Fsass%2Fsass.js;h=9c9a0dae079dbb701b0dea898aa788b13f6a4321;hb=31540dd504798e0aca69e10d8144fbedc5b16af8;hp=0000000000000000000000000000000000000000;hpb=937653fd70bbf7d95bcf870e7f2b46b4a8fec486;p=myslice.git diff --git a/to-be-integrated/third-party/codemirror-3.15/mode/sass/sass.js b/to-be-integrated/third-party/codemirror-3.15/mode/sass/sass.js new file mode 100644 index 00000000..9c9a0dae --- /dev/null +++ b/to-be-integrated/third-party/codemirror-3.15/mode/sass/sass.js @@ -0,0 +1,330 @@ +CodeMirror.defineMode("sass", function(config) { + var tokenRegexp = function(words){ + return new RegExp("^" + words.join("|")); + }; + + var keywords = ["true", "false", "null", "auto"]; + var keywordsRegexp = new RegExp("^" + keywords.join("|")); + + var operators = ["\\(", "\\)", "=", ">", "<", "==", ">=", "<=", "\\+", "-", "\\!=", "/", "\\*", "%", "and", "or", "not"]; + var opRegexp = tokenRegexp(operators); + + var pseudoElementsRegexp = /^::?[\w\-]+/; + + var urlTokens = function(stream, state){ + var ch = stream.peek(); + + if (ch === ")"){ + stream.next(); + state.tokenizer = tokenBase; + return "operator"; + }else if (ch === "("){ + stream.next(); + stream.eatSpace(); + + return "operator"; + }else if (ch === "'" || ch === '"'){ + state.tokenizer = buildStringTokenizer(stream.next()); + return "string"; + }else{ + state.tokenizer = buildStringTokenizer(")", false); + return "string"; + } + }; + var multilineComment = function(stream, state) { + if (stream.skipTo("*/")){ + stream.next(); + stream.next(); + state.tokenizer = tokenBase; + }else { + stream.next(); + } + + return "comment"; + }; + + var buildStringTokenizer = function(quote, greedy){ + if(greedy == null){ greedy = true; } + + function stringTokenizer(stream, state){ + var nextChar = stream.next(); + var peekChar = stream.peek(); + var previousChar = stream.string.charAt(stream.pos-2); + + var endingString = ((nextChar !== "\\" && peekChar === quote) || (nextChar === quote && previousChar !== "\\")); + + /* + console.log("previousChar: " + previousChar); + console.log("nextChar: " + nextChar); + console.log("peekChar: " + peekChar); + console.log("ending: " + endingString); + */ + + if (endingString){ + if (nextChar !== quote && greedy) { stream.next(); } + state.tokenizer = tokenBase; + return "string"; + }else if (nextChar === "#" && peekChar === "{"){ + state.tokenizer = buildInterpolationTokenizer(stringTokenizer); + stream.next(); + return "operator"; + }else { + return "string"; + } + } + + return stringTokenizer; + }; + + var buildInterpolationTokenizer = function(currentTokenizer){ + return function(stream, state){ + if (stream.peek() === "}"){ + stream.next(); + state.tokenizer = currentTokenizer; + return "operator"; + }else{ + return tokenBase(stream, state); + } + }; + }; + + var indent = function(state){ + if (state.indentCount == 0){ + state.indentCount++; + var lastScopeOffset = state.scopes[0].offset; + var currentOffset = lastScopeOffset + config.indentUnit; + state.scopes.unshift({ offset:currentOffset }); + } + }; + + var dedent = function(state){ + if (state.scopes.length == 1) { return; } + + state.scopes.shift(); + }; + + var tokenBase = function(stream, state) { + var ch = stream.peek(); + + // Single line Comment + if (stream.match('//')) { + stream.skipToEnd(); + return "comment"; + } + + // Multiline Comment + if (stream.match('/*')){ + state.tokenizer = multilineComment; + return state.tokenizer(stream, state); + } + + // Interpolation + if (stream.match('#{')){ + state.tokenizer = buildInterpolationTokenizer(tokenBase); + return "operator"; + } + + if (ch === "."){ + stream.next(); + + // Match class selectors + if (stream.match(/^[\w-]+/)){ + indent(state); + return "atom"; + }else if (stream.peek() === "#"){ + indent(state); + return "atom"; + }else{ + return "operator"; + } + } + + if (ch === "#"){ + stream.next(); + + // Hex numbers + if (stream.match(/[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/)){ + return "number"; + } + + // ID selectors + if (stream.match(/^[\w-]+/)){ + indent(state); + return "atom"; + } + + if (stream.peek() === "#"){ + indent(state); + return "atom"; + } + } + + // Numbers + if (stream.match(/^-?[0-9\.]+/)){ + return "number"; + } + + // Units + if (stream.match(/^(px|em|in)\b/)){ + return "unit"; + } + + if (stream.match(keywordsRegexp)){ + return "keyword"; + } + + if (stream.match(/^url/) && stream.peek() === "("){ + state.tokenizer = urlTokens; + return "atom"; + } + + // Variables + if (ch === "$"){ + stream.next(); + stream.eatWhile(/[\w-]/); + + if (stream.peek() === ":"){ + stream.next(); + return "variable-2"; + }else{ + return "variable-3"; + } + } + + if (ch === "!"){ + stream.next(); + + if (stream.match(/^[\w]+/)){ + return "keyword"; + } + + return "operator"; + } + + if (ch === "="){ + stream.next(); + + // Match shortcut mixin definition + if (stream.match(/^[\w-]+/)){ + indent(state); + return "meta"; + }else { + return "operator"; + } + } + + if (ch === "+"){ + stream.next(); + + // Match shortcut mixin definition + if (stream.match(/^[\w-]+/)){ + return "variable-3"; + }else { + return "operator"; + } + } + + // Indent Directives + if (stream.match(/^@(else if|if|media|else|for|each|while|mixin|function)/)){ + indent(state); + return "meta"; + } + + // Other Directives + if (ch === "@"){ + stream.next(); + stream.eatWhile(/[\w-]/); + return "meta"; + } + + // Strings + if (ch === '"' || ch === "'"){ + stream.next(); + state.tokenizer = buildStringTokenizer(ch); + return "string"; + } + + // Pseudo element selectors + if (ch == ':' && stream.match(pseudoElementsRegexp)){ + return "keyword"; + } + + // atoms + if (stream.eatWhile(/[\w-&]/)){ + // matches a property definition + if (stream.peek() === ":" && !stream.match(pseudoElementsRegexp, false)) + return "property"; + else + return "atom"; + } + + if (stream.match(opRegexp)){ + return "operator"; + } + + // If we haven't returned by now, we move 1 character + // and return an error + stream.next(); + return null; + }; + + var tokenLexer = function(stream, state) { + if (stream.sol()){ + state.indentCount = 0; + } + var style = state.tokenizer(stream, state); + var current = stream.current(); + + if (current === "@return"){ + dedent(state); + } + + if (style === "atom"){ + indent(state); + } + + if (style !== null){ + var startOfToken = stream.pos - current.length; + var withCurrentIndent = startOfToken + (config.indentUnit * state.indentCount); + + var newScopes = []; + + for (var i = 0; i < state.scopes.length; i++){ + var scope = state.scopes[i]; + + if (scope.offset <= withCurrentIndent){ + newScopes.push(scope); + } + } + + state.scopes = newScopes; + } + + + return style; + }; + + return { + startState: function() { + return { + tokenizer: tokenBase, + scopes: [{offset: 0, type: 'sass'}], + definedVars: [], + definedMixins: [] + }; + }, + token: function(stream, state) { + var style = tokenLexer(stream, state); + + state.lastToken = { style: style, content: stream.current() }; + + return style; + }, + + indent: function(state) { + return state.scopes[0].offset; + } + }; +}); + +CodeMirror.defineMIME("text/x-sass", "sass");