Skip to content

Commit 26b7738

Browse files
Automatically generate the correct static file names in rustdoc.css
1 parent a9985cf commit 26b7738

File tree

3 files changed

+67
-33
lines changed

3 files changed

+67
-33
lines changed

src/librustdoc/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ impl Options {
417417
let to_check = matches.opt_strs("check-theme");
418418
if !to_check.is_empty() {
419419
let paths = match theme::load_css_paths(
420-
std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
420+
std::str::from_utf8(&static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
421421
) {
422422
Ok(p) => p,
423423
Err(e) => {
@@ -560,7 +560,7 @@ impl Options {
560560
let mut themes = Vec::new();
561561
if matches.opt_present("theme") {
562562
let paths = match theme::load_css_paths(
563-
std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
563+
std::str::from_utf8(&static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
564564
) {
565565
Ok(p) => p,
566566
Err(e) => {

src/librustdoc/html/static/css/rustdoc.css

+9-17
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
/* When static files are updated, their suffixes need to be updated.
2-
1. In the top directory run:
3-
./x.py doc --stage 1 library/core
4-
2. Find the directory containing files named with updated suffixes:
5-
find build -path '*'/stage1-std/'*'/static.files
6-
3. Copy the filenames with updated suffixes from the directory.
7-
*/
8-
91
/* See FiraSans-LICENSE.txt for the Fira Sans license. */
102
@font-face {
113
font-family: 'Fira Sans';
124
font-style: normal;
135
font-weight: 400;
146
src: local('Fira Sans'),
15-
url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");
7+
url("/* REPLACE FiraSans-Regular.woff2 */") format("woff2");
168
font-display: swap;
179
}
1810
@font-face {
1911
font-family: 'Fira Sans';
2012
font-style: normal;
2113
font-weight: 500;
2214
src: local('Fira Sans Medium'),
23-
url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");
15+
url("/* REPLACE FiraSans-Medium.woff2 */") format("woff2");
2416
font-display: swap;
2517
}
2618

@@ -30,23 +22,23 @@
3022
font-style: normal;
3123
font-weight: 400;
3224
src: local('Source Serif 4'),
33-
url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");
25+
url("/* REPLACE SourceSerif4-Regular.ttf.woff2 */") format("woff2");
3426
font-display: swap;
3527
}
3628
@font-face {
3729
font-family: 'Source Serif 4';
3830
font-style: italic;
3931
font-weight: 400;
4032
src: local('Source Serif 4 Italic'),
41-
url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");
33+
url("/* REPLACE SourceSerif4-It.ttf.woff2 */") format("woff2");
4234
font-display: swap;
4335
}
4436
@font-face {
4537
font-family: 'Source Serif 4';
4638
font-style: normal;
4739
font-weight: 700;
4840
src: local('Source Serif 4 Bold'),
49-
url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");
41+
url("/* REPLACE SourceSerif4-Bold.ttf.woff2 */") format("woff2");
5042
font-display: swap;
5143
}
5244

@@ -57,28 +49,28 @@
5749
font-weight: 400;
5850
/* Avoid using locally installed font because bad versions are in circulation:
5951
* see https://github.com/rust-lang/rust/issues/24355 */
60-
src: url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");
52+
src: url("/* REPLACE SourceCodePro-Regular.ttf.woff2 */") format("woff2");
6153
font-display: swap;
6254
}
6355
@font-face {
6456
font-family: 'Source Code Pro';
6557
font-style: italic;
6658
font-weight: 400;
67-
src: url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");
59+
src: url("/* REPLACE SourceCodePro-It.ttf.woff2 */") format("woff2");
6860
font-display: swap;
6961
}
7062
@font-face {
7163
font-family: 'Source Code Pro';
7264
font-style: normal;
7365
font-weight: 600;
74-
src: url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");
66+
src: url("/* REPLACE SourceCodePro-Semibold.ttf.woff2 */") format("woff2");
7567
font-display: swap;
7668
}
7769

7870
/* Avoid using legacy CJK serif fonts in Windows like Batang. */
7971
@font-face {
8072
font-family: 'NanumBarunGothic';
81-
src: url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");
73+
src: url("/* REPLACE NanumBarunGothic.ttf.woff2 */") format("woff2");
8274
font-display: swap;
8375
unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF;
8476
}

src/librustdoc/html/static_files.rs

+56-14
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,49 @@
33
//! All the static files are included here for centralized access in case anything other than the
44
//! HTML rendering code (say, the theme checker) needs to access one of these files.
55
6-
use rustc_data_structures::fx::FxHasher;
6+
use rustc_data_structures::fx::{FxHashMap, FxHasher};
7+
use std::borrow::Cow;
78
use std::hash::Hasher;
89
use std::path::{Path, PathBuf};
910
use std::{fmt, str};
1011

1112
pub(crate) struct StaticFile {
1213
pub(crate) filename: PathBuf,
13-
pub(crate) bytes: &'static [u8],
14+
pub(crate) bytes: Cow<'static, [u8]>,
1415
}
1516

1617
impl StaticFile {
17-
fn new(filename: &str, bytes: &'static [u8]) -> StaticFile {
18-
Self { filename: static_filename(filename, bytes), bytes }
18+
fn new(
19+
filename: &str,
20+
bytes: &'static [u8],
21+
file_map: &mut FxHashMap<String, String>,
22+
) -> StaticFile {
23+
// For now, only `rustdoc.css` style file needs this mechanism but it can be extended
24+
// pretty easily by changing this condition.
25+
if filename.ends_with("/rustdoc.css") {
26+
let bytes = replace_static_files_include(bytes, file_map);
27+
Self { filename: static_filename(filename, &bytes), bytes: Cow::Owned(bytes) }
28+
} else {
29+
let ret =
30+
Self { filename: static_filename(filename, bytes), bytes: Cow::Borrowed(bytes) };
31+
let filename = Path::new(filename).file_name().unwrap().to_str().unwrap().to_string();
32+
file_map
33+
.insert(filename, ret.filename.file_name().unwrap().to_str().unwrap().to_string());
34+
ret
35+
}
1936
}
2037

2138
pub(crate) fn minified(&self) -> Vec<u8> {
2239
let extension = match self.filename.extension() {
2340
Some(e) => e,
24-
None => return self.bytes.to_owned(),
41+
None => return self.bytes.to_vec(),
2542
};
2643
if extension == "css" {
27-
minifier::css::minify(str::from_utf8(self.bytes).unwrap()).unwrap().to_string().into()
44+
minifier::css::minify(str::from_utf8(&self.bytes).unwrap()).unwrap().to_string().into()
2845
} else if extension == "js" {
29-
minifier::js::minify(str::from_utf8(self.bytes).unwrap()).to_string().into()
46+
minifier::js::minify(str::from_utf8(&self.bytes).unwrap()).to_string().into()
3047
} else {
31-
self.bytes.to_owned()
48+
self.bytes.to_vec()
3249
}
3350
}
3451

@@ -45,6 +62,26 @@ impl fmt::Display for StaticFile {
4562
}
4663
}
4764

65+
/// This function goes through the CSS content and replaces all content wrapped between:
66+
/// `/* REPLACE {content} */` (where `{content}` is what will be replaced.)
67+
fn replace_static_files_include(bytes: &[u8], file_map: &FxHashMap<String, String>) -> Vec<u8> {
68+
let bytes = str::from_utf8(bytes).unwrap();
69+
let mut it = bytes.split("/* REPLACE ");
70+
let mut content = String::with_capacity(bytes.len());
71+
while let Some(entry) = it.next() {
72+
if content.is_empty() {
73+
content.push_str(entry);
74+
continue;
75+
}
76+
let mut parts = entry.splitn(2, " */");
77+
let file = parts.next().unwrap();
78+
let rest = parts.next().unwrap();
79+
content.push_str(file_map.get(file).unwrap());
80+
content.push_str(rest);
81+
}
82+
content.into()
83+
}
84+
4885
/// Insert the provided suffix into a filename just before the extension.
4986
pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf {
5087
// We use splitn vs Path::extension here because we might get a filename
@@ -74,8 +111,11 @@ macro_rules! static_files {
74111
$(pub $field: StaticFile,)+
75112
}
76113

77-
pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| StaticFiles {
78-
$($field: StaticFile::new($file_path, include_bytes!($file_path)),)+
114+
pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| {
115+
let mut map = FxHashMap::default();
116+
StaticFiles {
117+
$($field: StaticFile::new($file_path, include_bytes!($file_path), &mut map),)+
118+
}
79119
});
80120

81121
pub(crate) fn for_each<E>(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<(), E> {
@@ -90,10 +130,6 @@ macro_rules! static_files {
90130
}
91131

92132
static_files! {
93-
rustdoc_css => "static/css/rustdoc.css",
94-
settings_css => "static/css/settings.css",
95-
noscript_css => "static/css/noscript.css",
96-
normalize_css => "static/css/normalize.css",
97133
main_js => "static/js/main.js",
98134
search_js => "static/js/search.js",
99135
settings_js => "static/js/settings.js",
@@ -125,6 +161,12 @@ static_files! {
125161
source_code_pro_license => "static/fonts/SourceCodePro-LICENSE.txt",
126162
nanum_barun_gothic_regular => "static/fonts/NanumBarunGothic.ttf.woff2",
127163
nanum_barun_gothic_license => "static/fonts/NanumBarunGothic-LICENSE.txt",
164+
// It's important for the CSS files to be the last since we need to replace some of their
165+
// content (the static file names).
166+
rustdoc_css => "static/css/rustdoc.css",
167+
settings_css => "static/css/settings.css",
168+
noscript_css => "static/css/noscript.css",
169+
normalize_css => "static/css/normalize.css",
128170
}
129171

130172
pub(crate) static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md");

0 commit comments

Comments
 (0)