@@ -180,10 +180,21 @@ public static MarkdownPipeline Pipeline
180180
181181 /// <summary>
182182 /// Preprocesses substitutions specifically in link patterns [text](url) before Markdig parsing
183+ /// Only processes links that are not inside code blocks with subs=false
183184 /// </summary>
184- private static string PreprocessLinkSubstitutions ( string markdown , ParserContext context ) =>
185- LinkPattern ( ) . Replace ( markdown , match =>
185+ private static string PreprocessLinkSubstitutions ( string markdown , ParserContext context )
186+ {
187+ // Find all code block boundaries to avoid processing links inside subs=false blocks
188+ var codeBlockRanges = GetCodeBlockRanges ( markdown ) ;
189+
190+ return LinkPattern ( ) . Replace ( markdown , match =>
186191 {
192+ // Check if this link is inside a code block with subs=false
193+ if ( IsInsideSubsDisabledCodeBlock ( match . Index , codeBlockRanges ) )
194+ {
195+ return match . Value ; // Don't process links in subs=false code blocks
196+ }
197+
187198 var linkText = match . Groups [ 1 ] . Value ;
188199 var linkUrl = match . Groups [ 2 ] . Value ;
189200
@@ -200,4 +211,54 @@ private static string PreprocessLinkSubstitutions(string markdown, ParserContext
200211 // Return original match for internal links
201212 return match . Value ;
202213 } ) ;
214+ }
215+
216+ private static List < ( int start , int end , bool subsDisabled ) > GetCodeBlockRanges ( string markdown )
217+ {
218+ var ranges = new List < ( int start , int end , bool subsDisabled ) > ( ) ;
219+ var lines = markdown . Split ( '\n ' ) ;
220+ var currentPos = 0 ;
221+
222+ for ( var i = 0 ; i < lines . Length ; i ++ )
223+ {
224+ var line = lines [ i ] ;
225+
226+ // Check for code block start (``` or ````)
227+ if ( line . TrimStart ( ) . StartsWith ( "```" ) )
228+ {
229+ // Check if this line contains subs=false
230+ var subsDisabled = line . Contains ( "subs=false" ) ;
231+ var blockStart = currentPos ;
232+
233+ // Find the end of the code block
234+ var blockEnd = currentPos + line . Length ;
235+ for ( var j = i + 1 ; j < lines . Length ; j ++ )
236+ {
237+ blockEnd += lines [ j ] . Length + 1 ; // +1 for newline
238+ if ( lines [ j ] . TrimStart ( ) . StartsWith ( "```" ) )
239+ {
240+ break ;
241+ }
242+ }
243+
244+ ranges . Add ( ( blockStart , blockEnd , subsDisabled ) ) ;
245+ }
246+
247+ currentPos += line . Length + 1 ; // +1 for newline
248+ }
249+
250+ return ranges ;
251+ }
252+
253+ private static bool IsInsideSubsDisabledCodeBlock ( int index , List < ( int start , int end , bool subsDisabled ) > codeBlockRanges )
254+ {
255+ foreach ( var ( start , end , subsDisabled ) in codeBlockRanges )
256+ {
257+ if ( index >= start && index <= end && subsDisabled )
258+ {
259+ return true ;
260+ }
261+ }
262+ return false ;
263+ }
203264}
0 commit comments