@@ -560,6 +560,14 @@ describe('link', () => {
560560 const expected = 'https://errors.pydantic.dev/2.13/v/value_error'
561561 expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
562562 } )
563+
564+ it ( 'should close inline code inside unclosed link text' , ( ) => {
565+ // Backtick must close before the bracket, else `]` lands inside the
566+ // unclosed code span and renders as literal "`foo]" not a code link.
567+ const input = '[`foo'
568+ const expected = '[`foo`]'
569+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
570+ } )
563571} )
564572describe ( 'attributes scope' , ( ) => {
565573 it ( 'should ignore $ in inline attributes' , ( ) => {
@@ -610,3 +618,91 @@ describe('attributes scope', () => {
610618 expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
611619 } )
612620} )
621+
622+ describe ( 'inline code spans as literal regions' , ( ) => {
623+ it ( 'should not count asterisks inside a closed code span' , ( ) => {
624+ const input = 'text `a*b` and **bold'
625+ const expected = 'text `a*b` and **bold**'
626+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
627+ } )
628+
629+ it ( 'should not count underscores inside a closed code span' , ( ) => {
630+ const input = 'see `a_b_c` then __bold'
631+ const expected = 'see `a_b_c` then __bold__'
632+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
633+ } )
634+
635+ it ( 'should close an open code span without leaking an asterisk' , ( ) => {
636+ const input = '`x * y'
637+ const expected = '`x * y`'
638+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
639+ } )
640+
641+ it ( 'should close only the code span when bold wraps an open code span' , ( ) => {
642+ const input = '**bold `code'
643+ const expected = '**bold `code`'
644+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
645+ } )
646+
647+ it ( 'should treat an underscore inside an open code span as literal' , ( ) => {
648+ const input = '`snake_case'
649+ const expected = '`snake_case`'
650+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
651+ } )
652+ } )
653+
654+ describe ( 'inline math as literal regions' , ( ) => {
655+ it ( 'should not count asterisks inside closed inline math' , ( ) => {
656+ const input = '$a * b$ and *italic'
657+ const expected = '$a * b$ and *italic*'
658+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
659+ } )
660+
661+ it ( 'should not count an underscore inside an open math region' , ( ) => {
662+ const input = 'value $x_0'
663+ const expected = 'value $x_0$'
664+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
665+ } )
666+
667+ it ( 'should close inline math without leaking an asterisk' , ( ) => {
668+ const input = '$a * b'
669+ const expected = '$a * b$'
670+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
671+ } )
672+ } )
673+
674+ describe ( 'escaped markers' , ( ) => {
675+ it ( 'should not count an escaped asterisk as a delimiter' , ( ) => {
676+ const input = 'a \\* b *it'
677+ const expected = 'a \\* b *it*'
678+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
679+ } )
680+
681+ it ( 'should not count an escaped underscore as a delimiter' , ( ) => {
682+ const input = 'a \\_ b _it'
683+ const expected = 'a \\_ b _it_'
684+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
685+ } )
686+
687+ it ( 'should not count an escaped backtick as a code span' , ( ) => {
688+ const input = 'literal \\` then `code'
689+ const expected = 'literal \\` then `code`'
690+ expect ( autoCloseMarkdown ( input ) ) . toBe ( expected )
691+ } )
692+
693+ it ( 'should leave a fully escaped marker untouched' , ( ) => {
694+ const input = 'just a \\* star'
695+ expect ( autoCloseMarkdown ( input ) ) . toBe ( input )
696+ } )
697+ } )
698+
699+ describe ( 'nested emphasis (known limitations)' , ( ) => {
700+ // Mixed-marker nesting needs CommonMark flanking resolution, out of scope here
701+ it . todo ( 'should close nested bold + underscore-italic (**_text -> **_text_**)' , ( ) => {
702+ expect ( autoCloseMarkdown ( '**_text' ) ) . toBe ( '**_text_**' )
703+ } )
704+
705+ it . todo ( 'should close nested italic + bold (*a **b -> *a **b***)' , ( ) => {
706+ expect ( autoCloseMarkdown ( '*a **b' ) ) . toBe ( '*a **b***' )
707+ } )
708+ } )
0 commit comments