@@ -1040,7 +1040,7 @@ impl LinkCollector<'_, '_> {
1040
1040
matches ! ( ori_link. kind, LinkType :: Reference | LinkType :: Shortcut ) ,
1041
1041
) ?;
1042
1042
1043
- self . check_redundant_explicit_link (
1043
+ self . resolve_display_text (
1044
1044
path_str,
1045
1045
ResolutionInfo {
1046
1046
item_id,
@@ -1384,42 +1384,93 @@ impl LinkCollector<'_, '_> {
1384
1384
}
1385
1385
}
1386
1386
1387
- /// Check if resolution of inline link's display text and explicit link are same.
1388
- fn check_redundant_explicit_link (
1387
+ /// Resolve display text if the provided link has separated parts of links.
1388
+ ///
1389
+ /// For example:
1390
+ /// Inline link `[display_text](dest_link)` and reference link `[display_text][reference_link]` has
1391
+ /// separated parts of links.
1392
+ fn resolve_display_text (
1389
1393
& mut self ,
1390
1394
explicit_link : & Box < str > ,
1391
1395
display_res_info : ResolutionInfo ,
1392
1396
ori_link : & MarkdownLink ,
1393
1397
diag_info : & DiagnosticInfo < ' _ > ,
1394
1398
) {
1395
1399
// Check if explicit resolution's path is same as resolution of original link's display text path, e.g.
1400
+ //
1401
+ // LinkType::Inline:
1402
+ //
1396
1403
// [target](target)
1397
1404
// [`target`](target)
1398
1405
// [target](path::to::target)
1399
1406
// [`target`](path::to::target)
1407
+ // [path::to::target](target)
1408
+ // [`path::to::target`](target)
1400
1409
// [path::to::target](path::to::target)
1401
1410
// [`path::to::target`](path::to::target)
1402
1411
//
1412
+ // LinkType::ReferenceUnknown
1413
+ //
1414
+ // [target][target]
1415
+ // [`target`][target]
1416
+ // [target][path::to::target]
1417
+ // [`target`][path::to::target]
1418
+ // [path::to::target][target]
1419
+ // [`path::to::target`][target]
1420
+ // [path::to::target][path::to::target]
1421
+ // [`path::to::target`][path::to::target]
1422
+ //
1423
+ // LinkType::Reference
1424
+ //
1425
+ // [target][target]
1426
+ // [`target`][target]
1427
+ // [target][path::to::target]
1428
+ // [`target`][path::to::target]
1429
+ // [path::to::target][target]
1430
+ // [`path::to::target`][target]
1431
+ // [path::to::target][path::to::target]
1432
+ // [`path::to::target`][path::to::target]
1433
+ //
1434
+ // [target]: target // or [target]: path::to::target
1435
+ // [path::to::target]: path::to::target // or [path::to::target]: target
1436
+ //
1403
1437
// To avoid disambiguator from panicking, we check if display text path is possible to be disambiguated
1404
1438
// into explicit path.
1405
- if ori_link. kind != LinkType :: Inline {
1439
+ if !matches ! (
1440
+ ori_link. kind,
1441
+ LinkType :: Inline | LinkType :: Reference | LinkType :: ReferenceUnknown
1442
+ ) {
1406
1443
return ;
1407
1444
}
1408
1445
1446
+ // Algorithm to check if display text could possibly be the explicit link:
1447
+ //
1448
+ // Consider 2 links which are display text and explicit link, pick the shorter
1449
+ // one as symbol and longer one as full qualified path, and tries to match symbol
1450
+ // to the full qualified path's last symbol.
1451
+ //
1452
+ // Otherwise, check if 2 links are same, if so, skip the resolve process.
1453
+ //
1454
+ // Notice that this algorithm is passive, might possibly miss actual redudant cases.
1455
+ let explicit_link = & explicit_link. to_string ( ) ;
1409
1456
let display_text = & ori_link. display_text ;
1410
1457
let display_len = display_text. len ( ) ;
1411
1458
let explicit_len = explicit_link. len ( ) ;
1412
1459
1413
- if explicit_len >= display_len
1414
- && & explicit_link[ ( explicit_len - display_len) ..] == display_text
1460
+ if display_len == explicit_len {
1461
+ // Whether they are same or not, skip the resolve process.
1462
+ return ;
1463
+ }
1464
+
1465
+ if ( explicit_len >= display_len
1466
+ && & explicit_link[ ( explicit_len - display_len) ..] == display_text)
1467
+ || ( display_len >= explicit_len
1468
+ && & display_text[ ( display_len - explicit_len) ..] == explicit_link)
1415
1469
{
1416
1470
self . resolve_with_disambiguator_cached (
1417
1471
display_res_info,
1418
1472
diag_info. clone ( ) , // this struct should really be Copy, but Range is not :(
1419
- // For reference-style links we want to report only one error so unsuccessful
1420
- // resolutions are cached, for other links we want to report an error every
1421
- // time so they are not cached.
1422
- matches ! ( ori_link. kind, LinkType :: Reference ) ,
1473
+ false ,
1423
1474
) ;
1424
1475
}
1425
1476
}
0 commit comments