Skip to content

Commit 68428f5

Browse files
committed
Update to 0.12
1 parent 0b7eb9b commit 68428f5

29 files changed

+673
-575
lines changed

Cargo.lock

Lines changed: 634 additions & 531 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ The bot uses two binaries:
1515

1616
To set up the working environment, create a directory with the following items:
1717

18-
- `fonts`: Copied from the repo. ~~Make sure you have Git LFS set up so the fonts are downloaded properly.~~ The fonts no longer use LFS due to GitHub's new transfer limits.
1918
- `worker`: The worker binary, copied/hardlinked from the target directory after building.
2019
- `bot`: The bot binary, copied/hardlinked from the target directory after building. (This doesn't need to be in this directory, but having everything in one place simplifies things.)
2120
- `db.sqlite`: You can just `touch` this, but the bot needs to be able to write to it.
21+
(Legacy note: you don't need `fonts` anymore because we use `typst-assets` now.)
2222

2323
To run, CD into this directory, set `DISCORD_TOKEN` to your bot token, set `CACHE_DIRECTORY` and `DB_PATH` to suitable locations, and run the `bot` binary (not the `worker` binary that's also in the directory).
2424

2525
### Docker
2626

27-
There is a `Dockerfile` and `docker-compose.yml` for running the bot inside a Docker container.
27+
There is a `Dockerfile` and `docker-compose.yml` for running the bot inside a Docker container.
2828

2929
To set up the bot with Docker, create a `.env` file like the following:
3030

crates/worker/src/render.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use std::io::Cursor;
22

33
use protocol::Rendered;
4-
use typst::eval::Tracer;
54
use typst::layout::{Axis, Size};
6-
use typst::visualize::Color;
75

86
use crate::diagnostic::format_diagnostics;
97
use crate::sandbox::Sandbox;
@@ -55,22 +53,21 @@ const BYTES_LIMIT: usize = 25 * 1024 * 1024;
5553
pub fn render(sandbox: &Sandbox, source: String) -> Result<Rendered, String> {
5654
let world = sandbox.with_source(source);
5755

58-
let mut tracer = Tracer::default();
59-
let document =
60-
typst::compile(&world, &mut tracer).map_err(|diags| format_diagnostics(&world, &diags))?;
61-
let warnings = tracer.warnings();
56+
let document = typst::compile(&world);
57+
let warnings = document.warnings;
58+
let document = document
59+
.output
60+
.map_err(|diags| format_diagnostics(&world, &diags))?;
6261

63-
let transparent = Color::from_u8(0, 0, 0, 0);
6462
let mut total_attachment_size = 0;
6563

6664
let images = document
6765
.pages
6866
.iter()
6967
.take(PAGE_LIMIT)
7068
.map(|page| {
71-
let frame = &page.frame;
72-
let pixels_per_point = determine_pixels_per_point(frame.size()).map_err(to_string)?;
73-
let pixmap = typst_render::render(frame, pixels_per_point, transparent);
69+
let pixels_per_point = determine_pixels_per_point(page.frame.size()).map_err(to_string)?;
70+
let pixmap = typst_render::render(page, pixels_per_point);
7471

7572
let mut writer = Cursor::new(Vec::new());
7673

crates/worker/src/sandbox.rs

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use std::cell::{RefCell, RefMut};
21
use std::collections::HashMap;
32
use std::path::PathBuf;
3+
use std::sync::Mutex;
44

5-
use comemo::Prehashed;
65
use typst::diag::{eco_format, FileError, FileResult, PackageError, PackageResult};
76
use typst::foundations::{Bytes, Datetime};
87
use typst::syntax::package::PackageSpec;
98
use typst::syntax::{FileId, Source};
109
use typst::text::{Font, FontBook};
10+
use typst::utils::LazyHash;
1111
use typst::Library;
1212

1313
struct FileEntry {
@@ -33,27 +33,22 @@ impl FileEntry {
3333
}
3434

3535
pub struct Sandbox {
36-
library: Prehashed<Library>,
37-
book: Prehashed<FontBook>,
36+
library: LazyHash<Library>,
37+
book: LazyHash<FontBook>,
3838
fonts: Vec<Font>,
3939

4040
cache_directory: PathBuf,
4141
http: ureq::Agent,
42-
files: RefCell<HashMap<FileId, FileEntry>>,
42+
files: Mutex<HashMap<FileId, FileEntry>>,
4343
}
4444

4545
fn fonts() -> Vec<Font> {
46-
std::fs::read_dir("fonts")
47-
.unwrap()
48-
.map(Result::unwrap)
49-
.flat_map(|entry| {
50-
let path = entry.path();
51-
let bytes = std::fs::read(&path).unwrap();
52-
let buffer = Bytes::from(bytes);
46+
typst_assets::fonts()
47+
.flat_map(|bytes| {
48+
let buffer = Bytes::from_static(bytes);
5349
let face_count = ttf_parser::fonts_in_collection(&buffer).unwrap_or(1);
5450
(0..face_count).map(move |face| {
55-
Font::new(buffer.clone(), face)
56-
.unwrap_or_else(|| panic!("failed to load font from {path:?} (face index {face})"))
51+
Font::new(buffer.clone(), face).expect("failed to load font from typst-assets")
5752
})
5853
})
5954
.collect()
@@ -91,15 +86,15 @@ impl Sandbox {
9186
let fonts = fonts();
9287

9388
Self {
94-
library: Prehashed::new(Library::default()),
95-
book: Prehashed::new(FontBook::from_fonts(&fonts)),
89+
library: LazyHash::new(Library::default()),
90+
book: LazyHash::new(FontBook::from_fonts(&fonts)),
9691
fonts,
9792

9893
cache_directory: std::env::var_os("CACHE_DIRECTORY")
9994
.expect("need the `CACHE_DIRECTORY` env var")
10095
.into(),
10196
http: ureq::Agent::new(),
102-
files: RefCell::new(HashMap::new()),
97+
files: Mutex::new(HashMap::new()),
10398
}
10499
}
105100

@@ -163,10 +158,14 @@ impl Sandbox {
163158
Ok(path)
164159
}
165160

166-
fn file(&self, id: FileId) -> FileResult<RefMut<'_, FileEntry>> {
167-
if let Ok(entry) = RefMut::filter_map(self.files.borrow_mut(), |files| files.get_mut(&id)) {
168-
return Ok(entry);
161+
// Weird pattern because mapping a MutexGuard is not stable yet.
162+
fn file<T>(&self, id: FileId, map: impl FnOnce(&mut FileEntry) -> T) -> FileResult<T> {
163+
let mut files = self.files.lock().unwrap();
164+
if let Some(entry) = files.get_mut(&id) {
165+
return Ok(map(entry));
169166
}
167+
// `files` must stay locked here so we don't download the same package multiple times.
168+
// TODO proper multithreading, maybe with typst-kit.
170169

171170
'x: {
172171
if let Some(package) = id.package() {
@@ -175,12 +174,11 @@ impl Sandbox {
175174
break 'x;
176175
};
177176
let contents = std::fs::read(&path).map_err(|error| FileError::from_io(error, &path))?;
178-
return Ok(RefMut::map(self.files.borrow_mut(), |files| {
179-
files.entry(id).or_insert(FileEntry {
180-
bytes: contents.into(),
181-
source: None,
182-
})
183-
}));
177+
let entry = files.entry(id).or_insert(FileEntry {
178+
bytes: contents.into(),
179+
source: None,
180+
});
181+
return Ok(map(entry));
184182
}
185183
}
186184

@@ -195,23 +193,23 @@ impl WithSource<'_> {
195193
}
196194

197195
impl typst::World for WithSource<'_> {
198-
fn library(&self) -> &Prehashed<Library> {
196+
fn library(&self) -> &LazyHash<Library> {
199197
&self.sandbox.library
200198
}
201199

202-
fn main(&self) -> Source {
203-
self.source.clone()
200+
fn main(&self) -> FileId {
201+
self.source.id()
204202
}
205203

206204
fn source(&self, id: FileId) -> FileResult<Source> {
207205
if id == self.source.id() {
208206
Ok(self.source.clone())
209207
} else {
210-
self.sandbox.file(id)?.source(id)
208+
self.sandbox.file(id, |file| file.source(id))?
211209
}
212210
}
213211

214-
fn book(&self) -> &Prehashed<FontBook> {
212+
fn book(&self) -> &LazyHash<FontBook> {
215213
&self.sandbox.book
216214
}
217215

@@ -220,7 +218,7 @@ impl typst::World for WithSource<'_> {
220218
}
221219

222220
fn file(&self, id: FileId) -> FileResult<Bytes> {
223-
self.sandbox.file(id).map(|file| file.bytes.clone())
221+
self.sandbox.file(id, |file| file.bytes.clone())
224222
}
225223

226224
fn today(&self, offset: Option<i64>) -> Option<Datetime> {

fonts/DejaVuSansMono-Bold.ttf

-324 KB
Binary file not shown.

fonts/DejaVuSansMono.ttf

-333 KB
Binary file not shown.

fonts/FiraMath-Regular.otf

-176 KB
Binary file not shown.

fonts/IBMPlexSerif-Regular.ttf

-156 KB
Binary file not shown.

fonts/InriaSerif-BoldItalic.ttf

-95.8 KB
Binary file not shown.

fonts/InriaSerif-Regular.ttf

-96.1 KB
Binary file not shown.

fonts/LinLibertine_R.ttf

-788 KB
Binary file not shown.

fonts/LinLibertine_RB.ttf

-731 KB
Binary file not shown.

fonts/LinLibertine_RBI.ttf

-521 KB
Binary file not shown.

fonts/LinLibertine_RI.ttf

-704 KB
Binary file not shown.

fonts/Nerd.ttf

-2.08 MB
Binary file not shown.

fonts/NewCM10-Bold.otf

-487 KB
Binary file not shown.

fonts/NewCM10-Regular.otf

-535 KB
Binary file not shown.

fonts/NewCMMath-Book.otf

-2.06 MB
Binary file not shown.

fonts/NewCMMath-Regular.otf

-1.17 MB
Binary file not shown.

fonts/NotoColorEmoji.ttf

-9.41 MB
Binary file not shown.

fonts/NotoSansArabic-Regular.ttf

-137 KB
Binary file not shown.

fonts/NotoSansSymbols2-Regular.ttf

-641 KB
Binary file not shown.

fonts/NotoSerifCJKsc-Regular.otf

-22.5 MB
Binary file not shown.

fonts/NotoSerifHebrew-Bold.ttf

-20.9 KB
Binary file not shown.

fonts/NotoSerifHebrew-Regular.ttf

-21 KB
Binary file not shown.

fonts/PTSans-Regular.ttf

-272 KB
Binary file not shown.

fonts/Roboto-Regular.ttf

-298 KB
Binary file not shown.

fonts/TwitterColorEmoji.ttf

-12.7 MB
Binary file not shown.

fonts/Ubuntu-Regular.ttf

-293 KB
Binary file not shown.

0 commit comments

Comments
 (0)