Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically generate static file names #107565

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ impl Options {
let to_check = matches.opt_strs("check-theme");
if !to_check.is_empty() {
let paths = match theme::load_css_paths(
std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
std::str::from_utf8(&static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
) {
Ok(p) => p,
Err(e) => {
Expand Down Expand Up @@ -560,7 +560,7 @@ impl Options {
let mut themes = Vec::new();
if matches.opt_present("theme") {
let paths = match theme::load_css_paths(
std::str::from_utf8(static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
std::str::from_utf8(&static_files::STATIC_FILES.theme_light_css.bytes).unwrap(),
) {
Ok(p) => p,
Err(e) => {
Expand Down
26 changes: 9 additions & 17 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
/* When static files are updated, their suffixes need to be updated.
1. In the top directory run:
./x.py doc --stage 1 library/core
2. Find the directory containing files named with updated suffixes:
find build -path '*'/stage1-std/'*'/static.files
3. Copy the filenames with updated suffixes from the directory.
*/

/* See FiraSans-LICENSE.txt for the Fira Sans license. */
@font-face {
font-family: 'Fira Sans';
font-style: normal;
font-weight: 400;
src: local('Fira Sans'),
url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");
url("/* REPLACE FiraSans-Regular.woff2 */") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Fira Sans';
font-style: normal;
font-weight: 500;
src: local('Fira Sans Medium'),
url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");
url("/* REPLACE FiraSans-Medium.woff2 */") format("woff2");
font-display: swap;
}

Expand All @@ -30,23 +22,23 @@
font-style: normal;
font-weight: 400;
src: local('Source Serif 4'),
url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");
url("/* REPLACE SourceSerif4-Regular.ttf.woff2 */") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Serif 4';
font-style: italic;
font-weight: 400;
src: local('Source Serif 4 Italic'),
url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");
url("/* REPLACE SourceSerif4-It.ttf.woff2 */") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Serif 4';
font-style: normal;
font-weight: 700;
src: local('Source Serif 4 Bold'),
url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");
url("/* REPLACE SourceSerif4-Bold.ttf.woff2 */") format("woff2");
font-display: swap;
}

Expand All @@ -57,28 +49,28 @@
font-weight: 400;
/* Avoid using locally installed font because bad versions are in circulation:
* see https://github.com/rust-lang/rust/issues/24355 */
src: url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");
src: url("/* REPLACE SourceCodePro-Regular.ttf.woff2 */") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: italic;
font-weight: 400;
src: url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");
src: url("/* REPLACE SourceCodePro-It.ttf.woff2 */") format("woff2");
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 600;
src: url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");
src: url("/* REPLACE SourceCodePro-Semibold.ttf.woff2 */") format("woff2");
font-display: swap;
}

/* Avoid using legacy CJK serif fonts in Windows like Batang. */
@font-face {
font-family: 'NanumBarunGothic';
src: url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");
src: url("/* REPLACE NanumBarunGothic.ttf.woff2 */") format("woff2");
font-display: swap;
unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF;
}
Expand Down
70 changes: 56 additions & 14 deletions src/librustdoc/html/static_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,49 @@
//! All the static files are included here for centralized access in case anything other than the
//! HTML rendering code (say, the theme checker) needs to access one of these files.

use rustc_data_structures::fx::FxHasher;
use rustc_data_structures::fx::{FxHashMap, FxHasher};
use std::borrow::Cow;
use std::hash::Hasher;
use std::path::{Path, PathBuf};
use std::{fmt, str};

pub(crate) struct StaticFile {
pub(crate) filename: PathBuf,
pub(crate) bytes: &'static [u8],
pub(crate) bytes: Cow<'static, [u8]>,
}

impl StaticFile {
fn new(filename: &str, bytes: &'static [u8]) -> StaticFile {
Self { filename: static_filename(filename, bytes), bytes }
fn new(
filename: &str,
bytes: &'static [u8],
file_map: &mut FxHashMap<String, String>,
) -> StaticFile {
// For now, only `rustdoc.css` style file needs this mechanism but it can be extended
// pretty easily by changing this condition.
if filename.ends_with("/rustdoc.css") {
let bytes = replace_static_files_include(bytes, file_map);
Self { filename: static_filename(filename, &bytes), bytes: Cow::Owned(bytes) }
} else {
let ret =
Self { filename: static_filename(filename, bytes), bytes: Cow::Borrowed(bytes) };
let filename = Path::new(filename).file_name().unwrap().to_str().unwrap().to_string();
file_map
.insert(filename, ret.filename.file_name().unwrap().to_str().unwrap().to_string());
ret
}
}

pub(crate) fn minified(&self) -> Vec<u8> {
let extension = match self.filename.extension() {
Some(e) => e,
None => return self.bytes.to_owned(),
None => return self.bytes.to_vec(),
};
if extension == "css" {
minifier::css::minify(str::from_utf8(self.bytes).unwrap()).unwrap().to_string().into()
minifier::css::minify(str::from_utf8(&self.bytes).unwrap()).unwrap().to_string().into()
} else if extension == "js" {
minifier::js::minify(str::from_utf8(self.bytes).unwrap()).to_string().into()
minifier::js::minify(str::from_utf8(&self.bytes).unwrap()).to_string().into()
} else {
self.bytes.to_owned()
self.bytes.to_vec()
}
}

Expand All @@ -45,6 +62,26 @@ impl fmt::Display for StaticFile {
}
}

/// This function goes through the CSS content and replaces all content wrapped between:
/// `/* REPLACE {content} */` (where `{content}` is what will be replaced.)
fn replace_static_files_include(bytes: &[u8], file_map: &FxHashMap<String, String>) -> Vec<u8> {
let bytes = str::from_utf8(bytes).unwrap();
let mut it = bytes.split("/* REPLACE ");
let mut content = String::with_capacity(bytes.len());
while let Some(entry) = it.next() {
if content.is_empty() {
content.push_str(entry);
continue;
}
let mut parts = entry.splitn(2, " */");
let file = parts.next().unwrap();
let rest = parts.next().unwrap();
content.push_str(file_map.get(file).unwrap());
content.push_str(rest);
}
content.into()
}

/// Insert the provided suffix into a filename just before the extension.
pub(crate) fn suffix_path(filename: &str, suffix: &str) -> PathBuf {
// We use splitn vs Path::extension here because we might get a filename
Expand Down Expand Up @@ -74,8 +111,11 @@ macro_rules! static_files {
$(pub $field: StaticFile,)+
}

pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| StaticFiles {
$($field: StaticFile::new($file_path, include_bytes!($file_path)),)+
pub(crate) static STATIC_FILES: std::sync::LazyLock<StaticFiles> = std::sync::LazyLock::new(|| {
let mut map = FxHashMap::default();
StaticFiles {
$($field: StaticFile::new($file_path, include_bytes!($file_path), &mut map),)+
}
});

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

static_files! {
rustdoc_css => "static/css/rustdoc.css",
settings_css => "static/css/settings.css",
noscript_css => "static/css/noscript.css",
normalize_css => "static/css/normalize.css",
main_js => "static/js/main.js",
search_js => "static/js/search.js",
settings_js => "static/js/settings.js",
Expand Down Expand Up @@ -125,6 +161,12 @@ static_files! {
source_code_pro_license => "static/fonts/SourceCodePro-LICENSE.txt",
nanum_barun_gothic_regular => "static/fonts/NanumBarunGothic.ttf.woff2",
nanum_barun_gothic_license => "static/fonts/NanumBarunGothic-LICENSE.txt",
// It's important for the CSS files to be the last since we need to replace some of their
// content (the static file names).
rustdoc_css => "static/css/rustdoc.css",
settings_css => "static/css/settings.css",
noscript_css => "static/css/noscript.css",
normalize_css => "static/css/normalize.css",
}

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