Resolve intra-doc links in summary desc
Before:  After: 
This commit is contained in:
parent
312b894cc1
commit
20915d471a
4 changed files with 61 additions and 11 deletions
|
@ -523,6 +523,33 @@ impl Item {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find a list of all link names, without finding their href.
|
||||||
|
///
|
||||||
|
/// This is used for generating summary text, which does not include
|
||||||
|
/// the link text, but does need to know which `[]`-bracketed names
|
||||||
|
/// are actually links.
|
||||||
|
crate fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> {
|
||||||
|
cache
|
||||||
|
.intra_doc_links
|
||||||
|
.get(&self.def_id)
|
||||||
|
.map_or(&[][..], |v| v.as_slice())
|
||||||
|
.iter()
|
||||||
|
.filter_map(|ItemLink { link: s, link_text, did, fragment }| {
|
||||||
|
// FIXME(83083): using fragments as a side-channel for
|
||||||
|
// primitive names is very unfortunate
|
||||||
|
if did.is_some() || fragment.is_some() {
|
||||||
|
Some(RenderedLink {
|
||||||
|
original_text: s.clone(),
|
||||||
|
new_text: link_text.clone(),
|
||||||
|
href: String::new(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
crate fn is_crate(&self) -> bool {
|
crate fn is_crate(&self) -> bool {
|
||||||
self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX)
|
self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX)
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,13 +292,14 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
||||||
// which should not be indexed. The crate-item itself is
|
// which should not be indexed. The crate-item itself is
|
||||||
// inserted later on when serializing the search-index.
|
// inserted later on when serializing the search-index.
|
||||||
if item.def_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) {
|
if item.def_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) {
|
||||||
|
let desc = item.doc_value().map_or_else(String::new, |x| {
|
||||||
|
short_markdown_summary(&x.as_str(), &item.link_names(&self.cache))
|
||||||
|
});
|
||||||
self.cache.search_index.push(IndexItem {
|
self.cache.search_index.push(IndexItem {
|
||||||
ty: item.type_(),
|
ty: item.type_(),
|
||||||
name: s.to_string(),
|
name: s.to_string(),
|
||||||
path: path.join("::"),
|
path: path.join("::"),
|
||||||
desc: item
|
desc,
|
||||||
.doc_value()
|
|
||||||
.map_or_else(String::new, |x| short_markdown_summary(&x.as_str())),
|
|
||||||
parent,
|
parent,
|
||||||
parent_idx: None,
|
parent_idx: None,
|
||||||
search_type: get_index_search_type(&item, &self.empty_cache, self.tcx),
|
search_type: get_index_search_type(&item, &self.empty_cache, self.tcx),
|
||||||
|
|
|
@ -1051,7 +1051,11 @@ impl MarkdownSummaryLine<'_> {
|
||||||
///
|
///
|
||||||
/// Returns a tuple of the rendered HTML string and whether the output was shortened
|
/// Returns a tuple of the rendered HTML string and whether the output was shortened
|
||||||
/// due to the provided `length_limit`.
|
/// due to the provided `length_limit`.
|
||||||
fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool) {
|
fn markdown_summary_with_limit(
|
||||||
|
md: &str,
|
||||||
|
link_names: &[RenderedLink],
|
||||||
|
length_limit: usize,
|
||||||
|
) -> (String, bool) {
|
||||||
if md.is_empty() {
|
if md.is_empty() {
|
||||||
return (String::new(), false);
|
return (String::new(), false);
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1069,20 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool)
|
||||||
*text_length += text.len();
|
*text_length += text.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
'outer: for event in Parser::new_ext(md, summary_opts()) {
|
let mut replacer = |broken_link: BrokenLink<'_>| {
|
||||||
|
if let Some(link) =
|
||||||
|
link_names.iter().find(|link| &*link.original_text == broken_link.reference)
|
||||||
|
{
|
||||||
|
Some((link.href.as_str().into(), link.new_text.as_str().into()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
|
||||||
|
let p = LinkReplacer::new(p, link_names);
|
||||||
|
|
||||||
|
'outer: for event in p {
|
||||||
match &event {
|
match &event {
|
||||||
Event::Text(text) => {
|
Event::Text(text) => {
|
||||||
for word in text.split_inclusive(char::is_whitespace) {
|
for word in text.split_inclusive(char::is_whitespace) {
|
||||||
|
@ -1121,8 +1138,8 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool)
|
||||||
/// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened.
|
/// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened.
|
||||||
///
|
///
|
||||||
/// See [`markdown_summary_with_limit`] for details about what is rendered and what is not.
|
/// See [`markdown_summary_with_limit`] for details about what is rendered and what is not.
|
||||||
crate fn short_markdown_summary(markdown: &str) -> String {
|
crate fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) -> String {
|
||||||
let (mut s, was_shortened) = markdown_summary_with_limit(markdown, 59);
|
let (mut s, was_shortened) = markdown_summary_with_limit(markdown, link_names, 59);
|
||||||
|
|
||||||
if was_shortened {
|
if was_shortened {
|
||||||
s.push('…');
|
s.push('…');
|
||||||
|
|
|
@ -34,11 +34,14 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
|
||||||
// has since been learned.
|
// has since been learned.
|
||||||
for &(did, ref item) in &cache.orphan_impl_items {
|
for &(did, ref item) in &cache.orphan_impl_items {
|
||||||
if let Some(&(ref fqp, _)) = cache.paths.get(&did) {
|
if let Some(&(ref fqp, _)) = cache.paths.get(&did) {
|
||||||
|
let desc = item
|
||||||
|
.doc_value()
|
||||||
|
.map_or_else(String::new, |s| short_markdown_summary(&s, &item.link_names(&cache)));
|
||||||
cache.search_index.push(IndexItem {
|
cache.search_index.push(IndexItem {
|
||||||
ty: item.type_(),
|
ty: item.type_(),
|
||||||
name: item.name.unwrap().to_string(),
|
name: item.name.unwrap().to_string(),
|
||||||
path: fqp[..fqp.len() - 1].join("::"),
|
path: fqp[..fqp.len() - 1].join("::"),
|
||||||
desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)),
|
desc,
|
||||||
parent: Some(did.into()),
|
parent: Some(did.into()),
|
||||||
parent_idx: None,
|
parent_idx: None,
|
||||||
search_type: get_index_search_type(&item, cache, tcx),
|
search_type: get_index_search_type(&item, cache, tcx),
|
||||||
|
@ -47,6 +50,11 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let crate_doc = krate
|
||||||
|
.module
|
||||||
|
.doc_value()
|
||||||
|
.map_or_else(String::new, |s| short_markdown_summary(&s, &krate.module.link_names(&cache)));
|
||||||
|
|
||||||
let Cache { ref mut search_index, ref paths, .. } = *cache;
|
let Cache { ref mut search_index, ref paths, .. } = *cache;
|
||||||
|
|
||||||
// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
|
// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
|
||||||
|
@ -100,9 +108,6 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
|
||||||
crate_items.push(&*item);
|
crate_items.push(&*item);
|
||||||
}
|
}
|
||||||
|
|
||||||
let crate_doc =
|
|
||||||
krate.module.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s));
|
|
||||||
|
|
||||||
struct CrateData<'a> {
|
struct CrateData<'a> {
|
||||||
doc: String,
|
doc: String,
|
||||||
items: Vec<&'a IndexItem>,
|
items: Vec<&'a IndexItem>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue