@@ -35,10 +35,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
35
35
if ( modeCfg . maxBlockquoteDepth === undefined )
36
36
modeCfg . maxBlockquoteDepth = 0 ;
37
37
38
- // Should underscores in words open/close em/strong?
39
- if ( modeCfg . underscoresBreakWords === undefined )
40
- modeCfg . underscoresBreakWords = true ;
41
-
42
38
// Use `fencedCodeBlocks` to configure fenced code blocks. false to
43
39
// disable, string to specify a precise regexp that the fence should
44
40
// match, and true to allow three or more backticks or tildes (as
@@ -91,6 +87,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
91
87
, textRE = / ^ [ ^ # ! \[ \] * _ \\ < > \$ ` " ' ( ~ ] + /
92
88
, fencedCodeRE = new RegExp ( "^(" + ( modeCfg . fencedCodeBlocks === true ? "~~~+|```+" : modeCfg . fencedCodeBlocks ) +
93
89
")[ \\t]*([\\w+#\-]*)" )
90
+ , punctuation = / [ ! \" # $ % & \' ( ) * + , \- \. \/ : ; < = > ? @ \[ \\ \] ^ _ ` { | } ~ — ] /
94
91
, fencedMathRE = new RegExp ( "^(\$\$)[ \\t]*([\\w+#\-]*)" ) ;
95
92
96
93
function switchInline ( stream , state , f ) {
@@ -136,7 +133,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
136
133
}
137
134
138
135
function blockNormal ( stream , state ) {
139
-
140
136
var sol = stream . sol ( ) ;
141
137
142
138
var prevLineIsList = state . list !== false ,
@@ -158,15 +154,11 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
158
154
}
159
155
160
156
var match = null ;
161
- if ( state . indentationDiff >= 4 ) {
157
+ if ( state . indentationDiff >= 4 && ( prevLineIsIndentedCode || lineIsEmpty ( state . prevLine ) ) ) {
162
158
stream . skipToEnd ( ) ;
163
- if ( prevLineIsIndentedCode || lineIsEmpty ( state . prevLine ) ) {
164
- state . indentation -= 4 ;
165
- state . indentedCode = true ;
166
- return tokenTypes . code ;
167
- } else {
168
- return null ;
169
- }
159
+ state . indentation -= 4 ;
160
+ state . indentedCode = true ;
161
+ return tokenTypes . code ;
170
162
} else if ( stream . eatSpace ( ) ) {
171
163
return null ;
172
164
} else if ( ( match = stream . match ( atxHeaderRE ) ) && match [ 1 ] . length <= 6 ) {
@@ -390,9 +382,6 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
390
382
return getType ( state ) ;
391
383
}
392
384
393
- // Get sol() value now, before character is consumed
394
- var sol = stream . sol ( ) ;
395
-
396
385
var ch = stream . next ( ) ;
397
386
398
387
// Matches link titles present on next line
@@ -402,7 +391,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
402
391
if ( ch === '(' ) {
403
392
matchCh = ')' ;
404
393
}
405
- matchCh = ( matchCh + '' ) . replace ( / ( [ . ? * + ^ $ [ \] \\ ( ) { } | - ] ) / g, "\\$1" ) ;
394
+ matchCh = ( matchCh + '' ) . replace ( / ( [ . ? * + ^ \ [\] \\ ( ) { } | - ] ) / g, "\\$1" ) ;
406
395
var regex = '^\\s*(?:[^' + matchCh + '\\\\]+|\\\\\\\\|\\\\.)' + matchCh ;
407
396
if ( stream . match ( new RegExp ( regex ) , true ) ) {
408
397
return tokenTypes . linkHref ;
@@ -483,13 +472,13 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
483
472
return type ;
484
473
}
485
474
486
- if ( ch === '[' && stream . match ( / [ ^ \] ] * \] ( \( . * \) | ? \[ . * ? \] ) / , false ) && ! state . image ) {
475
+ if ( ch === '[' && ! state . image ) {
487
476
state . linkText = true ;
488
477
if ( modeCfg . highlightFormatting ) state . formatting = "link" ;
489
478
return getType ( state ) ;
490
479
}
491
480
492
- if ( ch === ']' && state . linkText && stream . match ( / \( . * ? \) | ? \[ . * ? \] / , false ) ) {
481
+ if ( ch === ']' && state . linkText ) {
493
482
if ( modeCfg . highlightFormatting ) state . formatting = "link" ;
494
483
var type = getType ( state ) ;
495
484
state . linkText = false ;
@@ -535,41 +524,34 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
535
524
if ( ch === '<' && stream . match ( / ^ \/ \w * ?> / ) ) {
536
525
state . md_inside = false ;
537
526
return "tag" ;
538
- }
539
-
540
- var ignoreUnderscore = false ;
541
- if ( ! modeCfg . underscoresBreakWords ) {
542
- if ( ch === '_' && stream . peek ( ) !== '_' && stream . match ( / ( \w ) / , false ) ) {
543
- var prevPos = stream . pos - 2 ;
544
- if ( prevPos >= 0 ) {
545
- var prevCh = stream . string . charAt ( prevPos ) ;
546
- if ( prevCh !== '_' && prevCh . match ( / ( \w ) / , false ) ) {
547
- ignoreUnderscore = true ;
548
- }
549
- }
527
+ } else if ( ch === "*" || ch === "_" ) {
528
+ var len = 1 , before = stream . pos == 1 ? " " : stream . string . charAt ( stream . pos - 2 )
529
+ while ( len < 3 && stream . eat ( ch ) ) len ++
530
+ var after = stream . peek ( ) || " "
531
+ // See http://spec.commonmark.org/0.27/#emphasis-and-strong-emphasis
532
+ var leftFlanking = ! / \s / . test ( after ) && ( ! punctuation . test ( after ) || / \s / . test ( before ) || punctuation . test ( before ) )
533
+ var rightFlanking = ! / \s / . test ( before ) && ( ! punctuation . test ( before ) || / \s / . test ( after ) || punctuation . test ( after ) )
534
+ var setEm = null , setStrong = null
535
+ if ( len % 2 ) { // Em
536
+ if ( ! state . em && leftFlanking && ( ch === "*" || ! rightFlanking || punctuation . test ( before ) ) )
537
+ setEm = true
538
+ else if ( state . em == ch && rightFlanking && ( ch === "*" || ! leftFlanking || punctuation . test ( after ) ) )
539
+ setEm = false
550
540
}
551
- }
552
- if ( ch === '*' || ( ch === '_' && ! ignoreUnderscore ) ) {
553
- if ( sol && stream . peek ( ) === ' ' ) {
554
- // Do nothing, surrounded by newline and space
555
- } else if ( state . strong === ch && stream . eat ( ch ) ) { // Remove STRONG
556
- if ( modeCfg . highlightFormatting ) state . formatting = "strong" ;
557
- var t = getType ( state ) ;
558
- state . strong = false ;
559
- return t ;
560
- } else if ( ! state . strong && stream . eat ( ch ) ) { // Add STRONG
561
- state . strong = ch ;
562
- if ( modeCfg . highlightFormatting ) state . formatting = "strong" ;
563
- return getType ( state ) ;
564
- } else if ( state . em === ch ) { // Remove EM
565
- if ( modeCfg . highlightFormatting ) state . formatting = "em" ;
566
- var t = getType ( state ) ;
567
- state . em = false ;
568
- return t ;
569
- } else if ( ! state . em ) { // Add EM
570
- state . em = ch ;
571
- if ( modeCfg . highlightFormatting ) state . formatting = "em" ;
572
- return getType ( state ) ;
541
+ if ( len > 1 ) { // Strong
542
+ if ( ! state . strong && leftFlanking && ( ch === "*" || ! rightFlanking || punctuation . test ( before ) ) )
543
+ setStrong = true
544
+ else if ( state . strong == ch && rightFlanking && ( ch === "*" || ! leftFlanking || punctuation . test ( after ) ) )
545
+ setStrong = false
546
+ }
547
+ if ( setStrong != null || setEm != null ) {
548
+ if ( modeCfg . highlightFormatting ) state . formatting = setEm == null ? "strong" : setStrong == null ? "em" : "strong em"
549
+ if ( setEm === true ) state . em = ch
550
+ if ( setStrong === true ) state . strong = ch
551
+ var t = getType ( state )
552
+ if ( setEm === false ) state . em = false
553
+ if ( setStrong === false ) state . strong = false
554
+ return t
573
555
}
574
556
} else if ( ch === ' ' ) {
575
557
if ( stream . eat ( '*' ) || stream . eat ( '_' ) ) { // Probably surrounded by spaces
@@ -642,7 +624,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
642
624
}
643
625
var ch = stream . next ( ) ;
644
626
if ( ch === '(' || ch === '[' ) {
645
- state . f = state . inline = getLinkHrefInside ( ch === "(" ? ")" : "]" , 0 ) ;
627
+ state . f = state . inline = getLinkHrefInside ( ch === "(" ? ")" : "]" ) ;
646
628
if ( modeCfg . highlightFormatting ) state . formatting = "link-string" ;
647
629
state . linkHref = true ;
648
630
return getType ( state ) ;
@@ -652,7 +634,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
652
634
653
635
var linkRE = {
654
636
")" : / ^ (?: [ ^ \\ \( \) ] | \\ .| \( (?: [ ^ \\ \( \) ] | \\ .) * \) ) * ?(? = \) ) / ,
655
- "]" : / ^ (?: [ ^ \\ \[ \] ] | \\ .| \[ (?: [ ^ \\ \[ \\ ] ] | \\ .) * \] ) * ?(? = \] ) /
637
+ "]" : / ^ (?: [ ^ \\ \[ \] ] | \\ .| \[ (?: [ ^ \\ \[ \] ] | \\ .) * \] ) * ?(? = \] ) /
656
638
}
657
639
658
640
function getLinkHrefInside ( endChar ) {
@@ -768,6 +750,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
768
750
inline : s . inline ,
769
751
text : s . text ,
770
752
formatting : false ,
753
+ linkText : s . linkText ,
771
754
linkTitle : s . linkTitle ,
772
755
code : s . code ,
773
756
math : s . math ,
0 commit comments