@@ -50,7 +50,7 @@ use crate::html::render::small_url_encode;
50
50
use crate :: html:: toc:: TocBuilder ;
51
51
52
52
use pulldown_cmark:: {
53
- html, BrokenLink , CodeBlockKind , CowStr , Event , LinkType , Options , Parser , Tag ,
53
+ html, BrokenLink , CodeBlockKind , CowStr , Event , LinkType , OffsetIter , Options , Parser , Tag ,
54
54
} ;
55
55
56
56
#[ cfg( test) ]
@@ -1240,6 +1240,7 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
1240
1240
pub ( crate ) struct MarkdownLink {
1241
1241
pub kind : LinkType ,
1242
1242
pub link : String ,
1243
+ pub display_text : Option < String > ,
1243
1244
pub range : MarkdownLinkRange ,
1244
1245
}
1245
1246
@@ -1263,8 +1264,8 @@ impl MarkdownLinkRange {
1263
1264
}
1264
1265
}
1265
1266
1266
- pub ( crate ) fn markdown_links < R > (
1267
- md : & str ,
1267
+ pub ( crate ) fn markdown_links < ' md , R > (
1268
+ md : & ' md str ,
1268
1269
preprocess_link : impl Fn ( MarkdownLink ) -> Option < R > ,
1269
1270
) -> Vec < R > {
1270
1271
if md. is_empty ( ) {
@@ -1375,32 +1376,90 @@ pub(crate) fn markdown_links<R>(
1375
1376
MarkdownLinkRange :: Destination ( range. clone ( ) )
1376
1377
} ;
1377
1378
1378
- Parser :: new_with_broken_link_callback (
1379
+ let mut broken_link_callback = |link : BrokenLink < ' md > | Some ( ( link. reference , "" . into ( ) ) ) ;
1380
+ let mut event_iter = Parser :: new_with_broken_link_callback (
1379
1381
md,
1380
1382
main_body_opts ( ) ,
1381
- Some ( & mut | link : BrokenLink < ' _ > | Some ( ( link . reference , "" . into ( ) ) ) ) ,
1383
+ Some ( & mut broken_link_callback ) ,
1382
1384
)
1383
- . into_offset_iter ( )
1384
- . filter_map ( |( event, span) | match event {
1385
- Event :: Start ( Tag :: Link ( link_type, dest, _) ) if may_be_doc_link ( link_type) => {
1386
- let range = match link_type {
1387
- // Link is pulled from the link itself.
1388
- LinkType :: ReferenceUnknown | LinkType :: ShortcutUnknown => {
1389
- span_for_offset_backward ( span, b'[' , b']' )
1390
- }
1391
- LinkType :: CollapsedUnknown => span_for_offset_forward ( span, b'[' , b']' ) ,
1392
- LinkType :: Inline => span_for_offset_backward ( span, b'(' , b')' ) ,
1393
- // Link is pulled from elsewhere in the document.
1394
- LinkType :: Reference | LinkType :: Collapsed | LinkType :: Shortcut => {
1395
- span_for_link ( & dest, span)
1385
+ . into_offset_iter ( ) ;
1386
+ let mut links = Vec :: new ( ) ;
1387
+
1388
+ while let Some ( ( event, span) ) = event_iter. next ( ) {
1389
+ match event {
1390
+ Event :: Start ( Tag :: Link ( link_type, dest, _) ) if may_be_doc_link ( link_type) => {
1391
+ let range = match link_type {
1392
+ // Link is pulled from the link itself.
1393
+ LinkType :: ReferenceUnknown | LinkType :: ShortcutUnknown => {
1394
+ span_for_offset_backward ( span, b'[' , b']' )
1395
+ }
1396
+ LinkType :: CollapsedUnknown => span_for_offset_forward ( span, b'[' , b']' ) ,
1397
+ LinkType :: Inline => span_for_offset_backward ( span, b'(' , b')' ) ,
1398
+ // Link is pulled from elsewhere in the document.
1399
+ LinkType :: Reference | LinkType :: Collapsed | LinkType :: Shortcut => {
1400
+ span_for_link ( & dest, span)
1401
+ }
1402
+ LinkType :: Autolink | LinkType :: Email => unreachable ! ( ) ,
1403
+ } ;
1404
+
1405
+ let display_text = if matches ! (
1406
+ link_type,
1407
+ LinkType :: Inline
1408
+ | LinkType :: ReferenceUnknown
1409
+ | LinkType :: Reference
1410
+ | LinkType :: Shortcut
1411
+ | LinkType :: ShortcutUnknown
1412
+ ) {
1413
+ collect_link_data ( & mut event_iter)
1414
+ } else {
1415
+ None
1416
+ } ;
1417
+
1418
+ if let Some ( link) = preprocess_link ( MarkdownLink {
1419
+ kind : link_type,
1420
+ link : dest. into_string ( ) ,
1421
+ display_text,
1422
+ range,
1423
+ } ) {
1424
+ links. push ( link) ;
1396
1425
}
1397
- LinkType :: Autolink | LinkType :: Email => unreachable ! ( ) ,
1398
- } ;
1399
- preprocess_link ( MarkdownLink { kind : link_type, range, link : dest. into_string ( ) } )
1426
+ }
1427
+ _ => { }
1400
1428
}
1401
- _ => None ,
1402
- } )
1403
- . collect ( )
1429
+ }
1430
+
1431
+ links
1432
+ }
1433
+
1434
+ /// Collects additional data of link.
1435
+ fn collect_link_data < ' input , ' callback > (
1436
+ event_iter : & mut OffsetIter < ' input , ' callback > ,
1437
+ ) -> Option < String > {
1438
+ let mut display_text: Option < String > = None ;
1439
+ let mut append_text = |text : CowStr < ' _ > | {
1440
+ if let Some ( display_text) = & mut display_text {
1441
+ display_text. push_str ( & text) ;
1442
+ } else {
1443
+ display_text = Some ( text. to_string ( ) ) ;
1444
+ }
1445
+ } ;
1446
+
1447
+ while let Some ( ( event, _span) ) = event_iter. next ( ) {
1448
+ match event {
1449
+ Event :: Text ( text) => {
1450
+ append_text ( text) ;
1451
+ }
1452
+ Event :: Code ( code) => {
1453
+ append_text ( code) ;
1454
+ }
1455
+ Event :: End ( _) => {
1456
+ break ;
1457
+ }
1458
+ _ => { }
1459
+ }
1460
+ }
1461
+
1462
+ display_text
1404
1463
}
1405
1464
1406
1465
#[ derive( Debug ) ]
0 commit comments