@@ -457,34 +457,56 @@ module.exports = class Tokenizer {
457457 link ( src ) {
458458 const cap = this . rules . inline . link . exec ( src ) ;
459459 if ( cap ) {
460- const lastParenIndex = findClosingBracket ( cap [ 2 ] , '()' ) ;
461- if ( lastParenIndex > - 1 ) {
462- const start = cap [ 0 ] . indexOf ( '!' ) === 0 ? 5 : 4 ;
463- const linkLen = start + cap [ 1 ] . length + lastParenIndex ;
464- cap [ 2 ] = cap [ 2 ] . substring ( 0 , lastParenIndex ) ;
465- cap [ 0 ] = cap [ 0 ] . substring ( 0 , linkLen ) . trim ( ) ;
466- cap [ 3 ] = '' ;
460+ const trimmedUrl = cap [ 2 ] . trim ( ) ;
461+ if ( ! this . options . pedantic && trimmedUrl . startsWith ( '<' ) ) {
462+ // commonmark requires matching angle brackets
463+ if ( ! trimmedUrl . endsWith ( '>' ) ) {
464+ return ;
465+ }
466+
467+ // ending angle bracket cannot be escaped
468+ const rtrimSlash = rtrim ( trimmedUrl . slice ( 0 , - 1 ) , '\\' ) ;
469+ if ( ( trimmedUrl . length - rtrimSlash . length ) % 2 === 0 ) {
470+ return ;
471+ }
472+ } else {
473+ // find closing parenthesis
474+ const lastParenIndex = findClosingBracket ( cap [ 2 ] , '()' ) ;
475+ if ( lastParenIndex > - 1 ) {
476+ const start = cap [ 0 ] . indexOf ( '!' ) === 0 ? 5 : 4 ;
477+ const linkLen = start + cap [ 1 ] . length + lastParenIndex ;
478+ cap [ 2 ] = cap [ 2 ] . substring ( 0 , lastParenIndex ) ;
479+ cap [ 0 ] = cap [ 0 ] . substring ( 0 , linkLen ) . trim ( ) ;
480+ cap [ 3 ] = '' ;
481+ }
467482 }
468483 let href = cap [ 2 ] ;
469484 let title = '' ;
470485 if ( this . options . pedantic ) {
486+ // split pedantic href and title
471487 const link = / ^ ( [ ^ ' " ] * [ ^ \s ] ) \s + ( [ ' " ] ) ( .* ) \2/ . exec ( href ) ;
472488
473489 if ( link ) {
474490 href = link [ 1 ] ;
475491 title = link [ 3 ] ;
476- } else {
477- title = '' ;
478492 }
479493 } else {
480494 title = cap [ 3 ] ? cap [ 3 ] . slice ( 1 , - 1 ) : '' ;
481495 }
482- href = href . trim ( ) . replace ( / ^ < ( [ \s \S ] * ) > $ / , '$1' ) ;
483- const token = outputLink ( cap , {
496+
497+ href = href . trim ( ) ;
498+ if ( href . startsWith ( '<' ) ) {
499+ if ( this . options . pedantic && ! trimmedUrl . endsWith ( '>' ) ) {
500+ // pedantic allows starting angle bracket without ending angle bracket
501+ href = href . slice ( 1 ) ;
502+ } else {
503+ href = href . slice ( 1 , - 1 ) ;
504+ }
505+ }
506+ return outputLink ( cap , {
484507 href : href ? href . replace ( this . rules . inline . _escapes , '$1' ) : href ,
485508 title : title ? title . replace ( this . rules . inline . _escapes , '$1' ) : title
486509 } , cap [ 0 ] ) ;
487- return token ;
488510 }
489511 }
490512
@@ -502,8 +524,7 @@ module.exports = class Tokenizer {
502524 text
503525 } ;
504526 }
505- const token = outputLink ( cap , link , cap [ 0 ] ) ;
506- return token ;
527+ return outputLink ( cap , link , cap [ 0 ] ) ;
507528 }
508529 }
509530
0 commit comments