@@ -12,31 +12,25 @@ import (
1212)
1313
1414type inlineParser struct {
15- start []byte
16- end []byte
15+ trigger []byte
16+ endBytesSingleDollar []byte
17+ endBytesDoubleDollar []byte
18+ endBytesBracket []byte
1719}
1820
1921var defaultInlineDollarParser = & inlineParser {
20- start : []byte {'$' },
21- end : []byte {'$' },
22- }
23-
24- var defaultDualDollarParser = & inlineParser {
25- start : []byte {'$' , '$' },
26- end : []byte {'$' , '$' },
22+ trigger : []byte {'$' },
23+ endBytesSingleDollar : []byte {'$' },
24+ endBytesDoubleDollar : []byte {'$' , '$' },
2725}
2826
2927func NewInlineDollarParser () parser.InlineParser {
3028 return defaultInlineDollarParser
3129}
3230
33- func NewInlineDualDollarParser () parser.InlineParser {
34- return defaultDualDollarParser
35- }
36-
3731var defaultInlineBracketParser = & inlineParser {
38- start : []byte {'\\' , '(' },
39- end : []byte {'\\' , ')' },
32+ trigger : []byte {'\\' , '(' },
33+ endBytesBracket : []byte {'\\' , ')' },
4034}
4135
4236func NewInlineBracketParser () parser.InlineParser {
@@ -45,7 +39,7 @@ func NewInlineBracketParser() parser.InlineParser {
4539
4640// Trigger triggers this parser on $ or \
4741func (parser * inlineParser ) Trigger () []byte {
48- return parser .start
42+ return parser .trigger
4943}
5044
5145func isPunctuation (b byte ) bool {
@@ -64,33 +58,60 @@ func isAlphanumeric(b byte) bool {
6458func (parser * inlineParser ) Parse (parent ast.Node , block text.Reader , pc parser.Context ) ast.Node {
6559 line , _ := block .PeekLine ()
6660
67- if ! bytes .HasPrefix (line , parser .start ) {
61+ if ! bytes .HasPrefix (line , parser .trigger ) {
6862 // We'll catch this one on the next time round
6963 return nil
7064 }
7165
72- precedingCharacter := block .PrecendingCharacter ()
73- if precedingCharacter < 256 && (isAlphanumeric (byte (precedingCharacter )) || isPunctuation (byte (precedingCharacter ))) {
74- // need to exclude things like `a$` from being considered a start
75- return nil
66+ var startMarkLen int
67+ var stopMark []byte
68+ checkSurrounding := true
69+ if line [0 ] == '$' {
70+ startMarkLen = 1
71+ stopMark = parser .endBytesSingleDollar
72+ if len (line ) > 1 {
73+ if line [1 ] == '$' {
74+ startMarkLen = 2
75+ stopMark = parser .endBytesDoubleDollar
76+ } else if line [1 ] == '`' {
77+ pos := 1
78+ for ; pos < len (line ) && line [pos ] == '`' ; pos ++ {
79+ }
80+ startMarkLen = pos
81+ stopMark = bytes .Repeat ([]byte {'`' }, pos )
82+ stopMark [len (stopMark )- 1 ] = '$'
83+ checkSurrounding = false
84+ }
85+ }
86+ } else {
87+ startMarkLen = 2
88+ stopMark = parser .endBytesBracket
89+ }
90+
91+ if checkSurrounding {
92+ precedingCharacter := block .PrecendingCharacter ()
93+ if precedingCharacter < 256 && (isAlphanumeric (byte (precedingCharacter )) || isPunctuation (byte (precedingCharacter ))) {
94+ // need to exclude things like `a$` from being considered a start
95+ return nil
96+ }
7697 }
7798
7899 // move the opener marker point at the start of the text
79- opener := len ( parser . start )
100+ opener := startMarkLen
80101
81102 // Now look for an ending line
82103 depth := 0
83104 ender := - 1
84105 for i := opener ; i < len (line ); i ++ {
85- if depth == 0 && bytes .HasPrefix (line [i :], parser . end ) {
106+ if depth == 0 && bytes .HasPrefix (line [i :], stopMark ) {
86107 succeedingCharacter := byte (0 )
87- if i + len (parser . end ) < len (line ) {
88- succeedingCharacter = line [i + len (parser . end )]
108+ if i + len (stopMark ) < len (line ) {
109+ succeedingCharacter = line [i + len (stopMark )]
89110 }
90111 // check valid ending character
91112 isValidEndingChar := isPunctuation (succeedingCharacter ) || isBracket (succeedingCharacter ) ||
92113 succeedingCharacter == ' ' || succeedingCharacter == '\n' || succeedingCharacter == 0
93- if ! isValidEndingChar {
114+ if checkSurrounding && ! isValidEndingChar {
94115 break
95116 }
96117 ender = i
@@ -112,21 +133,12 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.
112133
113134 block .Advance (opener )
114135 _ , pos := block .Position ()
115- var node ast.Node
116- if parser == defaultDualDollarParser {
117- node = NewInlineBlock ()
118- } else {
119- node = NewInline ()
120- }
136+ node := NewInline ()
137+
121138 segment := pos .WithStop (pos .Start + ender - opener )
122139 node .AppendChild (node , ast .NewRawTextSegment (segment ))
123- block .Advance (ender - opener + len (parser .end ))
124-
125- if parser == defaultDualDollarParser {
126- trimBlock (& (node .(* InlineBlock )).Inline , block )
127- } else {
128- trimBlock (node .(* Inline ), block )
129- }
140+ block .Advance (ender - opener + len (stopMark ))
141+ trimBlock (node , block )
130142 return node
131143}
132144
0 commit comments