Skip to content

Commit 1aebff9

Browse files
committed
Add Top TOC support to rustdoc
This commit adds the headers for the top level documentation to rustdoc's existing table of contents, along with associated items. It only show two levels of headers. Going further would require the sidebar to be wider, and that seems unnecessary (the crates that have manually-built TOCs usually don't need deeply nested headers).
1 parent 5aea140 commit 1aebff9

15 files changed

Lines changed: 267 additions & 129 deletions

File tree

‎src/librustdoc/clean/types.rs‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -506,9 +506,6 @@ impl Item {
506506
pub(crate)fnis_mod(&self) -> bool{
507507
self.type_() == ItemType::Module
508508
}
509-
pub(crate)fnis_trait(&self) -> bool{
510-
self.type_() == ItemType::Trait
511-
}
512509
pub(crate)fnis_struct(&self) -> bool{
513510
self.type_() == ItemType::Struct
514511
}
@@ -536,9 +533,6 @@ impl Item {
536533
pub(crate)fnis_ty_method(&self) -> bool{
537534
self.type_() == ItemType::TyMethod
538535
}
539-
pub(crate)fnis_type_alias(&self) -> bool{
540-
self.type_() == ItemType::TypeAlias
541-
}
542536
pub(crate)fnis_primitive(&self) -> bool{
543537
self.type_() == ItemType::Primitive
544538
}

‎src/librustdoc/html/markdown.rs‎

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use crate::html::format::Buffer;
5555
usecrate::html::highlight;
5656
usecrate::html::length_limit::HtmlWithLimit;
5757
usecrate::html::render::small_url_encode;
58-
usecrate::html::toc::TocBuilder;
58+
usecrate::html::toc::{Toc,TocBuilder};
5959

6060
#[cfg(test)]
6161
mod tests;
@@ -101,6 +101,7 @@ pub struct Markdown<'a> {
101101
/// A struct like `Markdown` that renders the markdown with a table of contents.
102102
pub(crate)structMarkdownWithToc<'a>{
103103
pub(crate)content:&'astr,
104+
pub(crate)links:&'a[RenderedLink],
104105
pub(crate)ids:&'amutIdMap,
105106
pub(crate)error_codes:ErrorCodes,
106107
pub(crate)edition:Edition,
@@ -532,9 +533,9 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
532533
let id = self.id_map.derive(id);
533534

534535
ifletSome(refmut builder) = self.toc{
535-
letmuthtml_header = String::new();
536-
html::push_html(&mut html_header,self.buf.iter().map(|(ev, _)| ev.clone()));
537-
let sec = builder.push(level asu32,html_header, id.clone());
536+
letmuttext_header = String::new();
537+
plain_text_from_events(self.buf.iter().map(|(ev, _)| ev.clone()),&mut text_header);
538+
let sec = builder.push(level asu32,text_header, id.clone());
538539
self.buf.push_front((Event::Html(format!("{sec} ").into()),0..0));
539540
}
540541

@@ -1415,10 +1416,23 @@ impl Markdown<'_> {
14151416
}
14161417

14171418
implMarkdownWithToc<'_>{
1418-
pub(crate)fninto_string(self) -> String{
1419-
letMarkdownWithToc{content: md, ids,error_codes: codes, edition, playground } = self;
1419+
pub(crate)fninto_parts(self) -> (Toc,String){
1420+
letMarkdownWithToc{content: md, links, ids,error_codes: codes, edition, playground } =
1421+
self;
14201422

1421-
let p = Parser::new_ext(md,main_body_opts()).into_offset_iter();
1423+
// This is actually common enough to special-case
1424+
if md.is_empty(){
1425+
return(Toc{entries:Vec::new()},String::new());
1426+
}
1427+
letmut replacer = |broken_link:BrokenLink<'_>| {
1428+
links
1429+
.iter()
1430+
.find(|link| &*link.original_text == &*broken_link.reference)
1431+
.map(|link| (link.href.as_str().into(), link.tooltip.as_str().into()))
1432+
};
1433+
1434+
let p = Parser::new_with_broken_link_callback(md,main_body_opts(),Some(&mut replacer));
1435+
let p = p.into_offset_iter();
14221436

14231437
letmut s = String::with_capacity(md.len()*3 / 2);
14241438

@@ -1432,7 +1446,11 @@ impl MarkdownWithToc<'_> {
14321446
html::push_html(&mut s, p);
14331447
}
14341448

1435-
format!("<nav id=\"TOC\">{toc}</nav>{s}", toc = toc.into_toc().print())
1449+
(toc.into_toc(), s)
1450+
}
1451+
pub(crate)fninto_string(self) -> String{
1452+
let(toc, s) = self.into_parts();
1453+
format!("<nav id=\"TOC\">{toc}</nav>{s}", toc = toc.print())
14361454
}
14371455
}
14381456

@@ -1611,7 +1629,16 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16111629

16121630
let p = Parser::new_with_broken_link_callback(md,summary_opts(),Some(&mut replacer));
16131631

1614-
for event in p {
1632+
plain_text_from_events(p,&mut s);
1633+
1634+
s
1635+
}
1636+
1637+
pub(crate)fnplain_text_from_events<'a>(
1638+
events:implIterator<Item = pulldown_cmark::Event<'a>>,
1639+
s:&mutString,
1640+
){
1641+
for event in events {
16151642
match&event {
16161643
Event::Text(text) => s.push_str(text),
16171644
Event::Code(code) => {
@@ -1626,8 +1653,6 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16261653
_ => (),
16271654
}
16281655
}
1629-
1630-
s
16311656
}
16321657

16331658
#[derive(Debug)]

‎src/librustdoc/html/render/context.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,8 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
616616
let all = shared.all.replace(AllTypes::new());
617617
letmut sidebar = Buffer::html();
618618

619-
let blocks = sidebar_module_like(all.item_sections());
619+
// all.html is not customizable, so a blank id map is fine
620+
let blocks = sidebar_module_like(all.item_sections(),&mutIdMap::new());
620621
let bar = Sidebar{
621622
title_prefix:"",
622623
title:"",

0 commit comments

Comments
 (0)