Skip to content

Commit a77247a

Browse files
Move source HTML generation to own module
1 parent 9b91b9c commit a77247a

File tree

3 files changed

+194
-173
lines changed

3 files changed

+194
-173
lines changed

src/librustdoc/html/render.rs

Lines changed: 6 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ use crate::html::format::fmt_impl_for_trait_page;
7272
use crate::html::item_type::ItemType;
7373
use crate::html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
7474
use crate::html::{highlight, layout, static_files};
75+
use crate::html::sources;
7576

7677
use minifier;
7778

@@ -173,7 +174,7 @@ struct Context {
173174
playground: Option<markdown::Playground>,
174175
}
175176

176-
struct SharedContext {
177+
crate struct SharedContext {
177178
/// The path to the crate root source minus the file name.
178179
/// Used for simplifying paths to the highlighted source code files.
179180
pub src_root: PathBuf,
@@ -218,7 +219,7 @@ struct SharedContext {
218219
}
219220

220221
impl SharedContext {
221-
fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
222+
crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
222223
let mut dirs = self.created_dirs.borrow_mut();
223224
if !dirs.contains(dst) {
224225
try_err!(self.fs.create_dir_all(dst), dst);
@@ -389,18 +390,6 @@ pub struct RenderInfo {
389390
pub owned_box_did: Option<DefId>,
390391
}
391392

392-
/// Helper struct to render all source code to HTML pages
393-
struct SourceCollector<'a> {
394-
scx: &'a mut SharedContext,
395-
396-
/// Root destination to place all HTML output into
397-
dst: PathBuf,
398-
}
399-
400-
/// Wrapper struct to render the source code of a file. This will do things like
401-
/// adding line numbers to the left-hand side.
402-
struct Source<'a>(&'a str);
403-
404393
// Helper structs for rendering items/sidebars and carrying along contextual
405394
// information
406395

@@ -612,7 +601,7 @@ pub fn run(mut krate: clean::Crate,
612601
}
613602
let dst = output;
614603
scx.ensure_dir(&dst)?;
615-
krate = render_sources(&dst, &mut scx, krate)?;
604+
krate = sources::render(&dst, &mut scx, krate)?;
616605
let mut cx = Context {
617606
current: Vec::new(),
618607
dst,
@@ -1293,18 +1282,6 @@ themePicker.onblur = handleThemeButtonsBlur;
12931282
Ok(())
12941283
}
12951284

1296-
fn render_sources(dst: &Path, scx: &mut SharedContext,
1297-
krate: clean::Crate) -> Result<clean::Crate, Error> {
1298-
info!("emitting source files");
1299-
let dst = dst.join("src").join(&krate.name);
1300-
scx.ensure_dir(&dst)?;
1301-
let mut folder = SourceCollector {
1302-
dst,
1303-
scx,
1304-
};
1305-
Ok(folder.fold_crate(krate))
1306-
}
1307-
13081285
fn write_minify(fs:&DocFS, dst: PathBuf, contents: &str, enable_minification: bool
13091286
) -> Result<(), Error> {
13101287
if enable_minification {
@@ -1384,33 +1361,6 @@ fn write_minify_replacer<W: Write>(
13841361
}
13851362
}
13861363

1387-
/// Takes a path to a source file and cleans the path to it. This canonicalizes
1388-
/// things like ".." to components which preserve the "top down" hierarchy of a
1389-
/// static HTML tree. Each component in the cleaned path will be passed as an
1390-
/// argument to `f`. The very last component of the path (ie the file name) will
1391-
/// be passed to `f` if `keep_filename` is true, and ignored otherwise.
1392-
fn clean_srcpath<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
1393-
where
1394-
F: FnMut(&OsStr),
1395-
{
1396-
// make it relative, if possible
1397-
let p = p.strip_prefix(src_root).unwrap_or(p);
1398-
1399-
let mut iter = p.components().peekable();
1400-
1401-
while let Some(c) = iter.next() {
1402-
if !keep_filename && iter.peek().is_none() {
1403-
break;
1404-
}
1405-
1406-
match c {
1407-
Component::ParentDir => f("up".as_ref()),
1408-
Component::Normal(c) => f(c),
1409-
_ => continue,
1410-
}
1411-
}
1412-
}
1413-
14141364
/// Attempts to find where an external crate is located, given that we're
14151365
/// rendering in to the specified source destination.
14161366
fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Path)
@@ -1444,102 +1394,6 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat
14441394
}).next().unwrap_or(Unknown) // Well, at least we tried.
14451395
}
14461396

