Skip to content

Commit

Permalink
Automatically generate the correct static file names in rustdoc.css
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Feb 2, 2023
1 parent a9985cf commit 26b7738
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 33 deletions.
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");

0 comments on commit 26b7738

Please sign in to comment.