puffer/puffer_pages

View on GitHub
app/assets/javascripts/puffer/codemirror/yaml.js

Summary

Maintainability
C
1 day
Test Coverage
CodeMirror.defineMode("yaml", function() {
    
    var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
    var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
    
    return {
        token: function(stream, state) {
            var ch = stream.peek();
            var esc = state.escaped;
            state.escaped = false;
            /* comments */
            if (ch == "#") { stream.skipToEnd(); return "comment"; }
            if (state.literal && stream.indentation() > state.keyCol) {
                stream.skipToEnd(); return "string";
            } else if (state.literal) { state.literal = false; }
            if (stream.sol()) {
                state.keyCol = 0;
                state.pair = false;
                state.pairStart = false;
                /* document start */
                if(stream.match(/---/)) { return "def"; }
                /* document end */
                if (stream.match(/\.\.\./)) { return "def"; }
                /* array list item */
                if (stream.match(/\s*-\s+/)) { return 'meta'; }
            }
            /* pairs (associative arrays) -> key */
            if (!state.pair && stream.match(/^\s*([a-z0-9\._-])+(?=\s*:)/i)) {
                state.pair = true;
                state.keyCol = stream.indentation();
                return "atom";
            }
            if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
            
            /* inline pairs/lists */
            if (stream.match(/^(\{|\}|\[|\])/)) {
                if (ch == '{')
                    state.inlinePairs++;
                else if (ch == '}')
                    state.inlinePairs--;
                else if (ch == '[')
                    state.inlineList++;
                else
                    state.inlineList--;
                return 'meta';
            }
            
            /* list seperator */
            if (state.inlineList > 0 && !esc && ch == ',') {
                stream.next();
                return 'meta';
            }
            /* pairs seperator */
            if (state.inlinePairs > 0 && !esc && ch == ',') {
                state.keyCol = 0;
                state.pair = false;
                state.pairStart = false;
                stream.next();
                return 'meta';
            }
            
            /* start of value of a pair */
            if (state.pairStart) {
                /* block literals */
                if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
                /* references */
                if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
                /* numbers */
                if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
                if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
                /* keywords */
                if (stream.match(keywordRegex)) { return 'keyword'; }
            }

            /* nothing found, continue */
            state.pairStart = false;
            state.escaped = (ch == '\\');
            stream.next();
            return null;
        },
        startState: function() {
            return {
                pair: false,
                pairStart: false,
                keyCol: 0,
                inlinePairs: 0,
                inlineList: 0,
                literal: false,
                escaped: false
            };
        }
    };
});

CodeMirror.defineMIME("text/x-yaml", "yaml");