feat: Use typst as blog format. #24

Open
jackfiled wants to merge 2 commits from feat/typst into master
4 changed files with 533 additions and 17 deletions
Showing only changes of commit 9061092b64 - Show all commits

View File

@@ -17,6 +17,15 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.104" version = "1.0.104"
@@ -190,6 +199,17 @@ version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d1275808335c5583ea45a4141d631dafcb36b79fa8a5e10b00e356b6af3e08a" checksum = "0d1275808335c5583ea45a4141d631dafcb36b79fa8a5e10b00e356b6af3e08a"
[[package]]
name = "chrono"
version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [
"iana-time-zone",
"num-traits",
"windows-link",
]
[[package]] [[package]]
name = "ciborium" name = "ciborium"
version = "0.2.2" version = "0.2.2"
@@ -285,6 +305,12 @@ dependencies = [
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]] [[package]]
name = "core_maths" name = "core_maths"
version = "0.1.1" version = "0.1.1"
@@ -367,6 +393,27 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
[[package]]
name = "dirs"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys",
]
[[package]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.6" version = "0.2.6"
@@ -419,6 +466,16 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys",
]
[[package]] [[package]]
name = "euclid" name = "euclid"
version = "0.22.14" version = "0.22.14"
@@ -466,6 +523,16 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97b65636e5b9ef369943878ac74335ba1c55c1cb6adbf1e2c293c624248d693" checksum = "b97b65636e5b9ef369943878ac74335ba1c55c1cb6adbf1e2c293c624248d693"
[[package]]
name = "filetime"
version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759"
dependencies = [
"cfg-if",
"libc",
]
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.9"
@@ -531,6 +598,41 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "futures-core"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
[[package]]
name = "futures-task"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
[[package]]
name = "futures-util"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"slab",
]
[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "gif" name = "gif"
version = "0.14.2" version = "0.14.2"
@@ -731,6 +833,30 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef68590049bab63a464eee1a1158ac04c6f6613a546d8d90f78636b8b94f171" checksum = "bef68590049bab63a464eee1a1158ac04c6f6613a546d8d90f78636b8b94f171"
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "icu_collator" name = "icu_collator"
version = "2.2.1" version = "2.2.1"
@@ -979,6 +1105,17 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
version = "0.3.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
dependencies = [
"cfg-if",
"futures-util",
"wasm-bindgen",
]
[[package]] [[package]]
name = "kamadak-exif" name = "kamadak-exif"
version = "0.6.1" version = "0.6.1"
@@ -1012,6 +1149,15 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libredox"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "linebender_resource_handle" name = "linebender_resource_handle"
version = "0.1.1" version = "0.1.1"
@@ -1024,6 +1170,12 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]] [[package]]
name = "lipsum" name = "lipsum"
version = "0.9.1" version = "0.9.1"
@@ -1139,6 +1291,12 @@ version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]] [[package]]
name = "palette" name = "palette"
version = "0.7.6" version = "0.7.6"
@@ -1270,6 +1428,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-project-lite"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]] [[package]]
name = "plist" name = "plist"
version = "1.10.0" version = "1.10.0"
@@ -1476,6 +1640,17 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "redox_users"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.13.1" version = "1.13.1"
@@ -1536,6 +1711,25 @@ version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
[[package]]
name = "rustix"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
[[package]] [[package]]
name = "rustybuzz" name = "rustybuzz"
version = "0.20.1" version = "0.20.1"
@@ -1834,6 +2028,17 @@ dependencies = [
"yaml-rust", "yaml-rust",
] ]
[[package]]
name = "tar"
version = "0.4.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840"
dependencies = [
"filetime",
"libc",
"xattr",
]
[[package]] [[package]]
name = "thin-vec" name = "thin-vec"
version = "0.2.18" version = "0.2.18"
@@ -2073,12 +2278,18 @@ version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27ee52e27dfab0da5ac3d19e7e43a21fbc7ff83af9301119468bae89fa857a8b" checksum = "27ee52e27dfab0da5ac3d19e7e43a21fbc7ff83af9301119468bae89fa857a8b"
dependencies = [ dependencies = [
"chrono",
"dirs",
"ecow", "ecow",
"fastrand",
"flate2",
"once_cell", "once_cell",
"parking_lot", "parking_lot",
"rustc-hash", "rustc-hash",
"serde", "serde",
"serde_json", "serde_json",
"tar",
"typst-assets",
"typst-library", "typst-library",
"typst-syntax", "typst-syntax",
"typst-timing", "typst-timing",
@@ -2530,6 +2741,57 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasm-bindgen"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn 2.0.119",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
dependencies = [
"unicode-ident",
]
[[package]] [[package]]
name = "wasmi" name = "wasmi"
version = "1.1.0" version = "1.1.0"
@@ -2591,12 +2853,65 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]] [[package]]
name = "windows-link" name = "windows-link"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.61.2" version = "0.61.2"
@@ -2627,6 +2942,16 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
[[package]]
name = "xattr"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
dependencies = [
"libc",
"rustix",
]
[[package]] [[package]]
name = "xmlwriter" name = "xmlwriter"
version = "0.1.0" version = "0.1.0"
@@ -2640,6 +2965,7 @@ dependencies = [
"anyhow", "anyhow",
"libc", "libc",
"typst", "typst",
"typst-html",
"typst-kit", "typst-kit",
] ]

