aboutsummaryrefslogtreecommitdiff
path: root/imports/codemirror/mode/gfm/gfm.js
diff options
context:
space:
mode:
Diffstat (limited to 'imports/codemirror/mode/gfm/gfm.js')
-rwxr-xr-ximports/codemirror/mode/gfm/gfm.js108
1 files changed, 108 insertions, 0 deletions
diff --git a/imports/codemirror/mode/gfm/gfm.js b/imports/codemirror/mode/gfm/gfm.js
new file mode 100755
index 00000000..1e9d7d87
--- /dev/null
+++ b/imports/codemirror/mode/gfm/gfm.js
@@ -0,0 +1,108 @@
1CodeMirror.defineMode("gfm", function(config, parserConfig) {
2 var mdMode = CodeMirror.getMode(config, "markdown");
3 var aliases = {
4 html: "htmlmixed",
5 js: "javascript",
6 json: "application/json",
7 c: "text/x-csrc",
8 "c++": "text/x-c++src",
9 java: "text/x-java",
10 csharp: "text/x-csharp",
11 "c#": "text/x-csharp",
12 };
13
14 // make this lazy so that we don't need to load GFM last
15 var getMode = (function () {
16 var i, modes = {}, mimes = {}, mime;
17
18 var list = CodeMirror.listModes();
19 for (i = 0; i < list.length; i++) {
20 modes[list[i]] = list[i];
21 }
22 var mimesList = CodeMirror.listMIMEs();
23 for (i = 0; i < mimesList.length; i++) {
24 mime = mimesList[i].mime;
25 mimes[mime] = mimesList[i].mime;
26 }
27
28 for (var a in aliases) {
29 if (aliases[a] in modes || aliases[a] in mimes)
30 modes[a] = aliases[a];
31 }
32
33 return function (lang) {
34 return modes[lang] ? CodeMirror.getMode(config, modes[lang]) : null;
35 }
36 }());
37
38 function markdown(stream, state) {
39 // intercept fenced code blocks
40 if (stream.sol() && stream.match(/^```([\w+#]*)/)) {
41 // try switching mode
42 state.localMode = getMode(RegExp.$1)
43 if (state.localMode)
44 state.localState = state.localMode.startState();
45
46 state.token = local;
47 return 'code';
48 }
49
50 return mdMode.token(stream, state.mdState);
51 }
52
53 function local(stream, state) {
54 if (stream.sol() && stream.match(/^```/)) {
55 state.localMode = state.localState = null;
56 state.token = markdown;
57 return 'code';
58 }
59 else if (state.localMode) {
60 return state.localMode.token(stream, state.localState);
61 } else {
62 stream.skipToEnd();
63 return 'code';
64 }
65 }
66
67 // custom handleText to prevent emphasis in the middle of a word
68 // and add autolinking
69 function handleText(stream, mdState) {
70 var match;
71 if (stream.match(/^\w+:\/\/\S+/)) {
72 return 'linkhref';
73 }
74 if (stream.match(/^[^\[*\\<>` _][^\[*\\<>` ]*[^\[*\\<>` _]/)) {
75 return mdMode.getType(mdState);
76 }
77 if (match = stream.match(/^[^\[*\\<>` ]+/)) {
78 var word = match[0];
79 if (word[0] === '_' && word[word.length-1] === '_') {
80 stream.backUp(word.length);
81 return undefined;
82 }
83 return mdMode.getType(mdState);
84 }
85 if (stream.eatSpace()) {
86 return null;
87 }
88 }
89
90 return {
91 startState: function() {
92 var mdState = mdMode.startState();
93 mdState.text = handleText;
94 return {token: markdown, mode: "markdown", mdState: mdState,
95 localMode: null, localState: null};
96 },
97
98 copyState: function(state) {
99 return {token: state.token, mode: state.mode, mdState: CodeMirror.copyState(mdMode, state.mdState),
100 localMode: state.localMode,
101 localState: state.localMode ? CodeMirror.copyState(state.localMode, state.localState) : null};
102 },
103
104 token: function(stream, state) {
105 return state.token(stream, state);
106 }
107 }
108});