Rollup merge of #105780 - GuillaumeGomez:read-more-links, r=notriddle
rustdoc: Don't add "Read more" link if there is no extra content Fixes #105677.
This commit is contained in:
commit
11de52a46d
@ -567,11 +567,12 @@ struct SummaryLine<'a, I: Iterator<Item = Event<'a>>> {
|
||||
inner: I,
|
||||
started: bool,
|
||||
depth: u32,
|
||||
skipped_tags: u32,
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
|
||||
fn new(iter: I) -> Self {
|
||||
SummaryLine { inner: iter, started: false, depth: 0 }
|
||||
SummaryLine { inner: iter, started: false, depth: 0, skipped_tags: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -601,6 +602,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
||||
let is_allowed_tag = match event {
|
||||
Event::Start(ref c) => {
|
||||
if is_forbidden_tag(c) {
|
||||
self.skipped_tags += 1;
|
||||
return None;
|
||||
}
|
||||
self.depth += 1;
|
||||
@ -608,6 +610,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
||||
}
|
||||
Event::End(ref c) => {
|
||||
if is_forbidden_tag(c) {
|
||||
self.skipped_tags += 1;
|
||||
return None;
|
||||
}
|
||||
self.depth -= 1;
|
||||
@ -616,6 +619,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
||||
}
|
||||
_ => true,
|
||||
};
|
||||
if !is_allowed_tag {
|
||||
self.skipped_tags += 1;
|
||||
}
|
||||
return if !is_allowed_tag {
|
||||
if is_start {
|
||||
Some(Event::Start(Tag::Paragraph))
|
||||
@ -1096,11 +1102,11 @@ impl MarkdownItemInfo<'_> {
|
||||
}
|
||||
|
||||
impl MarkdownSummaryLine<'_> {
|
||||
pub(crate) fn into_string(self) -> String {
|
||||
pub(crate) fn into_string_with_has_more_content(self) -> (String, bool) {
|
||||
let MarkdownSummaryLine(md, links) = self;
|
||||
// This is actually common enough to special-case
|
||||
if md.is_empty() {
|
||||
return String::new();
|
||||
return (String::new(), false);
|
||||
}
|
||||
|
||||
let mut replacer = |broken_link: BrokenLink<'_>| {
|
||||
@ -1110,17 +1116,26 @@ impl MarkdownSummaryLine<'_> {
|
||||
.map(|link| (link.href.as_str().into(), link.new_text.as_str().into()))
|
||||
};
|
||||
|
||||
let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
|
||||
let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer))
|
||||
.peekable();
|
||||
let mut summary = SummaryLine::new(p);
|
||||
|
||||
let mut s = String::new();
|
||||
|
||||
let without_paragraphs = LinkReplacer::new(SummaryLine::new(p), links).filter(|event| {
|
||||
let without_paragraphs = LinkReplacer::new(&mut summary, links).filter(|event| {
|
||||
!matches!(event, Event::Start(Tag::Paragraph) | Event::End(Tag::Paragraph))
|
||||
});
|
||||
|
||||
html::push_html(&mut s, without_paragraphs);
|
||||
|
||||
s
|
||||
let has_more_content =
|
||||
matches!(summary.inner.peek(), Some(Event::Start(_))) || summary.skipped_tags > 0;
|
||||
|
||||
(s, has_more_content)
|
||||
}
|
||||
|
||||
pub(crate) fn into_string(self) -> String {
|
||||
self.into_string_with_has_more_content().0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,9 +467,10 @@ fn document_short(
|
||||
return;
|
||||
}
|
||||
if let Some(s) = item.doc_value() {
|
||||
let mut summary_html = MarkdownSummaryLine(&s, &item.links(cx)).into_string();
|
||||
let (mut summary_html, has_more_content) =
|
||||
MarkdownSummaryLine(&s, &item.links(cx)).into_string_with_has_more_content();
|
||||
|
||||
if s.contains('\n') {
|
||||
if has_more_content {
|
||||
let link = format!(r#" <a{}>Read more</a>"#, assoc_href_attr(item, link, cx));
|
||||
|
||||
if let Some(idx) = summary_html.rfind("</p>") {
|
||||
|
34
src/test/rustdoc/read-more-unneeded.rs
Normal file
34
src/test/rustdoc/read-more-unneeded.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/105677.
|
||||
// This test ensures that the "Read more" link is only generated when
|
||||
// there is actually more documentation to read after the short summary.
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
pub trait MyFrom {
|
||||
/// # Hello
|
||||
/// ## Yolo
|
||||
/// more!
|
||||
fn try_from1();
|
||||
/// a
|
||||
/// b
|
||||
/// c
|
||||
fn try_from2();
|
||||
/// a
|
||||
///
|
||||
/// b
|
||||
///
|
||||
/// c
|
||||
fn try_from3();
|
||||
}
|
||||
|
||||
pub struct NonZero;
|
||||
|
||||
// @has 'foo/struct.NonZero.html'
|
||||
impl MyFrom for NonZero {
|
||||
// @matches - '//*[@class="docblock"]' '^Hello Read more$'
|
||||
fn try_from1() {}
|
||||
// @matches - '//*[@class="docblock"]' '^a\sb\sc$'
|
||||
fn try_from2() {}
|
||||
// @matches - '//*[@class="docblock"]' '^a Read more$'
|
||||
fn try_from3() {}
|
||||
}
|
@ -30,8 +30,6 @@ impl Trait for Struct {
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]' 'These docs contain'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'reference link'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'https://example.com'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'Read more'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.b'
|
||||
fn b() {}
|
||||
|
||||
// @!has - '//*[@id="method.c"]/../../div[@class="docblock"]' 'code block'
|
||||
|
Loading…
x
Reference in New Issue
Block a user