1447-
impl<'a> DocFolder for SourceCollector<'a> {
1448-
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
1449-
// If we're including source files, and we haven't seen this file yet,
1450-
// then we need to render it out to the filesystem.
1451-
if self.scx.include_sources
1452-
// skip all invalid or macro spans
1453-
&& item.source.filename.is_real()
1454-
// skip non-local items
1455-
&& item.def_id.is_local() {
1456-
1457-
// If it turns out that we couldn't read this file, then we probably
1458-
// can't read any of the files (generating html output from json or
1459-
// something like that), so just don't include sources for the
1460-
// entire crate. The other option is maintaining this mapping on a
1461-
// per-file basis, but that's probably not worth it...
1462-
self.scx
1463-
.include_sources = match self.emit_source(&item.source.filename) {
1464-
Ok(()) => true,
1465-
Err(e) => {
1466-
println!("warning: source code was requested to be rendered, \
1467-
but processing `{}` had an error: {}",
1468-
item.source.filename, e);
1469-
println!(" skipping rendering of source code");
1470-
false
1471-
}
1472-
};
1473-
}
1474-
self.fold_item_recur(item)
1475-
}
1476-
}
1477-
1478-
impl<'a> SourceCollector<'a> {
1479-
/// Renders the given filename into its corresponding HTML source file.
1480-
fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
1481-
let p = match *filename {
1482-
FileName::Real(ref file) => file,
1483-
_ => return Ok(()),
1484-
};
1485-
if self.scx.local_sources.contains_key(&**p) {
1486-
// We've already emitted this source
1487-
return Ok(());
1488-
}
1489-
1490-
let contents = try_err!(fs::read_to_string(&p), &p);
1491-
1492-
// Remove the utf-8 BOM if any
1493-
let contents = if contents.starts_with("\u{feff}") {
1494-
&contents[3..]
1495-
} else {
1496-
&contents[..]
1497-
};
1498-
1499-
// Create the intermediate directories
1500-
let mut cur = self.dst.clone();
1501-
let mut root_path = String::from("../../");
1502-
let mut href = String::new();
1503-
clean_srcpath(&self.scx.src_root, &p, false, |component| {
1504-
cur.push(component);
1505-
root_path.push_str("../");
1506-
href.push_str(&component.to_string_lossy());
1507-
href.push('/');
1508-
});
1509-
self.scx.ensure_dir(&cur)?;
1510-
let mut fname = p.file_name()
1511-
.expect("source has no filename")
1512-
.to_os_string();
1513-
fname.push(".html");
1514-
cur.push(&fname);
1515-
href.push_str(&fname.to_string_lossy());
1516-
1517-
let mut v = Vec::new();
1518-
let title = format!("{} -- source", cur.file_name().expect("failed to get file name")
1519-
.to_string_lossy());
1520-
let desc = format!("Source to the Rust file `{}`.", filename);
1521-
let page = layout::Page {
1522-
title: &title,
1523-
css_class: "source",
1524-
root_path: &root_path,
1525-
static_root_path: self.scx.static_root_path.as_deref(),
1526-
description: &desc,
1527-
keywords: BASIC_KEYWORDS,
1528-
resource_suffix: &self.scx.resource_suffix,
1529-
extra_scripts: &[&format!("source-files{}", self.scx.resource_suffix)],
1530-
static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
1531-
};
1532-
try_err!(layout::render(&mut v, &self.scx.layout,
1533-
&page, &(""), &Source(contents),
1534-
self.scx.css_file_extension.is_some(),
1535-
&self.scx.themes,
1536-
self.scx.generate_search_filter), &cur);
1537-
self.scx.fs.write(&cur, &v)?;
1538-
self.scx.local_sources.insert(p.clone(), href);
1539-
Ok(())
1540-
}
1541-
}
1542-
15431397
impl DocFolder for Cache {
15441398
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
15451399
if item.def_id.is_local() {
@@ -2399,7 +2253,7 @@ impl<'a> Item<'a> {
23992253
(_, _, Unknown) => return None,
24002254
};
24012255

2402-
clean_srcpath(&src_root, file, false, |component| {
2256+
sources::clean_path(&src_root, file, false, |component| {
24032257
path.push_str(&component.to_string_lossy());
24042258
path.push('/');
24052259
});
@@ -5048,27 +4902,6 @@ fn sidebar_foreign_type(fmt: &mut fmt::Formatter<'_>, it: &clean::Item) -> fmt::
50484902
Ok(())
50494903
}
50504904

5051-
impl<'a> fmt::Display for Source<'a> {
5052-
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
5053-
let Source(s) = *self;
5054-
let lines = s.lines().count();
5055-
let mut cols = 0;
5056-
let mut tmp = lines;
5057-
while tmp > 0 {
5058-
cols += 1;
5059-
tmp /= 10;
5060-
}
5061-
write!(fmt, "<pre class=\"line-numbers\">")?;
5062-
for i in 1..=lines {
5063-
write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
5064-
}
5065-
write!(fmt, "</pre>")?;
5066-
write!(fmt, "{}",
5067-
highlight::render_with_highlighting(s, None, None, None))?;
5068-
Ok(())
5069-
}
5070-
}
5071-
50724905
fn item_macro(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
50734906
t: &clean::Macro) -> fmt::Result {
50744907
wrap_into_docblock(w, |w| {
@@ -5125,7 +4958,7 @@ fn item_keyword(w: &mut fmt::Formatter<'_>, cx: &Context,
51254958
document(w, cx, it)
51264959
}
51274960

5128-
const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
4961+
crate const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
51294962

51304963
fn make_item_keywords(it: &clean::Item) -> String {
51314964
format!("{}, {}", BASIC_KEYWORDS, it.name.as_ref().unwrap())

0 commit comments

Comments
 (0)