1010using Elastic . Documentation . Diagnostics ;
1111using Elastic . Markdown . Diagnostics ;
1212using Elastic . Markdown . Myst . InlineParsers . Substitution ;
13+ using Elastic . Markdown . Myst . Roles ;
1314using Markdig . Helpers ;
1415using Markdig . Parsers ;
1516using Markdig . Renderers ;
2021namespace Elastic . Markdown . Myst . InlineParsers . SubstitutionInlineCode ;
2122
2223[ DebuggerDisplay ( "{GetType().Name} Line: {Line}, Content: {Content}, ProcessedContent: {ProcessedContent}" ) ]
23- public class SubstitutionInlineCodeLeaf ( string content , string processedContent ) : CodeInline ( content )
24+ public class SubstitutionInlineCodeLeaf ( string role , string content , string processedContent ) : RoleLeaf ( role , content )
2425{
2526 public string ProcessedContent { get ; } = processedContent ;
2627}
@@ -38,108 +39,18 @@ protected override void Write(HtmlRenderer renderer, SubstitutionInlineCodeLeaf
3839 }
3940}
4041
41- public partial class SubstitutionInlineCodeParser : InlineParser
42+ public partial class SubstitutionInlineCodeParser : RoleParser < SubstitutionInlineCodeLeaf >
4243{
43- public SubstitutionInlineCodeParser ( ) => OpeningCharacters = [ '{' ] ;
44-
45- private readonly SearchValues < char > _values = SearchValues . Create ( [ '\r ' , '\n ' , ' ' , '\t ' , '}' ] ) ;
46- private static readonly Regex SubstitutionPattern = SubstitutionRegex ( ) ;
47-
48- public override bool Match ( InlineProcessor processor , ref StringSlice slice )
44+ protected override SubstitutionInlineCodeLeaf CreateRole ( string role , string content , InlineProcessor parserContext )
4945 {
50- var match = slice . CurrentChar ;
51-
52- if ( processor . Context is not ParserContext context )
53- return false ;
54-
55- Debug . Assert ( match is not ( '\r ' or '\n ' ) ) ;
56-
57- // Match the opened sticks
58- var openSticks = slice . CountAndSkipChar ( match ) ;
59- if ( openSticks > 1 )
60- return false ;
61-
62- var span = slice . AsSpan ( ) ;
63-
64- var i = span . IndexOfAny ( _values ) ;
65-
66- // We got to the end of the input before seeing the match character.
67- if ( ( uint ) i >= ( uint ) span . Length )
68- return false ;
69-
70- var closeSticks = 0 ;
71- while ( ( uint ) i < ( uint ) span . Length && span [ i ] == '}' )
72- {
73- closeSticks ++ ;
74- i ++ ;
75- }
76-
77- if ( closeSticks > 1 )
78- return false ;
79-
80- var roleContent = slice . AsSpan ( ) [ ..i ] ;
81-
82- // Check if this matches the "subs=true" pattern
83- if ( ! roleContent . SequenceEqual ( "{subs=true}" . AsSpan ( ) ) )
84- return false ;
85-
86- // Check if the next character is a backtick
87- if ( i >= span . Length || span [ i ] != '`' )
88- return false ;
89-
90- var openingBacktickPos = i ;
91- var contentStartPos = i + 1 ; // Skip the opening backtick
92-
93- var closingBacktickIndex = - 1 ;
94- for ( var j = contentStartPos ; j < span . Length ; j ++ )
95- {
96- if ( span [ j ] != '`' )
97- continue ;
98- closingBacktickIndex = j ;
99- break ;
100- }
101-
102- if ( closingBacktickIndex == - 1 )
103- return false ;
104-
105- var contentSpan = span [ openingBacktickPos ..( closingBacktickIndex + 1 ) ] ;
106-
107- var startPosition = slice . Start ;
108- slice . Start = startPosition + roleContent . Length + contentSpan . Length ;
109-
110- // We've already skipped the opening sticks. Account for that here.
111- startPosition -= openSticks ;
112- startPosition = Math . Max ( startPosition , 0 ) ;
113-
114- var start = processor . GetSourcePosition ( startPosition , out var line , out var column ) ;
115- var end = processor . GetSourcePosition ( slice . Start ) ;
116- var sourceSpan = new SourceSpan ( start , end ) ;
117-
118- // Extract the actual code content (without backticks)
119- var codeContent = contentSpan . Trim ( '`' ) . ToString ( ) ;
120-
121- // Process substitutions in the code content
122- var processedContent = ProcessSubstitutions ( codeContent , context , processor , line , column ) ;
46+ var context = ( ParserContext ) parserContext . Context ! ;
47+ var processedContent = ProcessSubstitutions ( content , context , parserContext , 0 , 0 ) ;
48+ return new SubstitutionInlineCodeLeaf ( role , content , processedContent ) ;
49+ }
12350
124- var leaf = new SubstitutionInlineCodeLeaf ( codeContent , processedContent )
125- {
126- Delimiter = '{' ,
127- Span = sourceSpan ,
128- Line = line ,
129- Column = column ,
130- DelimiterCount = openSticks
131- } ;
132-
133- if ( processor . TrackTrivia )
134- {
135- // startPosition and slice.Start include the opening/closing sticks.
136- leaf . ContentWithTrivia =
137- new StringSlice ( slice . Text , startPosition + openSticks , slice . Start - openSticks - 1 ) ;
138- }
51+ protected override bool Matches ( ReadOnlySpan < char > role ) => role . SequenceEqual ( "{subs}" . AsSpan ( ) ) ;
13952
140- processor . Inline = leaf ;
141- return true ;
142- }
53+ private static readonly Regex SubstitutionPattern = SubstitutionRegex ( ) ;
14354
14455 private static string ProcessSubstitutions ( string content , ParserContext context , InlineProcessor processor , int line , int column )
14556 {
0 commit comments