html5 boiler plate
[scannr.git] / js / flotr2 / examples / lib / codemirror / mode / gfm / gfm.js
blob:a/js/flotr2/examples/lib/codemirror/mode/gfm/gfm.js -> blob:b/js/flotr2/examples/lib/codemirror/mode/gfm/gfm.js
--- a/js/flotr2/examples/lib/codemirror/mode/gfm/gfm.js
+++ b/js/flotr2/examples/lib/codemirror/mode/gfm/gfm.js
@@ -1,1 +1,109 @@
+CodeMirror.defineMode("gfm", function(config, parserConfig) {
+  var mdMode = CodeMirror.getMode(config, "markdown");
+  var aliases = {
+    html: "htmlmixed",
+    js: "javascript",
+    json: "application/json",
+    c: "text/x-csrc",
+    "c++": "text/x-c++src",
+    java: "text/x-java",
+    csharp: "text/x-csharp",
+    "c#": "text/x-csharp",
+  };
 
+  // make this lazy so that we don't need to load GFM last
+  var getMode = (function () {
+    var i, modes = {}, mimes = {}, mime;
+
+    var list = CodeMirror.listModes();
+    for (i = 0; i < list.length; i++) {
+      modes[list[i]] = list[i];
+    }
+    var mimesList = CodeMirror.listMIMEs();
+    for (i = 0; i < mimesList.length; i++) {
+      mime = mimesList[i].mime;
+      mimes[mime] = mimesList[i].mime;
+    }
+
+    for (var a in aliases) {
+      if (aliases[a] in modes || aliases[a] in mimes)
+        modes[a] = aliases[a];
+    }
+    
+    return function (lang) {
+      return modes[lang] ? CodeMirror.getMode(config, modes[lang]) : null;
+    }
+  }());
+
+  function markdown(stream, state) {
+    // intercept fenced code blocks
+    if (stream.sol() && stream.match(/^```([\w+#]*)/)) {
+      // try switching mode
+      state.localMode = getMode(RegExp.$1)
+      if (state.localMode)
+        state.localState = state.localMode.startState();
+
+      state.token = local;
+      return 'code';
+    }
+
+    return mdMode.token(stream, state.mdState);
+  }
+
+  function local(stream, state) {
+    if (stream.sol() && stream.match(/^```/)) {
+      state.localMode = state.localState = null;
+      state.token = markdown;
+      return 'code';
+    }
+    else if (state.localMode) {
+      return state.localMode.token(stream, state.localState);
+    } else {
+      stream.skipToEnd();
+      return 'code';
+    }
+  }
+
+  // custom handleText to prevent emphasis in the middle of a word
+  // and add autolinking
+  function handleText(stream, mdState) {
+    var match;
+    if (stream.match(/^\w+:\/\/\S+/)) {
+      return 'linkhref';
+    }
+    if (stream.match(/^[^\[*\\<>` _][^\[*\\<>` ]*[^\[*\\<>` _]/)) {
+      return mdMode.getType(mdState);
+    }
+    if (match = stream.match(/^[^\[*\\<>` ]+/)) {
+      var word = match[0];
+      if (word[0] === '_' && word[word.length-1] === '_') {
+        stream.backUp(word.length);
+        return undefined;
+      }
+      return mdMode.getType(mdState);
+    }
+    if (stream.eatSpace()) {
+      return null;
+    }
+  }
+
+  return {
+    startState: function() {
+      var mdState = mdMode.startState();
+      mdState.text = handleText;
+      return {token: markdown, mode: "markdown", mdState: mdState,
+              localMode: null, localState: null};
+    },
+
+    copyState: function(state) {
+      return {token: state.token, mode: state.mode, mdState: CodeMirror.copyState(mdMode, state.mdState),
+              localMode: state.localMode,
+              localState: state.localMode ? CodeMirror.copyState(state.localMode, state.localState) : null};
+    },
+
+    token: function(stream, state) {
+      return state.token(stream, state);
+    }
+  }
+});
+