5
5
*/
6
6
7
7
; ( function ( ) {
8
+ 'use strict' ;
8
9
9
10
/**
10
11
* Block-Level Grammar
@@ -449,21 +450,21 @@ Lexer.prototype.token = function(src, top, bq) {
449
450
450
451
var inline = {
451
452
escape : / ^ \\ ( [ \\ ` * { } \[ \] ( ) # + \- . ! _ > ] ) / ,
452
- autolink : / ^ < ( [ ^ > ] + ( @ | : \/ ) [ ^ > ] + ) > / ,
453
+ autolink : / ^ < ( [ ^ < > ] + ( @ | : \/ ) [ ^ < > ] + ) > / ,
453
454
url : noop ,
454
- tag : / ^ < ! - - [ \s \S ] * ?- - > | ^ < \/ ? \w + (?: " [ ^ " ] * " | ' [ ^ ' ] * ' | [ ^ ' " > ] ) * ?> / ,
455
+ tag : / ^ < ! - - [ \s \S ] * ?- - > | ^ < \/ ? \w + (?: " [ ^ " ] * " | ' [ ^ ' ] * ' | [ ^ < ' " > ] ) * ?> / ,
455
456
link : / ^ ! ? \[ ( i n s i d e ) \] \( h r e f \) / ,
456
457
reflink : / ^ ! ? \[ ( i n s i d e ) \] \s * \[ ( [ ^ \] ] * ) \] / ,
457
458
nolink : / ^ ! ? \[ ( (?: \[ [ ^ \] ] * \] | [ ^ \[ \] ] ) * ) \] / ,
458
459
strong : / ^ _ _ ( [ \s \S ] + ?) _ _ (? ! _ ) | ^ \* \* ( [ \s \S ] + ?) \* \* (? ! \* ) / ,
459
460
em : / ^ \b _ ( (?: [ ^ _ ] | _ _ ) + ?) _ \b | ^ \* ( (?: \* \* | [ \s \S ] ) + ?) \* (? ! \* ) / ,
460
- code : / ^ ( ` + ) \s * ( [ \s \S ] * ?[ ^ ` ] ) \s * \1(? ! ` ) / ,
461
+ code : / ^ ( ` + ) ( [ \s \S ] * ?[ ^ ` ] ) \1(? ! ` ) / ,
461
462
br : / ^ { 2 , } \n (? ! \s * $ ) / ,
462
463
del : noop ,
463
464
text : / ^ [ \s \S ] + ?(? = [ \\ < ! \[ _ * ` ] | { 2 , } \n | $ ) /
464
465
} ;
465
466
466
- inline . _inside = / (?: \[ [ ^ \] ] * \] | [ ^ \[ \] ] | \] (? = [ ^ \[ ] * \] ) ) * / ;
467
+ inline . _inside = / (?: \[ [ ^ \] ] * \] | \\ [ \[ \] ] | [ ^ \[ \] ] | \] (? = [ ^ \[ ] * \] ) ) * / ;
467
468
inline . _href = / \s * < ? ( [ \s \S ] * ?) > ? (?: \s + [ ' " ] ( [ \s \S ] * ?) [ ' " ] ) ? \s * / ;
468
469
469
470
inline . link = replace ( inline . link )
@@ -578,9 +579,11 @@ InlineLexer.prototype.output = function(src) {
578
579
if ( cap = this . rules . autolink . exec ( src ) ) {
579
580
src = src . substring ( cap [ 0 ] . length ) ;
580
581
if ( cap [ 2 ] === '@' ) {
581
- text = cap [ 1 ] . charAt ( 6 ) === ':'
582
+ text = escape (
583
+ cap [ 1 ] . charAt ( 6 ) === ':'
582
584
? this . mangle ( cap [ 1 ] . substring ( 7 ) )
583
- : this . mangle ( cap [ 1 ] ) ;
585
+ : this . mangle ( cap [ 1 ] )
586
+ ) ;
584
587
href = this . mangle ( 'mailto:' ) + text ;
585
588
} else {
586
589
text = escape ( cap [ 1 ] ) ;
@@ -661,7 +664,7 @@ InlineLexer.prototype.output = function(src) {
661
664
// code
662
665
if ( cap = this . rules . code . exec ( src ) ) {
663
666
src = src . substring ( cap [ 0 ] . length ) ;
664
- out += this . renderer . codespan ( escape ( cap [ 2 ] , true ) ) ;
667
+ out += this . renderer . codespan ( escape ( cap [ 2 ] . trim ( ) , true ) ) ;
665
668
continue ;
666
669
}
667
670
@@ -873,12 +876,15 @@ Renderer.prototype.link = function(href, title, text) {
873
876
. replace ( / [ ^ \w : ] / g, '' )
874
877
. toLowerCase ( ) ;
875
878
} catch ( e ) {
876
- return '' ;
879
+ return text ;
877
880
}
878
- if ( prot . indexOf ( 'javascript:' ) === 0 || prot . indexOf ( 'vbscript:' ) === 0 ) {
879
- return '' ;
881
+ if ( prot . indexOf ( 'javascript:' ) === 0 || prot . indexOf ( 'vbscript:' ) === 0 || prot . indexOf ( 'data:' ) === 0 ) {
882
+ return text ;
880
883
}
881
884
}
885
+ if ( this . options . baseUrl && ! originIndependentUrl . test ( href ) ) {
886
+ href = resolveUrl ( this . options . baseUrl , href ) ;
887
+ }
882
888
var out = '<a href="' + href + '"' ;
883
889
if ( title ) {
884
890
out += ' title="' + title + '"' ;
@@ -888,6 +894,9 @@ Renderer.prototype.link = function(href, title, text) {
888
894
} ;
889
895
890
896
Renderer . prototype . image = function ( href , title , text ) {
897
+ if ( this . options . baseUrl && ! originIndependentUrl . test ( href ) ) {
898
+ href = resolveUrl ( this . options . baseUrl , href ) ;
899
+ }
891
900
var out = '<img src="' + href + '" alt="' + text + '"' ;
892
901
if ( title ) {
893
902
out += ' title="' + title + '"' ;
@@ -1094,8 +1103,8 @@ function escape(html, encode) {
1094
1103
}
1095
1104
1096
1105
function unescape ( html ) {
1097
- // explicitly match decimal, hex, and named HTML entities
1098
- return html . replace ( / & ( # (?: \d + ) | (?: # x [ 0 - 9 A - F a - f ] + ) | (?: \w + ) ) ; ? / g , function ( _ , n ) {
1106
+ // explicitly match decimal, hex, and named HTML entities
1107
+ return html . replace ( / & ( # (?: \d + ) | (?: # x [ 0 - 9 A - F a - f ] + ) | (?: \w + ) ) ; ? / ig , function ( _ , n ) {
1099
1108
n = n . toLowerCase ( ) ;
1100
1109
if ( n === 'colon' ) return ':' ;
1101
1110
if ( n . charAt ( 0 ) === '#' ) {
@@ -1119,6 +1128,30 @@ function replace(regex, opt) {
1119
1128
} ;
1120
1129
}
1121
1130
1131
+ function resolveUrl ( base , href ) {
1132
+ if ( ! baseUrls [ ' ' + base ] ) {
1133
+ // we can ignore everything in base after the last slash of its path component,
1134
+ // but we might need to add _that_
1135
+ // https://tools.ietf.org/html/rfc3986#section-3
1136
+ if ( / ^ [ ^ : ] + : \/ * [ ^ / ] * $ / . test ( base ) ) {
1137
+ baseUrls [ ' ' + base ] = base + '/' ;
1138
+ } else {
1139
+ baseUrls [ ' ' + base ] = base . replace ( / [ ^ / ] * $ / , '' ) ;
1140
+ }
1141
+ }
1142
+ base = baseUrls [ ' ' + base ] ;
1143
+
1144
+ if ( href . slice ( 0 , 2 ) === '//' ) {
1145
+ return base . replace ( / : [ \s \S ] * / , ':' ) + href ;
1146
+ } else if ( href . charAt ( 0 ) === '/' ) {
1147
+ return base . replace ( / ( : \/ * [ ^ / ] * ) [ \s \S ] * / , '$1' ) + href ;
1148
+ } else {
1149
+ return base + href ;
1150
+ }
1151
+ }
1152
+ var baseUrls = { } ;
1153
+ var originIndependentUrl = / ^ $ | ^ [ a - z ] [ a - z 0 - 9 + . - ] * : | ^ [ ? # ] / i;
1154
+
1122
1155
function noop ( ) { }
1123
1156
noop . exec = noop ;
1124
1157
@@ -1220,7 +1253,7 @@ function marked(src, opt, callback) {
1220
1253
} catch ( e ) {
1221
1254
e . message += '\nPlease report this to https://github.com/chjj/marked.' ;
1222
1255
if ( ( opt || marked . defaults ) . silent ) {
1223
- return '<p>An error occured :</p><pre>'
1256
+ return '<p>An error occurred :</p><pre>'
1224
1257
+ escape ( e . message + '' , true )
1225
1258
+ '</pre>' ;
1226
1259
}
@@ -1253,7 +1286,8 @@ marked.defaults = {
1253
1286
smartypants : false ,
1254
1287
headerPrefix : '' ,
1255
1288
renderer : new Renderer ,
1256
- xhtml : false
1289
+ xhtml : false ,
1290
+ baseUrl : null
1257
1291
} ;
1258
1292
1259
1293
/**
0 commit comments