summaryrefslogtreecommitdiff
path: root/codemirror_ui/lib/CodeMirror-2.3/mode/gfm/gfm.js
diff options
context:
space:
mode:
Diffstat (limited to 'codemirror_ui/lib/CodeMirror-2.3/mode/gfm/gfm.js')
-rw-r--r--codemirror_ui/lib/CodeMirror-2.3/mode/gfm/gfm.js144
1 files changed, 144 insertions, 0 deletions
diff --git a/codemirror_ui/lib/CodeMirror-2.3/mode/gfm/gfm.js b/codemirror_ui/lib/CodeMirror-2.3/mode/gfm/gfm.js
new file mode 100644
index 0000000..8f457c5
--- /dev/null
+++ b/codemirror_ui/lib/CodeMirror-2.3/mode/gfm/gfm.js
@@ -0,0 +1,144 @@
+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 'link';
+ }
+ 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) {
+ /* Parse GFM double bracket links */
+ if ((ch = stream.peek()) != undefined && ch == '[') {
+ stream.next(); // Advance the stream
+
+ /* Only handle double bracket links */
+ if ((ch = stream.peek()) == undefined || ch != '[') {
+ stream.backUp(1);
+ return state.token(stream, state);
+ }
+
+ while ((ch = stream.next()) != undefined && ch != ']') {}
+
+ if (ch == ']' && (ch = stream.next()) != undefined && ch == ']')
+ return 'link';
+
+ /* If we did not find the second ']' */
+ stream.backUp(1);
+ }
+
+ /* Match GFM latex formulas, as well as latex formulas within '$' */
+ if (stream.match(/^\$[^\$]+\$/)) {
+ return "string";
+ }
+
+ if (stream.match(/^\\\((.*?)\\\)/)) {
+ return "string";
+ }
+
+ if (stream.match(/^\$\$[^\$]+\$\$/)) {
+ return "string";
+ }
+
+ if (stream.match(/^\\\[(.*?)\\\]/)) {
+ return "string";
+ }
+
+ return state.token(stream, state);
+ }
+ }
+}, "markdown");