sn-collab-editor 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,816 @@
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("../xml/xml"), require("../meta"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "../xml/xml", "../meta"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
15
+
16
+ var htmlMode = CodeMirror.getMode(cmCfg, "text/html");
17
+ var htmlModeMissing = htmlMode.name == "null"
18
+
19
+ function getMode(name) {
20
+ if (CodeMirror.findModeByName) {
21
+ var found = CodeMirror.findModeByName(name);
22
+ if (found) name = found.mime || found.mimes[0];
23
+ }
24
+ var mode = CodeMirror.getMode(cmCfg, name);
25
+ return mode.name == "null" ? null : mode;
26
+ }
27
+
28
+ // Should characters that affect highlighting be highlighted separate?
29
+ // Does not include characters that will be output (such as `1.` and `-` for lists)
30
+ if (modeCfg.highlightFormatting === undefined)
31
+ modeCfg.highlightFormatting = false;
32
+
33
+ // Maximum number of nested blockquotes. Set to 0 for infinite nesting.
34
+ // Excess `>` will emit `error` token.
35
+ if (modeCfg.maxBlockquoteDepth === undefined)
36
+ modeCfg.maxBlockquoteDepth = 0;
37
+
38
+ // Should underscores in words open/close em/strong?
39
+ if (modeCfg.underscoresBreakWords === undefined)
40
+ modeCfg.underscoresBreakWords = true;
41
+
42
+ // Use `fencedCodeBlocks` to configure fenced code blocks. false to
43
+ // disable, string to specify a precise regexp that the fence should
44
+ // match, and true to allow three or more backticks or tildes (as
45
+ // per CommonMark).
46
+
47
+ // Turn on task lists? ("- [ ] " and "- [x] ")
48
+ if (modeCfg.taskLists === undefined) modeCfg.taskLists = false;
49
+
50
+ // Turn on strikethrough syntax
51
+ if (modeCfg.strikethrough === undefined)
52
+ modeCfg.strikethrough = false;
53
+
54
+ // Allow token types to be overridden by user-provided token types.
55
+ if (modeCfg.tokenTypeOverrides === undefined)
56
+ modeCfg.tokenTypeOverrides = {};
57
+
58
+ var tokenTypes = {
59
+ header: "header",
60
+ code: "comment",
61
+ quote: "quote",
62
+ list1: "variable-2",
63
+ list2: "variable-3",
64
+ list3: "keyword",
65
+ hr: "hr",
66
+ image: "image",
67
+ imageAltText: "image-alt-text",
68
+ imageMarker: "image-marker",
69
+ formatting: "formatting",
70
+ linkInline: "link",
71
+ linkEmail: "link",
72
+ linkText: "link",
73
+ linkHref: "string",
74
+ em: "em",
75
+ strong: "strong",
76
+ strikethrough: "strikethrough"
77
+ };
78
+
79
+ for (var tokenType in tokenTypes) {
80
+ if (tokenTypes.hasOwnProperty(tokenType) && modeCfg.tokenTypeOverrides[tokenType]) {
81
+ tokenTypes[tokenType] = modeCfg.tokenTypeOverrides[tokenType];
82
+ }
83
+ }
84
+
85
+ var hrRE = /^([*\-_])(?:\s*\1){2,}\s*$/
86
+ , listRE = /^(?:[*\-+]|^[0-9]+([.)]))\s+/
87
+ , taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
88
+ , atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
89
+ , setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
90
+ , textRE = /^[^#!\[\]*_\\<>` "'(~]+/
91
+ , fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
92
+ ")[ \\t]*([\\w+#\-]*)");
93
+
94
+ function switchInline(stream, state, f) {
95
+ state.f = state.inline = f;
96
+ return f(stream, state);
97
+ }
98
+
99
+ function switchBlock(stream, state, f) {
100
+ state.f = state.block = f;
101
+ return f(stream, state);
102
+ }
103
+
104
+ function lineIsEmpty(line) {
105
+ return !line || !/\S/.test(line.string)
106
+ }
107
+
108
+ // Blocks
109
+
110
+ function blankLine(state) {
111
+ // Reset linkTitle state
112
+ state.linkTitle = false;
113
+ // Reset EM state
114
+ state.em = false;
115
+ // Reset STRONG state
116
+ state.strong = false;
117
+ // Reset strikethrough state
118
+ state.strikethrough = false;
119
+ // Reset state.quote
120
+ state.quote = 0;
121
+ // Reset state.indentedCode
122
+ state.indentedCode = false;
123
+ if (htmlModeMissing && state.f == htmlBlock) {
124
+ state.f = inlineNormal;
125
+ state.block = blockNormal;
126
+ }
127
+ // Reset state.trailingSpace
128
+ state.trailingSpace = 0;
129
+ state.trailingSpaceNewLine = false;
130
+ // Mark this line as blank
131
+ state.prevLine = state.thisLine
132
+ state.thisLine = null
133
+ return null;
134
+ }
135
+
136
+ function blockNormal(stream, state) {
137
+
138
+ var sol = stream.sol();
139
+
140
+ var prevLineIsList = state.list !== false,
141
+ prevLineIsIndentedCode = state.indentedCode;
142
+
143
+ state.indentedCode = false;
144
+
145
+ if (prevLineIsList) {
146
+ if (state.indentationDiff >= 0) { // Continued list
147
+ if (state.indentationDiff < 4) { // Only adjust indentation if *not* a code block
148
+ state.indentation -= state.indentationDiff;
149
+ }
150
+ state.list = null;
151
+ } else if (state.indentation > 0) {
152
+ state.list = null;
153
+ } else { // No longer a list
154
+ state.list = false;
155
+ }
156
+ }
157
+
158
+ var match = null;
159
+ if (state.indentationDiff >= 4) {
160
+ stream.skipToEnd();
161
+ if (prevLineIsIndentedCode || lineIsEmpty(state.prevLine)) {
162
+ state.indentation -= 4;
163
+ state.indentedCode = true;
164
+ return tokenTypes.code;
165
+ } else {
166
+ return null;
167
+ }
168
+ } else if (stream.eatSpace()) {
169
+ return null;
170
+ } else if ((match = stream.match(atxHeaderRE)) && match[1].length <= 6) {
171
+ state.header = match[1].length;
172
+ if (modeCfg.highlightFormatting) state.formatting = "header";
173
+ state.f = state.inline;
174
+ return getType(state);
175
+ } else if (!lineIsEmpty(state.prevLine) && !state.quote && !prevLineIsList &&
176
+ !prevLineIsIndentedCode && (match = stream.match(setextHeaderRE))) {
177
+ state.header = match[0].charAt(0) == '=' ? 1 : 2;
178
+ if (modeCfg.highlightFormatting) state.formatting = "header";
179
+ state.f = state.inline;
180
+ return getType(state);
181
+ } else if (stream.eat('>')) {
182
+ state.quote = sol ? 1 : state.quote + 1;
183
+ if (modeCfg.highlightFormatting) state.formatting = "quote";
184
+ stream.eatSpace();
185
+ return getType(state);
186
+ } else if (stream.peek() === '[') {
187
+ return switchInline(stream, state, footnoteLink);
188
+ } else if (stream.match(hrRE, true)) {
189
+ state.hr = true;
190
+ return tokenTypes.hr;
191
+ } else if (match = stream.match(listRE)) {
192
+ var listType = match[1] ? "ol" : "ul";
193
+ state.indentation = stream.column() + stream.current().length;
194
+ state.list = true;
195
+
196
+ // While this list item's marker's indentation
197
+ // is less than the deepest list item's content's indentation,
198
+ // pop the deepest list item indentation off the stack.
199
+ while (state.listStack && stream.column() < state.listStack[state.listStack.length - 1]) {
200
+ state.listStack.pop();
201
+ }
202
+
203
+ // Add this list item's content's indentation to the stack
204
+ state.listStack.push(state.indentation);
205
+
206
+ if (modeCfg.taskLists && stream.match(taskListRE, false)) {
207
+ state.taskList = true;
208
+ }
209
+ state.f = state.inline;
210
+ if (modeCfg.highlightFormatting) state.formatting = ["list", "list-" + listType];
211
+ return getType(state);
212
+ } else if (modeCfg.fencedCodeBlocks && (match = stream.match(fencedCodeRE, true))) {
213
+ state.fencedChars = match[1]
214
+ // try switching mode
215
+ state.localMode = getMode(match[2]);
216
+ if (state.localMode) state.localState = CodeMirror.startState(state.localMode);
217
+ state.f = state.block = local;
218
+ if (modeCfg.highlightFormatting) state.formatting = "code-block";
219
+ state.code = -1
220
+ return getType(state);
221
+ }
222
+
223
+ return switchInline(stream, state, state.inline);
224
+ }
225
+
226
+ function htmlBlock(stream, state) {
227
+ var style = htmlMode.token(stream, state.htmlState);
228
+ if (!htmlModeMissing) {
229
+ var inner = CodeMirror.innerMode(htmlMode, state.htmlState)
230
+ if ((inner.mode.name == "xml" && inner.state.tagStart === null &&
231
+ (!inner.state.context && inner.state.tokenize.isInText)) ||
232
+ (state.md_inside && stream.current().indexOf(">") > -1)) {
233
+ state.f = inlineNormal;
234
+ state.block = blockNormal;
235
+ state.htmlState = null;
236
+ }
237
+ }
238
+ return style;
239
+ }
240
+
241
+ function local(stream, state) {
242
+ if (state.fencedChars && stream.match(state.fencedChars)) {
243
+ if (modeCfg.highlightFormatting) state.formatting = "code-block";
244
+ state.localMode = state.localState = null;
245
+ state.f = state.block = leavingLocal;
246
+ return getType(state)
247
+ } else if (state.fencedChars && stream.skipTo(state.fencedChars)) {
248
+ return "comment"
249
+ } else if (state.localMode) {
250
+ return state.localMode.token(stream, state.localState);
251
+ } else {
252
+ stream.skipToEnd();
253
+ return tokenTypes.code;
254
+ }
255
+ }
256
+
257
+ function leavingLocal(stream, state) {
258
+ stream.match(state.fencedChars);
259
+ state.block = blockNormal;
260
+ state.f = inlineNormal;
261
+ state.fencedChars = null;
262
+ if (modeCfg.highlightFormatting) state.formatting = "code-block";
263
+ state.code = 1
264
+ var returnType = getType(state);
265
+ state.code = 0
266
+ return returnType;
267
+ }
268
+
269
+ // Inline
270
+ function getType(state) {
271
+ var styles = [];
272
+
273
+ if (state.formatting) {
274
+ styles.push(tokenTypes.formatting);
275
+
276
+ if (typeof state.formatting === "string") state.formatting = [state.formatting];
277
+
278
+ for (var i = 0; i < state.formatting.length; i++) {
279
+ styles.push(tokenTypes.formatting + "-" + state.formatting[i]);
280
+
281
+ if (state.formatting[i] === "header") {
282
+ styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.header);
283
+ }
284
+
285
+ // Add `formatting-quote` and `formatting-quote-#` for blockquotes
286
+ // Add `error` instead if the maximum blockquote nesting depth is passed
287
+ if (state.formatting[i] === "quote") {
288
+ if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
289
+ styles.push(tokenTypes.formatting + "-" + state.formatting[i] + "-" + state.quote);
290
+ } else {
291
+ styles.push("error");
292
+ }
293
+ }
294
+ }
295
+ }
296
+
297
+ if (state.taskOpen) {
298
+ styles.push("meta");
299
+ return styles.length ? styles.join(' ') : null;
300
+ }
301
+ if (state.taskClosed) {
302
+ styles.push("property");
303
+ return styles.length ? styles.join(' ') : null;
304
+ }
305
+
306
+ if (state.linkHref) {
307
+ styles.push(tokenTypes.linkHref, "url");
308
+ } else { // Only apply inline styles to non-url text
309
+ if (state.strong) { styles.push(tokenTypes.strong); }
310
+ if (state.em) { styles.push(tokenTypes.em); }
311
+ if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
312
+ if (state.linkText) { styles.push(tokenTypes.linkText); }
313
+ if (state.code) { styles.push(tokenTypes.code); }
314
+ if (state.image) { styles.push(tokenTypes.image); }
315
+ if (state.imageAltText) { styles.push(tokenTypes.imageAltText, "link"); }
316
+ if (state.imageMarker) { styles.push(tokenTypes.imageMarker); }
317
+ }
318
+
319
+ if (state.header) { styles.push(tokenTypes.header, tokenTypes.header + "-" + state.header); }
320
+
321
+ if (state.quote) {
322
+ styles.push(tokenTypes.quote);
323
+
324
+ // Add `quote-#` where the maximum for `#` is modeCfg.maxBlockquoteDepth
325
+ if (!modeCfg.maxBlockquoteDepth || modeCfg.maxBlockquoteDepth >= state.quote) {
326
+ styles.push(tokenTypes.quote + "-" + state.quote);
327
+ } else {
328
+ styles.push(tokenTypes.quote + "-" + modeCfg.maxBlockquoteDepth);
329
+ }
330
+ }
331
+
332
+ if (state.list !== false) {
333
+ var listMod = (state.listStack.length - 1) % 3;
334
+ if (!listMod) {
335
+ styles.push(tokenTypes.list1);
336
+ } else if (listMod === 1) {
337
+ styles.push(tokenTypes.list2);
338
+ } else {
339
+ styles.push(tokenTypes.list3);
340
+ }
341
+ }
342
+
343
+ if (state.trailingSpaceNewLine) {
344
+ styles.push("trailing-space-new-line");
345
+ } else if (state.trailingSpace) {
346
+ styles.push("trailing-space-" + (state.trailingSpace % 2 ? "a" : "b"));
347
+ }
348
+
349
+ return styles.length ? styles.join(' ') : null;
350
+ }
351
+
352
+ function handleText(stream, state) {
353
+ if (stream.match(textRE, true)) {
354
+ return getType(state);
355
+ }
356
+ return undefined;
357
+ }
358
+
359
+ function inlineNormal(stream, state) {
360
+ var style = state.text(stream, state);
361
+ if (typeof style !== 'undefined')
362
+ return style;
363
+
364
+ if (state.list) { // List marker (*, +, -, 1., etc)
365
+ state.list = null;
366
+ return getType(state);
367
+ }
368
+
369
+ if (state.taskList) {
370
+ var taskOpen = stream.match(taskListRE, true)[1] !== "x";
371
+ if (taskOpen) state.taskOpen = true;
372
+ else state.taskClosed = true;
373
+ if (modeCfg.highlightFormatting) state.formatting = "task";
374
+ state.taskList = false;
375
+ return getType(state);
376
+ }
377
+
378
+ state.taskOpen = false;
379
+ state.taskClosed = false;
380
+
381
+ if (state.header && stream.match(/^#+$/, true)) {
382
+ if (modeCfg.highlightFormatting) state.formatting = "header";
383
+ return getType(state);
384
+ }
385
+
386
+ // Get sol() value now, before character is consumed
387
+ var sol = stream.sol();
388
+
389
+ var ch = stream.next();
390
+
391
+ // Matches link titles present on next line
392
+ if (state.linkTitle) {
393
+ state.linkTitle = false;
394
+ var matchCh = ch;
395
+ if (ch === '(') {
396
+ matchCh = ')';
397
+ }
398
+ matchCh = (matchCh+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
399
+ var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh;
400
+ if (stream.match(new RegExp(regex), true)) {
401
+ return tokenTypes.linkHref;
402
+ }
403
+ }
404
+
405
+ // If this block is changed, it may need to be updated in GFM mode
406
+ if (ch === '`') {
407
+ var previousFormatting = state.formatting;
408
+ if (modeCfg.highlightFormatting) state.formatting = "code";
409
+ stream.eatWhile('`');
410
+ var count = stream.current().length
411
+ if (state.code == 0) {
412
+ state.code = count
413
+ return getType(state)
414
+ } else if (count == state.code) { // Must be exact
415
+ var t = getType(state)
416
+ state.code = 0
417
+ return t
418
+ } else {
419
+ state.formatting = previousFormatting
420
+ return getType(state)
421
+ }
422
+ } else if (state.code) {
423
+ return getType(state);
424
+ }
425
+
426
+ if (ch === '\\') {
427
+ stream.next();
428
+ if (modeCfg.highlightFormatting) {
429
+ var type = getType(state);
430
+ var formattingEscape = tokenTypes.formatting + "-escape";
431
+ return type ? type + " " + formattingEscape : formattingEscape;
432
+ }
433
+ }
434
+
435
+ if (ch === '!' && stream.match(/\[[^\]]*\] ?(?:\(|\[)/, false)) {
436
+ state.imageMarker = true;
437
+ state.image = true;
438
+ if (modeCfg.highlightFormatting) state.formatting = "image";
439
+ return getType(state);
440
+ }
441
+
442
+ if (ch === '[' && state.imageMarker && stream.match(/[^\]]*\](\(.*?\)| ?\[.*?\])/, false)) {
443
+ state.imageMarker = false;
444
+ state.imageAltText = true
445
+ if (modeCfg.highlightFormatting) state.formatting = "image";
446
+ return getType(state);
447
+ }
448
+
449
+ if (ch === ']' && state.imageAltText) {
450
+ if (modeCfg.highlightFormatting) state.formatting = "image";
451
+ var type = getType(state);
452
+ state.imageAltText = false;
453
+ state.image = false;
454
+ state.inline = state.f = linkHref;
455
+ return type;
456
+ }
457
+
458
+ if (ch === '[' && stream.match(/[^\]]*\](\(.*\)| ?\[.*?\])/, false) && !state.image) {
459
+ state.linkText = true;
460
+ if (modeCfg.highlightFormatting) state.formatting = "link";
461
+ return getType(state);
462
+ }
463
+
464
+ if (ch === ']' && state.linkText && stream.match(/\(.*?\)| ?\[.*?\]/, false)) {
465
+ if (modeCfg.highlightFormatting) state.formatting = "link";
466
+ var type = getType(state);
467
+ state.linkText = false;
468
+ state.inline = state.f = linkHref;
469
+ return type;
470
+ }
471
+
472
+ if (ch === '<' && stream.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/, false)) {
473
+ state.f = state.inline = linkInline;
474
+ if (modeCfg.highlightFormatting) state.formatting = "link";
475
+ var type = getType(state);
476
+ if (type){
477
+ type += " ";
478
+ } else {
479
+ type = "";
480
+ }
481
+ return type + tokenTypes.linkInline;
482
+ }
483
+
484
+ if (ch === '<' && stream.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/, false)) {
485
+ state.f = state.inline = linkInline;
486
+ if (modeCfg.highlightFormatting) state.formatting = "link";
487
+ var type = getType(state);
488
+ if (type){
489
+ type += " ";
490
+ } else {
491
+ type = "";
492
+ }
493
+ return type + tokenTypes.linkEmail;
494
+ }
495
+
496
+ if (ch === '<' && stream.match(/^(!--|[a-z]+(?:\s+[a-z_:.\-]+(?:\s*=\s*[^ >]+)?)*\s*>)/i, false)) {
497
+ var end = stream.string.indexOf(">", stream.pos);
498
+ if (end != -1) {
499
+ var atts = stream.string.substring(stream.start, end);
500
+ if (/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(atts)) state.md_inside = true;
501
+ }
502
+ stream.backUp(1);
503
+ state.htmlState = CodeMirror.startState(htmlMode);
504
+ return switchBlock(stream, state, htmlBlock);
505
+ }
506
+
507
+ if (ch === '<' && stream.match(/^\/\w*?>/)) {
508
+ state.md_inside = false;
509
+ return "tag";
510
+ }
511
+
512
+ var ignoreUnderscore = false;
513
+ if (!modeCfg.underscoresBreakWords) {
514
+ if (ch === '_' && stream.peek() !== '_' && stream.match(/(\w)/, false)) {
515
+ var prevPos = stream.pos - 2;
516
+ if (prevPos >= 0) {
517
+ var prevCh = stream.string.charAt(prevPos);
518
+ if (prevCh !== '_' && prevCh.match(/(\w)/, false)) {
519
+ ignoreUnderscore = true;
520
+ }
521
+ }
522
+ }
523
+ }
524
+ if (ch === '*' || (ch === '_' && !ignoreUnderscore)) {
525
+ if (sol && stream.peek() === ' ') {
526
+ // Do nothing, surrounded by newline and space
527
+ } else if (state.strong === ch && stream.eat(ch)) { // Remove STRONG
528
+ if (modeCfg.highlightFormatting) state.formatting = "strong";
529
+ var t = getType(state);
530
+ state.strong = false;
531
+ return t;
532
+ } else if (!state.strong && stream.eat(ch)) { // Add STRONG
533
+ state.strong = ch;
534
+ if (modeCfg.highlightFormatting) state.formatting = "strong";
535
+ return getType(state);
536
+ } else if (state.em === ch) { // Remove EM
537
+ if (modeCfg.highlightFormatting) state.formatting = "em";
538
+ var t = getType(state);
539
+ state.em = false;
540
+ return t;
541
+ } else if (!state.em) { // Add EM
542
+ state.em = ch;
543
+ if (modeCfg.highlightFormatting) state.formatting = "em";
544
+ return getType(state);
545
+ }
546
+ } else if (ch === ' ') {
547
+ if (stream.eat('*') || stream.eat('_')) { // Probably surrounded by spaces
548
+ if (stream.peek() === ' ') { // Surrounded by spaces, ignore
549
+ return getType(state);
550
+ } else { // Not surrounded by spaces, back up pointer
551
+ stream.backUp(1);
552
+ }
553
+ }
554
+ }
555
+
556
+ if (modeCfg.strikethrough) {
557
+ if (ch === '~' && stream.eatWhile(ch)) {
558
+ if (state.strikethrough) {// Remove strikethrough
559
+ if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
560
+ var t = getType(state);
561
+ state.strikethrough = false;
562
+ return t;
563
+ } else if (stream.match(/^[^\s]/, false)) {// Add strikethrough
564
+ state.strikethrough = true;
565
+ if (modeCfg.highlightFormatting) state.formatting = "strikethrough";
566
+ return getType(state);
567
+ }
568
+ } else if (ch === ' ') {
569
+ if (stream.match(/^~~/, true)) { // Probably surrounded by space
570
+ if (stream.peek() === ' ') { // Surrounded by spaces, ignore
571
+ return getType(state);
572
+ } else { // Not surrounded by spaces, back up pointer
573
+ stream.backUp(2);
574
+ }
575
+ }
576
+ }
577
+ }
578
+
579
+ if (ch === ' ') {
580
+ if (stream.match(/ +$/, false)) {
581
+ state.trailingSpace++;
582
+ } else if (state.trailingSpace) {
583
+ state.trailingSpaceNewLine = true;
584
+ }
585
+ }
586
+
587
+ return getType(state);
588
+ }
589
+
590
+ function linkInline(stream, state) {
591
+ var ch = stream.next();
592
+
593
+ if (ch === ">") {
594
+ state.f = state.inline = inlineNormal;
595
+ if (modeCfg.highlightFormatting) state.formatting = "link";
596
+ var type = getType(state);
597
+ if (type){
598
+ type += " ";
599
+ } else {
600
+ type = "";
601
+ }
602
+ return type + tokenTypes.linkInline;
603
+ }
604
+
605
+ stream.match(/^[^>]+/, true);
606
+
607
+ return tokenTypes.linkInline;
608
+ }
609
+
610
+ function linkHref(stream, state) {
611
+ // Check if space, and return NULL if so (to avoid marking the space)
612
+ if(stream.eatSpace()){
613
+ return null;
614
+ }
615
+ var ch = stream.next();
616
+ if (ch === '(' || ch === '[') {
617
+ state.f = state.inline = getLinkHrefInside(ch === "(" ? ")" : "]", 0);
618
+ if (modeCfg.highlightFormatting) state.formatting = "link-string";
619
+ state.linkHref = true;
620
+ return getType(state);
621
+ }
622
+ return 'error';
623
+ }
624
+
625
+ var linkRE = {
626
+ ")": /^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,
627
+ "]": /^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/
628
+ }
629
+
630
+ function getLinkHrefInside(endChar) {
631
+ return function(stream, state) {
632
+ var ch = stream.next();
633
+
634
+ if (ch === endChar) {
635
+ state.f = state.inline = inlineNormal;
636
+ if (modeCfg.highlightFormatting) state.formatting = "link-string";
637
+ var returnState = getType(state);
638
+ state.linkHref = false;
639
+ return returnState;
640
+ }
641
+
642
+ stream.match(linkRE[endChar])
643
+ state.linkHref = true;
644
+ return getType(state);
645
+ };
646
+ }
647
+
648
+ function footnoteLink(stream, state) {
649
+ if (stream.match(/^([^\]\\]|\\.)*\]:/, false)) {
650
+ state.f = footnoteLinkInside;
651
+ stream.next(); // Consume [
652
+ if (modeCfg.highlightFormatting) state.formatting = "link";
653
+ state.linkText = true;
654
+ return getType(state);
655
+ }
656
+ return switchInline(stream, state, inlineNormal);
657
+ }
658
+
659
+ function footnoteLinkInside(stream, state) {
660
+ if (stream.match(/^\]:/, true)) {
661
+ state.f = state.inline = footnoteUrl;
662
+ if (modeCfg.highlightFormatting) state.formatting = "link";
663
+ var returnType = getType(state);
664
+ state.linkText = false;
665
+ return returnType;
666
+ }
667
+
668
+ stream.match(/^([^\]\\]|\\.)+/, true);
669
+
670
+ return tokenTypes.linkText;
671
+ }
672
+
673
+ function footnoteUrl(stream, state) {
674
+ // Check if space, and return NULL if so (to avoid marking the space)
675
+ if(stream.eatSpace()){
676
+ return null;
677
+ }
678
+ // Match URL
679
+ stream.match(/^[^\s]+/, true);
680
+ // Check for link title
681
+ if (stream.peek() === undefined) { // End of line, set flag to check next line
682
+ state.linkTitle = true;
683
+ } else { // More content on line, check if link title
684
+ stream.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/, true);
685
+ }
686
+ state.f = state.inline = inlineNormal;
687
+ return tokenTypes.linkHref + " url";
688
+ }
689
+
690
+ var mode = {
691
+ startState: function() {
692
+ return {
693
+ f: blockNormal,
694
+
695
+ prevLine: null,
696
+ thisLine: null,
697
+
698
+ block: blockNormal,
699
+ htmlState: null,
700
+ indentation: 0,
701
+
702
+ inline: inlineNormal,
703
+ text: handleText,
704
+
705
+ formatting: false,
706
+ linkText: false,
707
+ linkHref: false,
708
+ linkTitle: false,
709
+ code: 0,
710
+ em: false,
711
+ strong: false,
712
+ header: 0,
713
+ hr: false,
714
+ taskList: false,
715
+ list: false,
716
+ listStack: [],
717
+ quote: 0,
718
+ trailingSpace: 0,
719
+ trailingSpaceNewLine: false,
720
+ strikethrough: false,
721
+ fencedChars: null
722
+ };
723
+ },
724
+
725
+ copyState: function(s) {
726
+ return {
727
+ f: s.f,
728
+
729
+ prevLine: s.prevLine,
730
+ thisLine: s.thisLine,
731
+
732
+ block: s.block,
733
+ htmlState: s.htmlState && CodeMirror.copyState(htmlMode, s.htmlState),
734
+ indentation: s.indentation,
735
+
736
+ localMode: s.localMode,
737
+ localState: s.localMode ? CodeMirror.copyState(s.localMode, s.localState) : null,
738
+
739
+ inline: s.inline,
740
+ text: s.text,
741
+ formatting: false,
742
+ linkTitle: s.linkTitle,
743
+ code: s.code,
744
+ em: s.em,
745
+ strong: s.strong,
746
+ strikethrough: s.strikethrough,
747
+ header: s.header,
748
+ hr: s.hr,
749
+ taskList: s.taskList,
750
+ list: s.list,
751
+ listStack: s.listStack.slice(0),
752
+ quote: s.quote,
753
+ indentedCode: s.indentedCode,
754
+ trailingSpace: s.trailingSpace,
755
+ trailingSpaceNewLine: s.trailingSpaceNewLine,
756
+ md_inside: s.md_inside,
757
+ fencedChars: s.fencedChars
758
+ };
759
+ },
760
+
761
+ token: function(stream, state) {
762
+
763
+ // Reset state.formatting
764
+ state.formatting = false;
765
+
766
+ if (stream != state.thisLine) {
767
+ var forceBlankLine = state.header || state.hr;
768
+
769
+ // Reset state.header and state.hr
770
+ state.header = 0;
771
+ state.hr = false;
772
+
773
+ if (stream.match(/^\s*$/, true) || forceBlankLine) {
774
+ blankLine(state);
775
+ if (!forceBlankLine) return null
776
+ state.prevLine = null
777
+ }
778
+
779
+ state.prevLine = state.thisLine
780
+ state.thisLine = stream
781
+
782
+ // Reset state.taskList
783
+ state.taskList = false;
784
+
785
+ // Reset state.trailingSpace
786
+ state.trailingSpace = 0;
787
+ state.trailingSpaceNewLine = false;
788
+
789
+ state.f = state.block;
790
+ var indentation = stream.match(/^\s*/, true)[0].replace(/\t/g, ' ').length;
791
+ state.indentationDiff = Math.min(indentation - state.indentation, 4);
792
+ state.indentation = state.indentation + state.indentationDiff;
793
+ if (indentation > 0) return null;
794
+ }
795
+ return state.f(stream, state);
796
+ },
797
+
798
+ innerMode: function(state) {
799
+ if (state.block == htmlBlock) return {state: state.htmlState, mode: htmlMode};
800
+ if (state.localState) return {state: state.localState, mode: state.localMode};
801
+ return {state: state, mode: mode};
802
+ },
803
+
804
+ blankLine: blankLine,
805
+
806
+ getType: getType,
807
+
808
+ closeBrackets: "()[]{}''\"\"``",
809
+ fold: "markdown"
810
+ };
811
+ return mode;
812
+ }, "xml");
813
+
814
+ CodeMirror.defineMIME("text/x-markdown", "markdown");
815
+
816
+ });