@@ -46,6 +46,14 @@ const handleIncompleteBold = (text: string): string => {
4646 const boldMatch = text . match ( boldPattern ) ;
4747
4848 if ( boldMatch ) {
49+ // Don't close if there's no meaningful content after the opening markers
50+ // boldMatch[2] contains the content after **
51+ // Check if content is only whitespace or other emphasis markers
52+ const contentAfterMarker = boldMatch [ 2 ] ;
53+ if ( ! contentAfterMarker || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterMarker ) ) {
54+ return text ;
55+ }
56+
4957 const asteriskPairs = ( text . match ( / \* \* / g) || [ ] ) . length ;
5058 if ( asteriskPairs % 2 === 1 ) {
5159 return `${ text } **` ;
@@ -60,6 +68,14 @@ const handleIncompleteDoubleUnderscoreItalic = (text: string): string => {
6068 const italicMatch = text . match ( italicPattern ) ;
6169
6270 if ( italicMatch ) {
71+ // Don't close if there's no meaningful content after the opening markers
72+ // italicMatch[2] contains the content after __
73+ // Check if content is only whitespace or other emphasis markers
74+ const contentAfterMarker = italicMatch [ 2 ] ;
75+ if ( ! contentAfterMarker || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterMarker ) ) {
76+ return text ;
77+ }
78+
6379 const underscorePairs = ( text . match ( / _ _ / g) || [ ] ) . length ;
6480 if ( underscorePairs % 2 === 1 ) {
6581 return `${ text } __` ;
@@ -119,6 +135,28 @@ const handleIncompleteSingleAsteriskItalic = (text: string): string => {
119135 const singleAsteriskMatch = text . match ( singleAsteriskPattern ) ;
120136
121137 if ( singleAsteriskMatch ) {
138+ // Find the first single asterisk position (not part of **)
139+ let firstSingleAsteriskIndex = - 1 ;
140+ for ( let i = 0 ; i < text . length ; i ++ ) {
141+ if ( text [ i ] === '*' && text [ i - 1 ] !== '*' && text [ i + 1 ] !== '*' ) {
142+ firstSingleAsteriskIndex = i ;
143+ break ;
144+ }
145+ }
146+
147+ if ( firstSingleAsteriskIndex === - 1 ) {
148+ return text ;
149+ }
150+
151+ // Get content after the first single asterisk
152+ const contentAfterFirstAsterisk = text . substring ( firstSingleAsteriskIndex + 1 ) ;
153+
154+ // Check if there's meaningful content after the asterisk
155+ // Don't close if content is only whitespace or emphasis markers
156+ if ( ! contentAfterFirstAsterisk || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterFirstAsterisk ) ) {
157+ return text ;
158+ }
159+
122160 const singleAsterisks = countSingleAsterisks ( text ) ;
123161 if ( singleAsterisks % 2 === 1 ) {
124162 return `${ text } *` ;
@@ -189,6 +227,28 @@ const handleIncompleteSingleUnderscoreItalic = (text: string): string => {
189227 const singleUnderscoreMatch = text . match ( singleUnderscorePattern ) ;
190228
191229 if ( singleUnderscoreMatch ) {
230+ // Find the first single underscore position (not part of __)
231+ let firstSingleUnderscoreIndex = - 1 ;
232+ for ( let i = 0 ; i < text . length ; i ++ ) {
233+ if ( text [ i ] === '_' && text [ i - 1 ] !== '_' && text [ i + 1 ] !== '_' && ! isWithinMathBlock ( text , i ) ) {
234+ firstSingleUnderscoreIndex = i ;
235+ break ;
236+ }
237+ }
238+
239+ if ( firstSingleUnderscoreIndex === - 1 ) {
240+ return text ;
241+ }
242+
243+ // Get content after the first single underscore
244+ const contentAfterFirstUnderscore = text . substring ( firstSingleUnderscoreIndex + 1 ) ;
245+
246+ // Check if there's meaningful content after the underscore
247+ // Don't close if content is only whitespace or emphasis markers
248+ if ( ! contentAfterFirstUnderscore || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterFirstUnderscore ) ) {
249+ return text ;
250+ }
251+
192252 const singleUnderscores = countSingleUnderscores ( text ) ;
193253 if ( singleUnderscores % 2 === 1 ) {
194254 return `${ text } _` ;
@@ -260,6 +320,14 @@ const handleIncompleteInlineCode = (text: string): string => {
260320 const inlineCodeMatch = text . match ( inlineCodePattern ) ;
261321
262322 if ( inlineCodeMatch && ! insideIncompleteCodeBlock ) {
323+ // Don't close if there's no meaningful content after the opening marker
324+ // inlineCodeMatch[2] contains the content after `
325+ // Check if content is only whitespace or other emphasis markers
326+ const contentAfterMarker = inlineCodeMatch [ 2 ] ;
327+ if ( ! contentAfterMarker || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterMarker ) ) {
328+ return text ;
329+ }
330+
263331 const singleBacktickCount = countSingleBackticks ( text ) ;
264332 if ( singleBacktickCount % 2 === 1 ) {
265333 return `${ text } \`` ;
@@ -274,6 +342,14 @@ const handleIncompleteStrikethrough = (text: string): string => {
274342 const strikethroughMatch = text . match ( strikethroughPattern ) ;
275343
276344 if ( strikethroughMatch ) {
345+ // Don't close if there's no meaningful content after the opening markers
346+ // strikethroughMatch[2] contains the content after ~~
347+ // Check if content is only whitespace or other emphasis markers
348+ const contentAfterMarker = strikethroughMatch [ 2 ] ;
349+ if ( ! contentAfterMarker || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterMarker ) ) {
350+ return text ;
351+ }
352+
277353 const tildePairs = ( text . match ( / ~ ~ / g) || [ ] ) . length ;
278354 if ( tildePairs % 2 === 1 ) {
279355 return `${ text } ~~` ;
@@ -359,6 +435,14 @@ const handleIncompleteBoldItalic = (text: string): string => {
359435 const boldItalicMatch = text . match ( boldItalicPattern ) ;
360436
361437 if ( boldItalicMatch ) {
438+ // Don't close if there's no meaningful content after the opening markers
439+ // boldItalicMatch[2] contains the content after ***
440+ // Check if content is only whitespace or other emphasis markers
441+ const contentAfterMarker = boldItalicMatch [ 2 ] ;
442+ if ( ! contentAfterMarker || / ^ [ \s _ ~ * ` ] * $ / . test ( contentAfterMarker ) ) {
443+ return text ;
444+ }
445+
362446 const tripleAsteriskCount = countTripleAsterisks ( text ) ;
363447 if ( tripleAsteriskCount % 2 === 1 ) {
364448 return `${ text } ***` ;
0 commit comments