@@ -89,7 +89,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
89
89
, atxHeaderRE = modeCfg . allowAtxHeaderWithoutSpace ? / ^ ( # + ) / : / ^ ( # + ) (?: | $ ) /
90
90
, setextHeaderRE = / ^ * (?: \= { 1 , } | - { 1 , } ) \s * $ /
91
91
, textRE = / ^ [ ^ # ! \[ \] * _ \\ < > ` " ' ( ~ : ] + /
92
- , fencedCodeRE = / ^ ( ~ ~ ~ + | ` ` ` + ) [ \t ] * ( [ \w + # - ] * ) /
92
+ , fencedCodeRE = / ^ ( ~ ~ ~ + | ` ` ` + ) [ \t ] * ( [ \w + # - ] * ) [ ^ \n ` ] * $ /
93
93
, linkDefRE = / ^ \s * \[ [ ^ \] ] + ?\] : \s * \S + ( \s * \S * \s * ) ? $ / // naive link-definition
94
94
, punctuation = / [ ! \" # $ % & \' ( ) * + , \- \. \/ : ; < = > ? @ \[ \\ \] ^ _ ` { | } ~ — ] /
95
95
, expandedTab = " " // CommonMark specifies tab as 4 spaces
@@ -133,13 +133,13 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
133
133
state . trailingSpaceNewLine = false ;
134
134
// Mark this line as blank
135
135
state . prevLine = state . thisLine
136
- state . thisLine = null
136
+ state . thisLine = { stream : null }
137
137
return null ;
138
138
}
139
139
140
140
function blockNormal ( stream , state ) {
141
141
var firstTokenOnLine = stream . column ( ) === state . indentation ;
142
- var prevLineLineIsEmpty = lineIsEmpty ( state . prevLine ) ;
142
+ var prevLineLineIsEmpty = lineIsEmpty ( state . prevLine . stream ) ;
143
143
var prevLineIsIndentedCode = state . indentedCode ;
144
144
var prevLineIsHr = state . hr ;
145
145
var prevLineIsList = state . list !== false ;
@@ -176,7 +176,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
176
176
state . indentation <= maxNonCodeIndentation && stream . match ( hrRE ) ;
177
177
178
178
var match = null ;
179
- if ( state . indentationDiff >= 4 && ( prevLineIsIndentedCode || prevLineLineIsEmpty ) ) {
179
+ if ( state . indentationDiff >= 4 && ( prevLineIsIndentedCode || state . prevLine . fencedCodeEnd ||
180
+ state . prevLine . header || prevLineLineIsEmpty ) ) {
180
181
stream . skipToEnd ( ) ;
181
182
state . indentedCode = true ;
182
183
return tokenTypes . code ;
@@ -185,6 +186,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
185
186
} else if ( firstTokenOnLine && state . indentation <= maxNonCodeIndentation && ( match = stream . match ( atxHeaderRE ) ) && match [ 1 ] . length <= 6 ) {
186
187
state . quote = 0 ;
187
188
state . header = match [ 1 ] . length ;
189
+ state . thisLine . header = true ;
188
190
if ( modeCfg . highlightFormatting ) state . formatting = "header" ;
189
191
state . f = state . inline ;
190
192
return getType ( state ) ;
@@ -211,7 +213,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
211
213
return getType ( state ) ;
212
214
} else if ( firstTokenOnLine && state . indentation <= maxNonCodeIndentation && ( match = stream . match ( fencedCodeRE , true ) ) ) {
213
215
state . quote = 0 ;
214
- state . fencedChars = match [ 1 ]
216
+ state . fencedEndRE = new RegExp ( match [ 1 ] + "+ *$" ) ;
215
217
// try switching mode
216
218
state . localMode = modeCfg . fencedCodeBlockHighlighting && getMode ( match [ 2 ] ) ;
217
219
if ( state . localMode ) state . localState = CodeMirror . startState ( state . localMode ) ;
@@ -240,6 +242,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
240
242
stream . skipToEnd ( ) ;
241
243
if ( modeCfg . highlightFormatting ) state . formatting = "header" ;
242
244
}
245
+ state . thisLine . header = true ;
243
246
state . f = state . inline ;
244
247
return getType ( state ) ;
245
248
} else if ( isHr ) {
@@ -269,20 +272,21 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
269
272
}
270
273
271
274
function local ( stream , state ) {
272
- var hasExitedList = state . indentation < state . listStack [ state . listStack . length - 1 ] ;
273
- if ( state . fencedChars && ( hasExitedList || stream . match ( state . fencedChars ) ) ) {
275
+ var currListInd = state . listStack [ state . listStack . length - 1 ] || 0 ;
276
+ var hasExitedList = state . indentation < currListInd ;
277
+ var maxFencedEndInd = currListInd + 3 ;
278
+ if ( state . fencedEndRE && state . indentation <= maxFencedEndInd && ( hasExitedList || stream . match ( state . fencedEndRE ) ) ) {
274
279
if ( modeCfg . highlightFormatting ) state . formatting = "code-block" ;
275
280
var returnType ;
276
281
if ( ! hasExitedList ) returnType = getType ( state )
277
282
state . localMode = state . localState = null ;
278
283
state . block = blockNormal ;
279
284
state . f = inlineNormal ;
280
- state . fencedChars = null ;
285
+ state . fencedEndRE = null ;
281
286
state . code = 0
287
+ state . thisLine . fencedCodeEnd = true ;
282
288
if ( hasExitedList ) return switchBlock ( stream , state , state . block ) ;
283
289
return returnType ;
284
- } else if ( state . fencedChars && stream . skipTo ( state . fencedChars ) ) {
285
- return "comment"
286
290
} else if ( state . localMode ) {
287
291
return state . localMode . token ( stream , state . localState ) ;
288
292
} else {
@@ -716,8 +720,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
716
720
return {
717
721
f : blockNormal ,
718
722
719
- prevLine : null ,
720
- thisLine : null ,
723
+ prevLine : { stream : null } ,
724
+ thisLine : { stream : null } ,
721
725
722
726
block : blockNormal ,
723
727
htmlState : null ,
@@ -744,7 +748,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
744
748
trailingSpaceNewLine : false ,
745
749
strikethrough : false ,
746
750
emoji : false ,
747
- fencedChars : null
751
+ fencedEndRE : null
748
752
} ;
749
753
} ,
750
754
@@ -783,7 +787,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
783
787
trailingSpace : s . trailingSpace ,
784
788
trailingSpaceNewLine : s . trailingSpaceNewLine ,
785
789
md_inside : s . md_inside ,
786
- fencedChars : s . fencedChars
790
+ fencedEndRE : s . fencedEndRE
787
791
} ;
788
792
} ,
789
793
@@ -792,8 +796,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
792
796
// Reset state.formatting
793
797
state . formatting = false ;
794
798
795
- if ( stream != state . thisLine ) {
796
799
// Reset state.header
800
+ if ( stream != state . thisLine . stream ) {
797
801
state . header = 0 ;
798
802
799
803
if ( stream . match ( / ^ \s * $ / , true ) ) {
@@ -802,7 +806,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
802
806
}
803
807
804
808
state . prevLine = state . thisLine
805
- state . thisLine = stream
809
+ state . thisLine = { stream : stream }
806
810
807
811
// Reset state.taskList
808
812
state . taskList = false ;
0 commit comments