Inject fonts into css
This commit is contained in:
parent
ec0746011e
commit
0b8717aa2b
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -135,6 +135,12 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@ -624,8 +630,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "grass"
|
name = "grass"
|
||||||
version = "0.13.4"
|
version = "0.13.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://git.shadowfacts.net/shadowfacts/grass.git?branch=custom-global-variables#e64e648b6174d23b6d4a8ad674eb443dc6fcbdff"
|
||||||
checksum = "f7a68216437ef68f0738e48d6c7bb9e6e6a92237e001b03d838314b068f33c94"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"grass_compiler",
|
"grass_compiler",
|
||||||
@ -634,14 +639,14 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "grass_compiler"
|
name = "grass_compiler"
|
||||||
version = "0.13.4"
|
version = "0.13.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://git.shadowfacts.net/shadowfacts/grass.git?branch=custom-global-variables#e64e648b6174d23b6d4a8ad674eb443dc6fcbdff"
|
||||||
checksum = "2d9e3df7f0222ce5184154973d247c591d9aadc28ce7a73c6cd31100c9facff6"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"codemap",
|
"codemap",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"lasso",
|
"lasso",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"phf",
|
"phf",
|
||||||
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1891,6 +1896,7 @@ name = "v7"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"compute_graph",
|
"compute_graph",
|
||||||
@ -1898,6 +1904,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
"grass",
|
"grass",
|
||||||
|
"grass_compiler",
|
||||||
"html5ever",
|
"html5ever",
|
||||||
"log",
|
"log",
|
||||||
"markup5ever_rcdom",
|
"markup5ever_rcdom",
|
||||||
|
@ -17,13 +17,17 @@ serde_json = "1.0"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.95"
|
anyhow = "1.0.95"
|
||||||
|
base64 = "0.22.1"
|
||||||
chrono = { version = "0.4.39", features = ["serde"] }
|
chrono = { version = "0.4.39", features = ["serde"] }
|
||||||
clap = { version = "4.5.23", features = ["cargo"] }
|
clap = { version = "4.5.23", features = ["cargo"] }
|
||||||
compute_graph = { path = "crates/compute_graph" }
|
compute_graph = { path = "crates/compute_graph" }
|
||||||
debounced = "0.2.0"
|
debounced = "0.2.0"
|
||||||
env_logger = "0.11.6"
|
env_logger = "0.11.6"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
grass = { version = "0.13.4", default-features = false }
|
grass = { version = "0.13.4", default-features = false, git = "https://git.shadowfacts.net/shadowfacts/grass.git", branch = "custom-global-variables" }
|
||||||
|
grass_compiler = { version = "0.13.4", features = [
|
||||||
|
"custom-builtin-fns",
|
||||||
|
], git = "https://git.shadowfacts.net/shadowfacts/grass.git", branch = "custom-global-variables" }
|
||||||
html5ever = "0.27.0"
|
html5ever = "0.27.0"
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
markup5ever_rcdom = "0.3.0"
|
markup5ever_rcdom = "0.3.0"
|
||||||
|
@ -1,5 +1,35 @@
|
|||||||
.foo {
|
@font-face {
|
||||||
.bar {
|
font-family: "Equity A";
|
||||||
color: red;
|
font-style: normal;
|
||||||
}
|
font-weight: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-display: auto;
|
||||||
|
src: url("data:font/woff2;base64," + $equity-a-regular) format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Equity A";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-display: auto;
|
||||||
|
src: url("data:font/woff2;base64," + $equity-a-italic) format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Equity A";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-display: auto;
|
||||||
|
src: url("data:font/woff2;base64," + $equity-a-bold) format("woff2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Equity A";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: bold;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-display: auto;
|
||||||
|
src: url("data:font/woff2;base64," + $equity-a-bold-italic) format("woff2");
|
||||||
}
|
}
|
||||||
|
BIN
site_test/fonts/equity-a-bold-italic.woff2
Normal file
BIN
site_test/fonts/equity-a-bold-italic.woff2
Normal file
Binary file not shown.
BIN
site_test/fonts/equity-a-bold.woff2
Normal file
BIN
site_test/fonts/equity-a-bold.woff2
Normal file
Binary file not shown.
BIN
site_test/fonts/equity-a-italic.woff2
Normal file
BIN
site_test/fonts/equity-a-italic.woff2
Normal file
Binary file not shown.
BIN
site_test/fonts/equity-a-regular.woff2
Normal file
BIN
site_test/fonts/equity-a-regular.woff2
Normal file
Binary file not shown.
@ -1,5 +1,12 @@
|
|||||||
use std::{cell::RefCell, collections::HashSet, io::Write, path::PathBuf, rc::Rc};
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
io::Write,
|
||||||
|
path::PathBuf,
|
||||||
|
rc::Rc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use base64::{Engine, prelude::BASE64_STANDARD};
|
||||||
use compute_graph::{
|
use compute_graph::{
|
||||||
InvalidationSignal,
|
InvalidationSignal,
|
||||||
builder::GraphBuilder,
|
builder::GraphBuilder,
|
||||||
@ -7,6 +14,7 @@ use compute_graph::{
|
|||||||
synchronicity::Asynchronous,
|
synchronicity::Asynchronous,
|
||||||
};
|
};
|
||||||
use grass::{Fs, Options, OutputStyle};
|
use grass::{Fs, Options, OutputStyle};
|
||||||
|
use grass_compiler::sass_value::{QuoteKind, Value};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -18,21 +26,55 @@ pub fn make_graph(
|
|||||||
builder: &mut GraphBuilder<(), Asynchronous>,
|
builder: &mut GraphBuilder<(), Asynchronous>,
|
||||||
watcher: Rc<RefCell<FileWatcher>>,
|
watcher: Rc<RefCell<FileWatcher>>,
|
||||||
) -> Input<()> {
|
) -> Input<()> {
|
||||||
|
let mut watcher_ = watcher.borrow_mut();
|
||||||
|
let mut fonts = HashMap::<&'static str, Input<String>>::new();
|
||||||
|
let filenames: &[&str] = &[
|
||||||
|
"equity-a-regular",
|
||||||
|
"equity-a-bold",
|
||||||
|
"equity-a-italic",
|
||||||
|
"equity-a-bold-italic",
|
||||||
|
];
|
||||||
|
for name in filenames {
|
||||||
|
fonts.insert(name, read_font(name, builder, &mut *watcher_));
|
||||||
|
}
|
||||||
|
drop(watcher_);
|
||||||
|
|
||||||
let invalidate_css_box = Rc::new(RefCell::new(None));
|
let invalidate_css_box = Rc::new(RefCell::new(None));
|
||||||
let (css, invalidate_css) = builder.add_invalidatable_rule(CompileScss {
|
let (css, invalidate_css) = builder.add_invalidatable_rule(CompileScss {
|
||||||
watcher,
|
watcher,
|
||||||
watched: HashSet::new(),
|
watched: HashSet::new(),
|
||||||
invalidate: Rc::clone(&invalidate_css_box),
|
invalidate: Rc::clone(&invalidate_css_box),
|
||||||
|
fonts,
|
||||||
});
|
});
|
||||||
invalidate_css_box.replace(Some(invalidate_css));
|
invalidate_css_box.replace(Some(invalidate_css));
|
||||||
css
|
css
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(InputVisitable)]
|
fn read_font(
|
||||||
|
name: &'static str,
|
||||||
|
builder: &mut GraphBuilder<(), Asynchronous>,
|
||||||
|
watcher: &mut FileWatcher,
|
||||||
|
) -> Input<String> {
|
||||||
|
let mut path = content_path("fonts");
|
||||||
|
path.push(name);
|
||||||
|
path.set_extension("woff2");
|
||||||
|
let (font, invalidate) = builder.add_invalidatable_rule(ReadFont(path.clone()));
|
||||||
|
watcher.watch(path, move || invalidate.invalidate());
|
||||||
|
font
|
||||||
|
}
|
||||||
|
|
||||||
struct CompileScss {
|
struct CompileScss {
|
||||||
watcher: Rc<RefCell<FileWatcher>>,
|
watcher: Rc<RefCell<FileWatcher>>,
|
||||||
watched: HashSet<PathBuf>,
|
watched: HashSet<PathBuf>,
|
||||||
invalidate: Rc<RefCell<Option<InvalidationSignal>>>,
|
invalidate: Rc<RefCell<Option<InvalidationSignal>>>,
|
||||||
|
fonts: HashMap<&'static str, Input<String>>,
|
||||||
|
}
|
||||||
|
impl InputVisitable for CompileScss {
|
||||||
|
fn visit_inputs(&self, visitor: &mut impl compute_graph::rule::InputVisitor) {
|
||||||
|
for input in self.fonts.values() {
|
||||||
|
visitor.visit(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl Rule for CompileScss {
|
impl Rule for CompileScss {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
@ -44,8 +86,14 @@ impl Rule for CompileScss {
|
|||||||
} else {
|
} else {
|
||||||
OutputStyle::Compressed
|
OutputStyle::Compressed
|
||||||
};
|
};
|
||||||
let options = Options::default().fs(&fs).style(style);
|
let mut options = Options::default().fs(&fs).style(style);
|
||||||
|
for (name, input) in self.fonts.iter() {
|
||||||
|
let value = Value::String(input.value().to_owned(), QuoteKind::None);
|
||||||
|
options = options.add_custom_var(*name, value);
|
||||||
|
}
|
||||||
|
|
||||||
let result = grass::from_path(content_path("css/main.scss"), &options);
|
let result = grass::from_path(content_path("css/main.scss"), &options);
|
||||||
|
|
||||||
let mut watcher = self.watcher.borrow_mut();
|
let mut watcher = self.watcher.borrow_mut();
|
||||||
for file in read_files.take() {
|
for file in read_files.take() {
|
||||||
if !self.watched.contains(&file) {
|
if !self.watched.contains(&file) {
|
||||||
@ -54,6 +102,7 @@ impl Rule for CompileScss {
|
|||||||
watcher.watch(file, move || signal.invalidate());
|
watcher.watch(file, move || signal.invalidate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
output_writer("css/main.css")
|
output_writer("css/main.css")
|
||||||
@ -88,3 +137,18 @@ impl<'a> Fs for TrackingFs<'a> {
|
|||||||
std::fs::canonicalize(path)
|
std::fs::canonicalize(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(InputVisitable)]
|
||||||
|
struct ReadFont(PathBuf);
|
||||||
|
impl Rule for ReadFont {
|
||||||
|
type Output = String;
|
||||||
|
fn evaluate(&mut self) -> Self::Output {
|
||||||
|
match std::fs::read(&self.0) {
|
||||||
|
Ok(data) => BASE64_STANDARD.encode(data),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error reading font {:?}: {:?}", &self.0, e);
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user