@@ -1135,6 +1135,7 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
1135
1135
1136
1136
let links = RefCell :: new ( vec ! [ ] ) ;
1137
1137
1138
+ // FIXME: remove this function once pulldown_cmark can provide spans for link definitions.
1138
1139
let locate = |s : & str , fallback : Range < usize > | unsafe {
1139
1140
let s_start = s. as_ptr ( ) ;
1140
1141
let s_end = s_start. add ( s. len ( ) ) ;
@@ -1149,10 +1150,25 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
1149
1150
}
1150
1151
} ;
1151
1152
1153
+ let span_for_link = |link : & CowStr < ' _ > , span : Range < usize > | {
1154
+ // For diagnostics, we want to underline the link's definition but `span` will point at
1155
+ // where the link is used. This is a problem for reference-style links, where the definition
1156
+ // is separate from the usage.
1157
+ match link {
1158
+ // `Borrowed` variant means the string (the link's destination) may come directly from
1159
+ // the markdown text and we can locate the original link destination.
1160
+ // NOTE: LinkReplacer also provides `Borrowed` but possibly from other sources,
1161
+ // so `locate()` can fall back to use `span`.
1162
+ CowStr :: Borrowed ( s) => locate ( s, span) ,
1163
+
1164
+ // For anything else, we can only use the provided range.
1165
+ CowStr :: Boxed ( _) | CowStr :: Inlined ( _) => span,
1166
+ }
1167
+ } ;
1168
+
1152
1169
let mut push = |link : BrokenLink < ' _ > | {
1153
- // FIXME: use `link.span` instead of `locate`
1154
- // (doing it now includes the `[]` as well as the text)
1155
- links. borrow_mut ( ) . push ( ( link. reference . to_owned ( ) , locate ( link. reference , link. span ) ) ) ;
1170
+ let span = span_for_link ( & CowStr :: Borrowed ( link. reference ) , link. span ) ;
1171
+ links. borrow_mut ( ) . push ( ( link. reference . to_owned ( ) , span) ) ;
1156
1172
None
1157
1173
} ;
1158
1174
let p = Parser :: new_with_broken_link_callback ( md, opts ( ) , Some ( & mut push) ) . into_offset_iter ( ) ;
@@ -1165,10 +1181,8 @@ crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
1165
1181
for ev in iter {
1166
1182
if let Event :: Start ( Tag :: Link ( _, dest, _) ) = ev. 0 {
1167
1183
debug ! ( "found link: {}" , dest) ;
1168
- links. borrow_mut ( ) . push ( match dest {
1169
- CowStr :: Borrowed ( s) => ( s. to_owned ( ) , locate ( s, ev. 1 ) ) ,
1170
- s @ ( CowStr :: Boxed ( ..) | CowStr :: Inlined ( ..) ) => ( s. into_string ( ) , ev. 1 ) ,
1171
- } ) ;
1184
+ let span = span_for_link ( & dest, ev. 1 ) ;
1185
+ links. borrow_mut ( ) . push ( ( dest. into_string ( ) , span) ) ;
1172
1186
}
1173
1187
}
1174
1188
0 commit comments