Skip to content

Commit 7a93800

Browse files
committed
Add template for print_item
Add print_item.html and the code in print_item.rs to use it.
1 parent f875143 commit 7a93800

File tree

4 files changed

+96
-46
lines changed

4 files changed

+96
-46
lines changed

src/librustdoc/html/render/context.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::formats::FormatRenderer;
3333
use crate::html::escape::Escape;
3434
use crate::html::format::Buffer;
3535
use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
36-
use crate::html::static_files::PAGE;
36+
use crate::html::static_files::{PAGE, PRINT_ITEM};
3737
use crate::html::{layout, sources};
3838

3939
/// Major driving force in all rustdoc rendering. This contains information
@@ -225,7 +225,7 @@ impl<'tcx> Context<'tcx> {
225225
&self.shared.layout,
226226
&page,
227227
|buf: &mut _| print_sidebar(self, it, buf),
228-
|buf: &mut _| print_item(self, it, buf, &page),
228+
|buf: &mut _| print_item(self, &self.shared.templates, it, buf, &page),
229229
&self.shared.style_files,
230230
)
231231
} else {
@@ -422,6 +422,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
422422
file: "page.html".into(),
423423
error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
424424
})?;
425+
templates.add_raw_template("print_item.html", PRINT_ITEM).map_err(|e| Error {
426+
file: "print_item.html".into(),
427+
error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
428+
})?;
425429

426430
// Crawl the crate attributes looking for attributes which control how we're
427431
// going to emit HTML

src/librustdoc/html/render/print_item.rs

+63-44
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,41 @@ use crate::html::highlight;
3232
use crate::html::layout::Page;
3333
use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
3434

35+
use serde::Serialize;
36+
3537
const ITEM_TABLE_OPEN: &'static str = "<div class=\"item-table\">";
3638
const ITEM_TABLE_CLOSE: &'static str = "</div>";
3739
const ITEM_TABLE_ROW_OPEN: &'static str = "<div class=\"item-row\">";
3840
const ITEM_TABLE_ROW_CLOSE: &'static str = "</div>";
3941

