@@ -113,6 +113,18 @@ function parseMarkdown(html: string) {
113113 '<img alt="$1" data-document-id="$2">' ,
114114 ) ;
115115
116+ // Protect raw URLs from markdown processing (e.g., '__' inside paths)
117+ // Temporarily replace detected URLs with placeholders, apply markdown, then restore.
118+ const urlPlaceholders : string [ ] = [ ] ;
119+ const PLACEHOLDER_PREFIX = '[[TT_URL_' ;
120+ const PLACEHOLDER_SUFFIX = ']]' ;
121+ const escapeRegExp = ( s : string ) => s . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
122+ const reRawLink = new RegExp ( RE_LINK_TEMPLATE , 'g' ) ;
123+ parsedHtml = parsedHtml . replace ( reRawLink , ( match ) => {
124+ const i = urlPlaceholders . push ( match ) - 1 ;
125+ return `${ PLACEHOLDER_PREFIX } ${ i } ${ PLACEHOLDER_SUFFIX } ` ;
126+ } ) ;
127+
116128 // Other simple markdown
117129 parsedHtml = parsedHtml . replace (
118130 / (? ! < ( c o d e | p r e ) [ ^ < ] * | < \/ ) [ * ] { 2 } ( [ ^ * \n ] + ) [ * ] { 2 } (? ! [ ^ < ] * < \/ ( c o d e | p r e ) > ) / g,
@@ -131,6 +143,15 @@ function parseMarkdown(html: string) {
131143 `<span data-entity-type="${ ApiMessageEntityTypes . Spoiler } ">$2</span>` ,
132144 ) ;
133145
146+ // Restore protected URLs
147+ if ( urlPlaceholders . length ) {
148+ const restoreRe = new RegExp ( `${ escapeRegExp ( PLACEHOLDER_PREFIX ) } (\\d+)${ escapeRegExp ( PLACEHOLDER_SUFFIX ) } ` , 'g' ) ;
149+ parsedHtml = parsedHtml . replace ( restoreRe , ( full , idx ) => {
150+ const i = Number ( idx ) ;
151+ return Number . isFinite ( i ) && urlPlaceholders [ i ] !== undefined ? urlPlaceholders [ i ] : full ;
152+ } ) ;
153+ }
154+
134155 return parsedHtml ;
135156}
136157
0 commit comments