@@ -45,19 +45,19 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: Defin
45
45
// and valid URLs so we choose to be too eager to try to resolve what might be
46
46
// a URL.
47
47
if target. contains ( "://" ) {
48
- ( target. to_string ( ) , title. to_string ( ) )
48
+ ( Some ( LinkType :: Inline ) , target. to_string ( ) , title. to_string ( ) )
49
49
} else {
50
50
// Two possibilities:
51
51
// * path-based links: `../../module/struct.MyStruct.html`
52
52
// * module-based links (AKA intra-doc links): `super::super::module::MyStruct`
53
- if let Some ( rewritten ) = rewrite_intra_doc_link ( db, definition, target, title) {
54
- return rewritten ;
53
+ if let Some ( ( target , title ) ) = rewrite_intra_doc_link ( db, definition, target, title) {
54
+ return ( None , target , title ) ;
55
55
}
56
56
if let Some ( target) = rewrite_url_link ( db, definition, target) {
57
- return ( target, title. to_string ( ) ) ;
57
+ return ( Some ( LinkType :: Inline ) , target, title. to_string ( ) ) ;
58
58
}
59
59
60
- ( target. to_string ( ) , title. to_string ( ) )
60
+ ( None , target. to_string ( ) , title. to_string ( ) )
61
61
}
62
62
} ) ;
63
63
let mut out = String :: new ( ) ;
@@ -368,33 +368,42 @@ fn mod_path_of_def(db: &RootDatabase, def: Definition) -> Option<String> {
368
368
/// Rewrites a markdown document, applying 'callback' to each link.
369
369
fn map_links < ' e > (
370
370
events : impl Iterator < Item = Event < ' e > > ,
371
- callback : impl Fn ( & str , & str ) -> ( String , String ) ,
371
+ callback : impl Fn ( & str , & str ) -> ( Option < LinkType > , String , String ) ,
372
372
) -> impl Iterator < Item = Event < ' e > > {
373
373
let mut in_link = false ;
374
- let mut link_target: Option < CowStr > = None ;
374
+ // holds the origin link target on start event and the rewritten one on end event
375
+ let mut end_link_target: Option < CowStr > = None ;
376
+ // normally link's type is determined by the type of link tag in the end event,
377
+ // however in same cases we want to change the link type, for example,
378
+ // `Shortcut` type doesn't make sense for url links
379
+ let mut end_link_type: Option < LinkType > = None ;
375
380
376
381
events. map ( move |evt| match evt {
377
382
Event :: Start ( Tag :: Link ( _, ref target, _) ) => {
378
383
in_link = true ;
379
- link_target = Some ( target. clone ( ) ) ;
384
+ end_link_target = Some ( target. clone ( ) ) ;
380
385
evt
381
386
}
382
387
Event :: End ( Tag :: Link ( link_type, target, _) ) => {
383
388
in_link = false ;
384
389
Event :: End ( Tag :: Link (
385
- link_type,
386
- link_target . take ( ) . unwrap_or ( target) ,
390
+ end_link_type . unwrap_or ( link_type) ,
391
+ end_link_target . take ( ) . unwrap_or ( target) ,
387
392
CowStr :: Borrowed ( "" ) ,
388
393
) )
389
394
}
390
395
Event :: Text ( s) if in_link => {
391
- let ( link_target_s, link_name) = callback ( & link_target. take ( ) . unwrap ( ) , & s) ;
392
- link_target = Some ( CowStr :: Boxed ( link_target_s. into ( ) ) ) ;
396
+ let ( link_type, link_target_s, link_name) =
397
+ callback ( & end_link_target. take ( ) . unwrap ( ) , & s) ;
398
+ end_link_target = Some ( CowStr :: Boxed ( link_target_s. into ( ) ) ) ;
399
+ end_link_type = link_type;
393
400
Event :: Text ( CowStr :: Boxed ( link_name. into ( ) ) )
394
401
}
395
402
Event :: Code ( s) if in_link => {
396
- let ( link_target_s, link_name) = callback ( & link_target. take ( ) . unwrap ( ) , & s) ;
397
- link_target = Some ( CowStr :: Boxed ( link_target_s. into ( ) ) ) ;
403
+ let ( link_type, link_target_s, link_name) =
404
+ callback ( & end_link_target. take ( ) . unwrap ( ) , & s) ;
405
+ end_link_target = Some ( CowStr :: Boxed ( link_target_s. into ( ) ) ) ;
406
+ end_link_type = link_type;
398
407
Event :: Code ( CowStr :: Boxed ( link_name. into ( ) ) )
399
408
}
400
409
_ => evt,
@@ -468,7 +477,13 @@ fn filename_and_frag_for_def(
468
477
Adt :: Union ( u) => format ! ( "union.{}.html" , u. name( db) ) ,
469
478
} ,
470
479
Definition :: Module ( m) => match m. name ( db) {
471
- Some ( name) => format ! ( "{}/index.html" , name) ,
480
+ // `#[doc(keyword = "...")]` is internal used only by rust compiler
481
+ Some ( name) => match m. attrs ( db) . by_key ( "doc" ) . find_string_value_in_tt ( "keyword" ) {
482
+ Some ( kw) => {
483
+ format ! ( "keyword.{}.html" , kw. trim_matches( '"' ) )
484
+ }
485
+ None => format ! ( "{}/index.html" , name) ,
486
+ } ,
472
487
None => String :: from ( "index.html" ) ,
473
488
} ,
474
489
Definition :: Trait ( t) => format ! ( "trait.{}.html" , t. name( db) ) ,
0 commit comments