sn-collab-editor 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ });