@@ -28,6 +28,50 @@ func TestInitialPositionPunctAnchor(t *testing.T) {
2828 }
2929}
3030
31+ // A match butted directly against a code span's delimiter is inside (or
32+ // beside) that span, and locating an alert there mislocates it -- the prose
33+ // occurrence the rule actually matched sits later in the line. fs[1] is
34+ // exclusive, so the character to inspect is ctx[fs[1]] itself. See #1132's
35+ // follow-up: `Inline `+"`sum(x) # ZQX`"+` and text ZQX after.`
36+ func TestInsideInlineMarkup (t * testing.T ) {
37+ cases := []struct {
38+ name string
39+ ctx string
40+ fs []int
41+ want bool
42+ }{
43+ {"plain prose" , "some ZQX here" , []int {5 , 8 }, false },
44+ {"opening backtick beside match" , "x `ZQX` y" , []int {3 , 6 }, true },
45+ {"closing backtick against match" , "x `f() # ZQX` and ZQX y" ,
46+ []int {9 , 12 }, true },
47+ {"prose occurrence after a span" , "x `f() # ZQX` and ZQX y" ,
48+ []int {18 , 21 }, false },
49+ {"hyphenated compound is not markup" , "a well-known fix" ,
50+ []int {2 , 6 }, false },
51+ }
52+
53+ for _ , c := range cases {
54+ t .Run (c .name , func (t * testing.T ) {
55+ if got := insideInlineMarkup (c .ctx , c .fs ); got != c .want {
56+ t .Errorf ("insideInlineMarkup(%q, %v) = %v, want %v" ,
57+ c .ctx , c .fs , got , c .want )
58+ }
59+ })
60+ }
61+ }
62+
63+ // A match shadowed by an identical string inside a code span must be located
64+ // at its prose occurrence, not the span's.
65+ func TestInitialPositionSkipsCodeSpan (t * testing.T ) {
66+ ctx := "Inline `sum(x) # ZQX` and text ZQX after."
67+ txt := "Inline ************ and text ZQX after."
68+
69+ pos , _ := initialPosition (ctx , txt , Alert {Match : "ZQX" }, - 1 )
70+ if pos != 32 {
71+ t .Errorf ("pos = %d, want 32 (the prose occurrence)" , pos )
72+ }
73+ }
74+
3175func TestIsPunctOnly (t * testing.T ) {
3276 cases := map [string ]bool {
3377 "," : true ,
0 commit comments