Skip to content

Commit 994073f

Browse files
committed
Don't override explicit link definitions.
If the author has an explicit link definition, don't allow std_links to override it.
1 parent ef165e6 commit 994073f

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

mdbook-spec/src/std_links.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use mdbook::book::Chapter;
22
use once_cell::sync::Lazy;
33
use regex::{Captures, Regex};
4+
use std::collections::HashSet;
45
use std::fmt::Write as _;
56
use std::fs;
67
use std::io::{self, Write as _};
@@ -32,6 +33,15 @@ static STD_LINK_RE: Lazy<Regex> = Lazy::new(|| {
3233
static STD_LINK_EXTRACT_RE: Lazy<Regex> =
3334
Lazy::new(|| Regex::new(r#"<li><a [^>]*href="(https://doc.rust-lang.org/[^"]+)""#).unwrap());
3435

36+
/// The Regex for a markdown link definition.
37+
static LINK_DEF_RE: Lazy<Regex> = Lazy::new(|| {
38+
// This is a pretty lousy regex for a link definition. It doesn't
39+
// handle things like blockquotes, code blocks, etc. Using a
40+
// markdown parser isn't really feasible here, it would be nice to
41+
// improve this.
42+
Regex::new(r#"(?m)^(?<label>\[[^]]+\]): *(?<dest>.*)"#).unwrap()
43+
});
44+
3545
/// Converts links to the standard library to the online documentation in a
3646
/// fashion similar to rustdoc intra-doc links.
3747
pub fn std_links(chapter: &Chapter) -> String {
@@ -87,7 +97,7 @@ pub fn std_links(chapter: &Chapter) -> String {
8797
output
8898
}
8999

90-
/// Collects all markdown links.
100+
/// Collects all markdown links, excluding those that already have link definitions.
91101
///
92102
/// Returns a `Vec` of `(link, Option<dest>)` where markdown text like
93103
/// ``[`std::fmt`]`` would return that as a link. The dest is optional, for
@@ -112,6 +122,21 @@ fn collect_markdown_links(chapter: &Chapter) -> Vec<(&str, Option<&str>)> {
112122
}
113123
links.sort();
114124
links.dedup();
125+
// Remove any links that already have a link definition. We don't want
126+
// to override what the author explicitly specified.
127+
let existing_labels: HashSet<_> = LINK_DEF_RE
128+
.captures_iter(&chapter.content)
129+
.map(|cap| cap.get(1).unwrap().as_str())
130+
.collect();
131+
links.retain(|(link, dest)| {
132+
let mut tmp = None;
133+
let label: &str = dest.map_or(link, |d| {
134+
tmp = Some(format!("[`{d}`]"));
135+
tmp.as_deref().unwrap()
136+
});
137+
!existing_labels.contains(label)
138+
});
139+
115140
links
116141
}
117142

0 commit comments

Comments
 (0)