40-
pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
42+
// A component in a `use` path, like `string` in std::string::ToString
43+
#[derive(Serialize)]
44+
struct PathComponent<'a> {
45+
path: String,
46+
name: &'a str,
47+
}
48+
49+
#[derive(Serialize)]
50+
struct ItemVars<'a> {
51+
page: &'a Page<'a>,
52+
static_root_path: &'a str,
53+
typ: &'a str,
54+
name: &'a str,
55+
item_type: &'a str,
56+
path_components: Vec<PathComponent<'a>>,
57+
stability_since_raw: &'a str,
58+
src_href: Option<&'a str>,
59+
}
60+
61+
pub(super) fn print_item(
62+
cx: &Context<'_>,
63+
templates: &tera::Tera,
64+
item: &clean::Item,
65+
buf: &mut Buffer,
66+
page: &Page<'_>,
67+
) {
4168
debug_assert!(!item.is_stripped());
42-
// Write the breadcrumb trail header for the top
43-
buf.write_str("<h1 class=\"fqn\"><span class=\"in-band\">");
44-
let name = match *item.kind {
69+
let typ = match *item.kind {
4570
clean::ModuleItem(_) => {
4671
if item.is_crate() {
4772
"Crate "
@@ -73,60 +98,54 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
7398
unreachable!();
7499
}
75100
};
76-
buf.write_str(name);
77-
if !item.is_primitive() && !item.is_keyword() {
78-
let cur = &cx.current;
79-
let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
80-
for (i, component) in cur.iter().enumerate().take(amt) {
81-
write!(
82-
buf,
83-
"<a href=\"{}index.html\">{}</a>::<wbr>",
84-
"../".repeat(cur.len() - i - 1),
85-
component
86-
);
87-
}
88-
}
89-
write!(buf, "<a class=\"{}\" href=\"#\">{}</a>", item.type_(), item.name.as_ref().unwrap());
90-
write!(
91-
buf,
92-
"<button id=\"copy-path\" onclick=\"copy_path(this)\" title=\"Copy item path to clipboard\">\
93-
<img src=\"{static_root_path}clipboard{suffix}.svg\" \
94-
width=\"19\" height=\"18\" \
95-
alt=\"Copy item path\">\
96-
</button>",
97-
static_root_path = page.get_static_root_path(),
98-
suffix = page.resource_suffix,
99-
);
100-
101-
buf.write_str("</span>"); // in-band
102-
buf.write_str("<span class=\"out-of-band\">");
101+
let mut stability_since_raw = Buffer::new();
103102
render_stability_since_raw(
104-
buf,
103+
&mut stability_since_raw,
105104
item.stable_since(cx.tcx()).as_deref(),
106105
item.const_stability(cx.tcx()),
107106
None,
108107
None,
109108
);
110-
buf.write_str(
111-
"<span id=\"render-detail\">\
112-
<a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
113-
title=\"collapse all docs\">\
114-
[<span class=\"inner\">&#x2212;</span>]\
115-
</a>\
116-
</span>",
117-
);
109+
let stability_since_raw: String = stability_since_raw.into_inner();
118110

119111
// Write `src` tag
120112
//
121113
// When this item is part of a `crate use` in a downstream crate, the
122114
// [src] link in the downstream documentation will actually come back to
123115
// this page, and this link will be auto-clicked. The `id` attribute is
124116
// used to find the link to auto-click.
125-
if cx.include_sources && !item.is_primitive() {
126-
write_srclink(cx, item, buf);
127-
}
117+
let src_href =
118+
if cx.include_sources && !item.is_primitive() { cx.src_href(item) } else { None };
119+
120+
let path_components = if item.is_primitive() || item.is_keyword() {
121+
vec![]
122+
} else {
123+
let cur = &cx.current;
124+
let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
125+
cur.iter()
126+
.enumerate()
127+
.take(amt)
128+
.map(|(i, component)| PathComponent {
129+
path: "../".repeat(cur.len() - i - 1),
130+
name: component,
131+
})
132+
.collect()
133+
};
134+
135+
let item_vars = ItemVars {
136+
page: page,
137+
static_root_path: page.get_static_root_path(),
138+
typ: typ,
139+
name: &item.name.as_ref().unwrap().as_str(),
140+
item_type: &item.type_().to_string(),
141+
path_components: path_components,
142+
stability_since_raw: &stability_since_raw,
143+
src_href: src_href.as_deref(),
144+
};
128145

129-
buf.write_str("</span></h1>"); // out-of-band
146+
let teractx = tera::Context::from_serialize(item_vars).unwrap();
147+
let heading = templates.render("print_item.html", &teractx).unwrap();
148+
buf.write_str(&heading);
130149

131150
match *item.kind {
132151
clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),

src/librustdoc/html/static_files.rs

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-
7171
crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
7272

7373
crate static PAGE: &str = include_str!("templates/page.html");
74+
crate static PRINT_ITEM: &str = include_str!("templates/print_item.html");
7475

7576
/// The built-in themes given to every documentation site.
7677
crate mod themes {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<h1 class="fqn"> {#- -#}
2+
<span class="in-band"> {#- -#}
3+
{{-typ-}}
4+
{#- The breadcrumbs of the item path, like std::string -#}
5+
{%- for component in path_components -%}
6+
<a href="{{component.path | safe}}index.html">{{component.name}}</a>::<wbr>
7+
{%- endfor -%}
8+
<a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
9+
<button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
10+
<img src="{{static_root_path | safe}}clipboard{{page.resource_suffix}}.svg"
11+
width="19" height="18"
12+
alt="Copy item path">
13+
</button> {#- -#}
14+
</span> {#- -#}
15+
<span class="out-of-band"> {#- -#}
16+
{{- stability_since_raw | safe -}}
17+
<span id="render-detail"> {#- -#}
18+
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
19+
[<span class="inner">&#x2212;</span>] {#- -#}
20+
</a> {#- -#}
21+
</span> {#- -#}
22+
{%- if src_href -%}
23+
<a class="srclink" href="{{src_href | safe}}" title="goto source code">[src]</a>
24+
{%- endif -%}
25+
</span> {#- -#}
26+
</h1> {#- -#}

0 commit comments

Comments
 (0)