@@ -18,6 +18,31 @@ const hasCompleteCodeBlock = (text: string): boolean => {
1818 return tripleBackticks > 0 && tripleBackticks % 2 === 0 && text . includes ( "\n" ) ;
1919} ;
2020
21+ // Returns the start index of the currently open fenced code block, or -1 if none
22+ const getOpenCodeFenceIndex = ( text : string ) : number => {
23+ let openFenceIndex = - 1 ;
24+ let inFence = false ;
25+
26+ for ( const match of text . matchAll ( / ` ` ` / g) ) {
27+ const index = match . index ?? - 1 ;
28+ if ( index === - 1 ) {
29+ continue ;
30+ }
31+
32+ if ( inFence ) {
33+ // This fence closes the current block
34+ inFence = false ;
35+ openFenceIndex = - 1 ;
36+ } else {
37+ // This fence opens a new block
38+ inFence = true ;
39+ openFenceIndex = index ;
40+ }
41+ }
42+
43+ return openFenceIndex ;
44+ } ;
45+
2146// Handles incomplete links and images by preserving them with a special marker
2247const handleIncompleteLinksAndImages = ( text : string ) : string => {
2348 // First check for incomplete URLs: [text](partial-url or 
@@ -84,6 +109,12 @@ const handleIncompleteBold = (text: string): string => {
84109 // Check if the bold marker is in a list item context
85110 // Find the position of the matched bold marker
86111 const markerIndex = text . lastIndexOf ( boldMatch [ 1 ] ) ;
112+
113+ // Don't process if the marker is inside an incomplete code block
114+ const openFenceIndex = getOpenCodeFenceIndex ( text ) ;
115+ if ( openFenceIndex !== - 1 && markerIndex > openFenceIndex ) {
116+ return text ;
117+ }
87118 const beforeMarker = text . substring ( 0 , markerIndex ) ;
88119 const lastNewlineBeforeMarker = beforeMarker . lastIndexOf ( "\n" ) ;
89120 const lineStart = lastNewlineBeforeMarker === - 1 ? 0 : lastNewlineBeforeMarker + 1 ;
@@ -111,6 +142,11 @@ const handleIncompleteBold = (text: string): string => {
111142
112143// Completes incomplete italic formatting with double underscores (__)
113144const handleIncompleteDoubleUnderscoreItalic = ( text : string ) : string => {
145+ // Don't process if inside a complete code block
146+ if ( hasCompleteCodeBlock ( text ) ) {
147+ return text ;
148+ }
149+
114150 const italicMatch = text . match ( italicPattern ) ;
115151
116152 if ( italicMatch ) {
@@ -125,6 +161,12 @@ const handleIncompleteDoubleUnderscoreItalic = (text: string): string => {
125161 // Check if the underscore marker is in a list item context
126162 // Find the position of the matched underscore marker
127163 const markerIndex = text . lastIndexOf ( italicMatch [ 1 ] ) ;
164+
165+ // Don't process if the marker is inside an incomplete code block
166+ const openFenceIndex = getOpenCodeFenceIndex ( text ) ;
167+ if ( openFenceIndex !== - 1 && markerIndex > openFenceIndex ) {
168+ return text ;
169+ }
128170 const beforeMarker = text . substring ( 0 , markerIndex ) ;
129171 const lastNewlineBeforeMarker = beforeMarker . lastIndexOf ( "\n" ) ;
130172 const lineStart = lastNewlineBeforeMarker === - 1 ? 0 : lastNewlineBeforeMarker + 1 ;
@@ -210,6 +252,12 @@ const handleIncompleteSingleAsteriskItalic = (text: string): string => {
210252 return text ;
211253 }
212254
255+ // Don't process if the marker is inside an incomplete code block
256+ const openFenceIndex = getOpenCodeFenceIndex ( text ) ;
257+ if ( openFenceIndex !== - 1 && firstSingleAsteriskIndex > openFenceIndex ) {
258+ return text ;
259+ }
260+
213261 // Get content after the first single asterisk
214262 const contentAfterFirstAsterisk = text . substring ( firstSingleAsteriskIndex + 1 ) ;
215263
@@ -329,6 +377,12 @@ const handleIncompleteSingleUnderscoreItalic = (text: string): string => {
329377 return text ;
330378 }
331379
380+ // Don't process if the marker is inside an incomplete code block
381+ const openFenceIndex = getOpenCodeFenceIndex ( text ) ;
382+ if ( openFenceIndex !== - 1 && firstSingleUnderscoreIndex > openFenceIndex ) {
383+ return text ;
384+ }
385+
332386 // Get content after the first single underscore
333387 const contentAfterFirstUnderscore = text . substring ( firstSingleUnderscoreIndex + 1 ) ;
334388
@@ -535,6 +589,15 @@ const handleIncompleteBoldItalic = (text: string): string => {
535589 return text ;
536590 }
537591
592+ // Find the position of the matched bold-italic marker
593+ const markerIndex = text . lastIndexOf ( boldItalicMatch [ 1 ] ) ;
594+
595+ // Don't process if the marker is inside an incomplete code block
596+ const openFenceIndex = getOpenCodeFenceIndex ( text ) ;
597+ if ( openFenceIndex !== - 1 && markerIndex > openFenceIndex ) {
598+ return text ;
599+ }
600+
538601 const tripleAsteriskCount = countTripleAsterisks ( text ) ;
539602 if ( tripleAsteriskCount % 2 === 1 ) {
540603 return `${ text } ***` ;
0 commit comments