77 regexFrontMatter = / ^ - - - \r ? \n ( [ \s \S ] * ?) \r ? \n - - - \r ? \n / ,
88 regexLabClose = / < ! - - \s * \/ l a b \s * - - > / g,
99 regexLabOpen = / < ! - - \s * l a b \s * - - > / g,
10- regexLivePreview = / ` ` ` ( j a v a s c r i p t | h t m l | c s s | j s o n ) \s + l i v e - p r e v i e w \s * \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
11- regexMermaid = / ` ` ` m e r m a i d \s * \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
12- regexNeoComponent = / ` ` ` j s o n \s + n e o - c o m p o n e n t \s * \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
10+ regexLivePreview = / (?< ! \\ ) ` ` ` ( j a v a s c r i p t | h t m l | c s s | j s o n ) \s + l i v e - p r e v i e w \s * \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
11+ regexMermaid = / (?< ! \\ ) ` ` ` m e r m a i d \s * \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
12+ regexNeoComponent = / (?< ! \\ ) ` ` ` j s o n \s + n e o - c o m p o n e n t \s * \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
1313 regexNewLines = / ^ \n + | \n + $ / g,
14- regexCodeBlock = / ` ` ` ( \w * ) (?: [ ^ \n ] * ) ? \n ( [ \s \S ] * ?) \n \s * ` ` ` / g,
14+ regexCodeBlock = / (?< ! \\ ) ( ` { 3 , } ) ( \w * ) (?: [ ^ \n ] * ) ? \n ( [ \s \S ] * ?) \n \s * \1 / g,
1515 regexInlineCode = / ` ( [ ^ ` ] + ) ` / g,
1616 regexTicketId = / ( ^ | [ \s ( ] ) # ( \d + ) \b / g;
1717
@@ -439,9 +439,14 @@ class Markdown extends Component {
439439 */
440440 processNeoComponentsBlocks ( contentString , map ) {
441441 return contentString . replace ( regexNeoComponent , ( match , code ) => {
442- const key = IdGenerator . getId ( 'learn-content-component' ) ;
443- map [ key ] = JSON . parse ( code ) ;
444- return `<div id="${ key } "></div>`
442+ try {
443+ const key = IdGenerator . getId ( 'learn-content-component' ) ;
444+ map [ key ] = JSON . parse ( code ) ;
445+ return `<div id="${ key } "></div>`
446+ } catch ( e ) {
447+ console . warn ( 'Failed to parse neo-component block, returning original code.' , e ) ;
448+ return match ;
449+ }
445450 } )
446451 }
447452
@@ -455,10 +460,13 @@ class Markdown extends Component {
455460 count = 0 ,
456461 replacements ;
457462
458- let updatedContent = contentString . replace ( regexCodeBlock , ( match , language , code ) => {
463+ let updatedContent = contentString . replace ( regexCodeBlock , ( match , backticks , language , code ) => {
459464 const token = `__NEO-READONLY-TOKEN-${ ++ count } __` ;
460465 const lang = ( ! language || language . trim ( ) === '' || language === 'text' ) ? 'plaintext' : language ;
461466
467+ // Remove the backslash escape from special blocks so they display correctly
468+ code = code . replace ( / \\ ` ` ` / g, '```' ) ;
469+
462470 replacementPromises . push (
463471 HighlightJs . highlight ( code , lang , windowId )
464472 . catch ( err => {
@@ -539,6 +547,10 @@ class Markdown extends Component {
539547
540548 // Parse the (now modified) markdown content into HTML
541549 // This content string now contains standard markdown PLUS the HTML divs/pres we injected.
550+
551+ // Remove the backslash escape from special blocks so marked.js treats them as normal markdown blocks
552+ content = content . replace ( / \\ ` ` ` / g, '```' ) ;
553+
542554 html = marked . parse ( content ) ;
543555
544556 // Wrap raw HTML img tags in a scrollable container
0 commit comments