View File

@@ -10,4 +10,5 @@ crate-type = ["cdylib"]
anyhow = "1.0.104" anyhow = "1.0.104"
libc = "0.2.187" libc = "0.2.187"
typst = "0.15.1" typst = "0.15.1"
typst-kit = "0.15.1" typst-html = "0.15.1"
typst-kit = { version = "0.15.1", features = ["datetime", "system-packages", "embedded-fonts"]}

View File

@@ -1,17 +1,122 @@
mod ffi_utils; mod ffi_utils;
mod world; mod world;
use crate::ffi_utils::{ExternResult, extract_str, from_handler, into_handler, return_str};
use crate::world::SystemWorld;
use anyhow::anyhow;
use std::ffi::{c_char, c_void}; use std::ffi::{c_char, c_void};
use crate::ffi_utils::ExternResult; use std::path::PathBuf;
use std::str::FromStr;
use typst::diag::{EcoVec, SourceDiagnostic, Warned};
use typst_html::{HtmlDocument, HtmlOptions};
pub struct TypstCompiler { struct TypstCompiler {
world: SystemWorld,
}
impl TypstCompiler {
fn new(work_dir: &str) -> anyhow::Result<Self> {
let path = PathBuf::from_str(work_dir)?;
Ok(Self {
world: SystemWorld::new(path),
})
}
fn compile(&mut self, input: &str) -> anyhow::Result<String> {
self.world.set_current_file(input);
let Warned { output, warnings } = typst::compile::<HtmlDocument>(&mut self.world);
let document = match output {
Ok(d) => Ok(d),
Err(e) => Err(anyhow!(typst_to_err(e))),
}?;
let content = export_html(&document)?;
Ok(content)
}
}
fn typst_to_err(e: EcoVec<SourceDiagnostic>) -> String {
let mut message = String::new();
message.push_str("Failed to compile: \n");
for err in e {
message.push_str(format!(" - {} \n", err.message.as_str()).as_str());
}
message
}
fn export_html(document: &HtmlDocument) -> anyhow::Result<String> {
let options = HtmlOptions { pretty: false };
match typst_html::html(document, &options) {
Ok(o) => Ok(o),
Err(e) => Err(anyhow!(typst_to_err(e))),
}
}
fn create_compiler(work_dir: *const c_char) -> anyhow::Result<Box<TypstCompiler>> {
let work_dir = extract_str(work_dir)?;
let compiler = TypstCompiler::new(work_dir)?;
Ok(Box::new(compiler))
} }
pub extern "C" fn init_compiler(work_dir: *const c_char) -> ExternResult<*mut c_void> { pub extern "C" fn init_compiler(work_dir: *const c_char) -> ExternResult<*mut c_void> {
todo!() let compiler = create_compiler(work_dir);
let handler = compiler.map(into_handler);
ExternResult::from_result(handler)
} }
pub extern "C" fn typst_compile(handler: *mut c_void, str: *const c_char) -> ExternResult<*mut c_char> { fn typst_compile_inner(
todo!() compiler: &mut TypstCompiler,
str: *const c_char,
) -> anyhow::Result<*mut c_char> {
let input = extract_str(str)?;
compiler.compile(input).map(return_str)
}
pub extern "C" fn typst_compile(
handler: *mut c_void,
str: *const c_char,
) -> ExternResult<*mut c_char> {
let compiler = from_handler::<TypstCompiler>(handler);
ExternResult::from_result(typst_compile_inner(compiler, str))
}
pub extern "C" fn free_compiler(handler: *mut c_void) {
if handler.is_null() {
return;
}
unsafe {
// Drop it!
let _ = Box::from_raw(handler as *mut TypstCompiler);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke_test() {
let mut compiler = TypstCompiler::new(".").unwrap();
let result = compiler.compile("= 123").unwrap();
assert!(result.contains("<h2>123</h2>"))
}
#[test]
fn math_test() {
let mut compiler = TypstCompiler::new(".").unwrap();
let result = compiler.compile(
"$1 + 1 = 2$").unwrap();
assert!(result.contains("math"));
}
} }

View File

@@ -1,43 +1,127 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::LazyLock; use std::sync::LazyLock;
use typst::utils::LazyHash; use typst::diag::{FileError, FileResult, PackageError};
use typst::{Library, World};
use typst::diag::FileResult;
use typst::foundations::{Bytes, Datetime, Duration}; use typst::foundations::{Bytes, Datetime, Duration};
use typst::syntax::{FileId, Source}; use typst::syntax::{FileId, RootedPath, Source, VirtualPath, VirtualRoot};
use typst::text::{Font, FontBook}; use typst::text::{Font, FontBook};
use typst::utils::LazyHash;
use typst::{Feature, Features, Library, LibraryExt, World};
use typst_kit::datetime::Time;
use typst_kit::files::{FileLoader, FileStore, FsRoot};
use typst_kit::fonts::{FontStore, embedded};
pub struct SystemWorld { pub struct SystemWorld {
work_dir: PathBuf, work_dir: PathBuf,
library: LazyHash<Library>, library: LazyHash<Library>,
files: FileStore<SystemFiles>,
fonts: LazyLock<FontStore, Box<dyn Fn() -> FontStore + Send + Sync>>,
now: Time,
}
const DEFAULT_FEATURES: [Feature; 1] = [Feature::Html];
impl SystemWorld {
pub fn new(work_dir: PathBuf) -> Self {
let features = DEFAULT_FEATURES.iter().copied().map(Into::into).collect();
let library = Library::builder().with_features(features).build();
Self {
work_dir: work_dir.clone(),
library: LazyHash::new(library),
files: FileStore::new(SystemFiles::new(work_dir)),
fonts: LazyLock::new(Box::new(|| {
let mut fonts = FontStore::new();
fonts.extend(embedded());
fonts
})),
now: Time::system(),
}
}
pub fn set_current_file(&mut self, content: &str) {
let current_file = &mut self.files.loader_mut().current_file;
let bytes = content.as_bytes();
current_file.clear();
current_file.resize(bytes.len(), 0);
current_file.copy_from_slice(content.as_bytes())
}
} }
impl World for SystemWorld { impl World for SystemWorld {
fn library(&self) -> &LazyHash<Library> { fn library(&self) -> &LazyHash<Library> {
todo!() &self.library
} }
fn book(&self) -> &LazyHash<FontBook> { fn book(&self) -> &LazyHash<FontBook> {
todo!() self.fonts.book()
} }
fn main(&self) -> FileId { fn main(&self) -> FileId {
todo!() *MAIN_ID
} }
fn source(&self, id: FileId) -> FileResult<Source> { fn source(&self, id: FileId) -> FileResult<Source> {
todo!() self.files.source(id)
} }
fn file(&self, id: FileId) -> FileResult<Bytes> { fn file(&self, id: FileId) -> FileResult<Bytes> {
todo!() self.files.file(id)
} }
fn font(&self, index: usize) -> Option<Font> { fn font(&self, index: usize) -> Option<Font> {
todo!() self.fonts.font(index)
} }
fn today(&self, offset: Option<Duration>) -> Option<Datetime> { fn today(&self, offset: Option<Duration>) -> Option<Datetime> {
todo!() self.now.today(offset)
}
}
/// Provides project files from a configured directory and package files from
/// standard locations.
struct SystemFiles {
pub main: FileId,
project: FsRoot,
current_file: Vec<u8>,
}
static MAIN_ID: LazyLock<FileId> = LazyLock::new(|| {
FileId::unique(RootedPath::new(
VirtualRoot::Project,
VirtualPath::new("<main>").unwrap(),
))
});
impl SystemFiles {
pub fn new(work_dir: PathBuf) -> Self {
Self {
main: *MAIN_ID,
project: FsRoot::new(work_dir),
current_file: Vec::new(),
}
}
pub fn resolve(&self, id: FileId) -> FileResult<PathBuf> {
Ok(self.root(id)?.resolve(id.vpath())?)
}
fn root(&self, id: FileId) -> FileResult<FsRoot> {
Ok(match id.root() {
VirtualRoot::Project => Ok(self.project.clone()),
VirtualRoot::Package(_) => Err(FileError::Package(PackageError::Other(None))),
}?)
}
}
impl FileLoader for SystemFiles {
fn load(&self, id: FileId) -> FileResult<Bytes> {
if id == *MAIN_ID {
Ok(Bytes::new(self.current_file.clone()))
} else {
self.root(id)?.load(id.vpath())
}
} }
} }