typst 0.15.1.6 → 0.15.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.toml +4 -1
- data/README.md +2 -1
- data/README.typ +2 -1
- data/Rakefile +4 -0
- data/ext/typst/src/lib.rs +5 -0
- data/ext/typst/src/world.rs +76 -5
- data/lib/typst.rb +14 -6
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e504e7d6117a089aea226128ffb96a606d0569184d274a31b786b40323ea2459
|
|
4
|
+
data.tar.gz: c54e606e7ec710230a13fd418b8faeb1f427342f6533ebe0cfa1402fbb0ee327
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db255e768cc4b75a8f233494478140672721c19de71b5c7a8e9f3dc48cbe89fb4a8a372f004fd5136388ba0a6c673a9e133a003ea73dfc285bab6f371108cd50
|
|
7
|
+
data.tar.gz: ae2a297b332214c1b83ed24a0862b5288aae8ded7a7d921b198f7777ce5ef091492ff85d4484729f171416a2ab8cd9765b4234f338e2bbd7ca3bf9c6434c315d
|
data/Cargo.toml
CHANGED
data/README.md
CHANGED
|
@@ -269,7 +269,8 @@ clear_cache was contributed by [NRicciVestmark](https://github.com/NRicciVestmar
|
|
|
269
269
|
CI improvements were contributed by [am1006](https://github.com/am1006)\
|
|
270
270
|
Defect resolutions by [adam12](https://github.com/adam12) and [walterdavis](https://github.com/walterdavis)\
|
|
271
271
|
Design suggestions by [alec-c4](https://github.com/alec-c4)\
|
|
272
|
-
Compiler warnings were contributed by [TheSoloHacker47](https://github.com/TheSoloHacker47)
|
|
272
|
+
Compiler warnings were contributed by [TheSoloHacker47](https://github.com/TheSoloHacker47) \
|
|
273
|
+
Font optimization patches were contributed by [dmke](https://github.com/dmke)
|
|
273
274
|
|
|
274
275
|
## License
|
|
275
276
|
|
data/README.typ
CHANGED
|
@@ -276,7 +276,8 @@ clear_cache was contributed by #link("https://github.com/NRicciVestmark")[NRicci
|
|
|
276
276
|
CI improvements were contributed by #link("https://github.com/am1006")[am1006]\
|
|
277
277
|
Defect resolutions by #link("https://github.com/adam12")[adam12] and #link("https://github.com/walterdavis")[walterdavis]\
|
|
278
278
|
Design suggestions by #link("https://github.com/alec-c4")[alec-c4]\
|
|
279
|
-
Compiler warnings were contributed by #link("https://github.com/TheSoloHacker47")[TheSoloHacker47]
|
|
279
|
+
Compiler warnings were contributed by #link("https://github.com/TheSoloHacker47")[TheSoloHacker47] \
|
|
280
|
+
Font optimization patches were contributed by #link("https://github.com/dmke")[dmke]
|
|
280
281
|
|
|
281
282
|
== License
|
|
282
283
|
|
data/Rakefile
CHANGED
|
@@ -34,6 +34,10 @@ Rake::TestTask.new do |t|
|
|
|
34
34
|
t.verbose = true
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
task 'benchmark' do |t|
|
|
38
|
+
sh "bundle exec ruby benchmarks/compile_pdf.rb"
|
|
39
|
+
end
|
|
40
|
+
|
|
37
41
|
task 'gem:native' do |t|
|
|
38
42
|
CROSS_PLATFORMS.each do |platform|
|
|
39
43
|
sh "bundle exec rb-sys-dock --platform #{platform} --build"
|
data/ext/typst/src/lib.rs
CHANGED
|
@@ -287,6 +287,10 @@ fn clear_cache(_ruby: &Ruby, max_age: usize) {
|
|
|
287
287
|
comemo::evict(max_age);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
fn clear_font_cache(_ruby: &Ruby) {
|
|
291
|
+
world::clear_font_cache();
|
|
292
|
+
}
|
|
293
|
+
|
|
290
294
|
#[magnus::init]
|
|
291
295
|
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
292
296
|
env_logger::init();
|
|
@@ -298,5 +302,6 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
298
302
|
module.define_singleton_method("_to_html", function!(to_html, 8))?;
|
|
299
303
|
module.define_singleton_method("_query", function!(query, 10))?;
|
|
300
304
|
module.define_singleton_method("_clear_cache", function!(clear_cache, 1))?;
|
|
305
|
+
module.define_singleton_method("_clear_font_cache", function!(clear_font_cache, 0))?;
|
|
301
306
|
Ok(())
|
|
302
307
|
}
|
data/ext/typst/src/world.rs
CHANGED
|
@@ -7,10 +7,10 @@ use chrono::{DateTime, Datelike, FixedOffset, Local};
|
|
|
7
7
|
use typst::diag::{FileError, FileResult, StrResult};
|
|
8
8
|
use typst::foundations::{Bytes, Datetime, Dict, Duration};
|
|
9
9
|
use typst::syntax::{FileId, Lines, Source, VirtualPath, VirtualRoot, RootedPath};
|
|
10
|
-
use typst::text::{Font, FontBook};
|
|
10
|
+
use typst::text::{Font, FontBook, FontInfo};
|
|
11
11
|
use typst::utils::LazyHash;
|
|
12
12
|
use typst::{Features, Library, LibraryExt, World};
|
|
13
|
-
use typst_kit::fonts::{self, FontStore};
|
|
13
|
+
use typst_kit::fonts::{self, FontPath, FontStore};
|
|
14
14
|
use typst_kit::packages::{FsPackages, SystemPackages, UniversePackages};
|
|
15
15
|
|
|
16
16
|
/// A world that provides access to the operating system.
|
|
@@ -195,7 +195,7 @@ impl SystemWorldBuilder {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
pub fn build(self) -> StrResult<SystemWorld> {
|
|
198
|
-
let fonts =
|
|
198
|
+
let fonts = font_store(self.ignore_system_fonts, self.ignore_embedded_fonts, self.font_paths);
|
|
199
199
|
|
|
200
200
|
let package_storage = system_packages(self.package_path, self.package_cache_path);
|
|
201
201
|
|
|
@@ -217,13 +217,84 @@ impl SystemWorldBuilder {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
/// Font discovery, which is far too slow to repeat on every compile.
|
|
221
|
+
///
|
|
222
|
+
/// A full system font scan takes about 95 ms, which for a small document
|
|
223
|
+
/// dwarfs the compilation itself. `FontStore` cannot be cloned, so the
|
|
224
|
+
/// discovered fonts are kept alongside the assembled stores.
|
|
225
|
+
struct FontCache {
|
|
226
|
+
/// The locations found by walking the system font directories.
|
|
227
|
+
system: Option<Arc<Vec<(PathBuf, u32, FontInfo)>>>,
|
|
228
|
+
/// The fonts shipped with typst, already parsed.
|
|
229
|
+
embedded: Option<Arc<Vec<(Font, FontInfo)>>>,
|
|
230
|
+
/// A store per combination of the two ignore flags, for compiles that
|
|
231
|
+
/// bring no font paths of their own. Sharing one keeps the fonts a
|
|
232
|
+
/// document uses loaded between compiles and hashes the book only once.
|
|
233
|
+
stores: [Option<Arc<FontStore>>; 4],
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const EMPTY_FONT_CACHE: FontCache =
|
|
237
|
+
FontCache { system: None, embedded: None, stores: [const { None }; 4] };
|
|
238
|
+
|
|
239
|
+
static FONT_CACHE: Mutex<FontCache> = Mutex::new(EMPTY_FONT_CACHE);
|
|
240
|
+
|
|
241
|
+
/// Forgets everything discovered so far, so that the next compile picks up
|
|
242
|
+
/// fonts installed or removed since.
|
|
243
|
+
pub fn clear_font_cache() {
|
|
244
|
+
*FONT_CACHE.lock().unwrap() = EMPTY_FONT_CACHE;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/// Reads a cache field, filling it on a miss.
|
|
248
|
+
///
|
|
249
|
+
/// The lock is not held while building, so two threads missing at once both
|
|
250
|
+
/// build and one result is dropped. That wastes a scan but keeps a 95 ms
|
|
251
|
+
/// build off the lock.
|
|
252
|
+
fn cached<T>(
|
|
253
|
+
select: impl Fn(&mut FontCache) -> &mut Option<Arc<T>>,
|
|
254
|
+
build: impl FnOnce() -> T,
|
|
255
|
+
) -> Arc<T> {
|
|
256
|
+
let hit = select(&mut FONT_CACHE.lock().unwrap()).clone();
|
|
257
|
+
if let Some(value) = hit {
|
|
258
|
+
return value;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let value = Arc::new(build());
|
|
262
|
+
*select(&mut FONT_CACHE.lock().unwrap()) = Some(value.clone());
|
|
263
|
+
value
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/// Obtains a font store for the given configuration.
|
|
267
|
+
///
|
|
268
|
+
/// Extra font paths are scanned on every compile. They are usually a
|
|
269
|
+
/// temporary directory written by `Typst.build_world_from_s`, so their
|
|
270
|
+
/// contents can change between compiles and caching on them would grow
|
|
271
|
+
/// without bound.
|
|
272
|
+
fn font_store(ignore_system_fonts: bool, ignore_embedded_fonts: bool, font_paths: Vec<PathBuf>) -> Arc<FontStore> {
|
|
273
|
+
if !font_paths.is_empty() {
|
|
274
|
+
return Arc::new(build_font_store(ignore_system_fonts, ignore_embedded_fonts, font_paths));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let index = usize::from(ignore_system_fonts) << 1 | usize::from(ignore_embedded_fonts);
|
|
278
|
+
cached(
|
|
279
|
+
move |cache| &mut cache.stores[index],
|
|
280
|
+
|| build_font_store(ignore_system_fonts, ignore_embedded_fonts, Vec::new()),
|
|
281
|
+
)
|
|
282
|
+
}
|
|
283
|
+
|
|
220
284
|
fn build_font_store(ignore_system_fonts: bool, ignore_embedded_fonts: bool, font_paths: Vec<PathBuf>) -> FontStore {
|
|
221
285
|
let mut fonts = FontStore::new();
|
|
222
286
|
if !ignore_system_fonts {
|
|
223
|
-
|
|
287
|
+
let system = cached(
|
|
288
|
+
|cache| &mut cache.system,
|
|
289
|
+
|| fonts::system().map(|(path, info)| (path.path, path.index, info)).collect(),
|
|
290
|
+
);
|
|
291
|
+
fonts.extend(system.iter().map(|(path, index, info)| {
|
|
292
|
+
(FontPath { path: path.clone(), index: *index }, info.clone())
|
|
293
|
+
}));
|
|
224
294
|
}
|
|
225
295
|
if !ignore_embedded_fonts {
|
|
226
|
-
|
|
296
|
+
let embedded = cached(|cache| &mut cache.embedded, || fonts::embedded().collect());
|
|
297
|
+
fonts.extend(embedded.iter().cloned());
|
|
227
298
|
}
|
|
228
299
|
for path in font_paths {
|
|
229
300
|
fonts.extend(fonts::scan(&path));
|
data/lib/typst.rb
CHANGED
|
@@ -17,6 +17,12 @@ module Typst
|
|
|
17
17
|
Typst::_clear_cache(max_age)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Discards the discovered system and embedded fonts, so that the next
|
|
21
|
+
# compile picks up fonts installed or removed since the first one.
|
|
22
|
+
def self.clear_font_cache
|
|
23
|
+
Typst::_clear_font_cache
|
|
24
|
+
end
|
|
25
|
+
|
|
20
26
|
def self.build_world_from_s(main_source, **options, &blk)
|
|
21
27
|
dependencies = options[:dependencies] ||= {}
|
|
22
28
|
fonts = options[:fonts] ||= {}
|
|
@@ -30,16 +36,18 @@ module Typst
|
|
|
30
36
|
File.binwrite(tmp_dep_file, dep_source)
|
|
31
37
|
end
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
unless fonts.empty?
|
|
40
|
+
relative_font_path = Pathname.new(tmp_dir).join("fonts")
|
|
41
|
+
relative_font_path.mkpath
|
|
42
|
+
fonts.each do |font_name, font_bytes|
|
|
43
|
+
tmp_font_file = relative_font_path.join(font_name)
|
|
44
|
+
File.binwrite(tmp_font_file, font_bytes)
|
|
45
|
+
end
|
|
46
|
+
options[:font_paths] = (options[:font_paths] || []) + [relative_font_path]
|
|
38
47
|
end
|
|
39
48
|
|
|
40
49
|
options[:file] = tmp_main_file
|
|
41
50
|
options[:root] = tmp_dir
|
|
42
|
-
options[:font_paths] = [relative_font_path]
|
|
43
51
|
|
|
44
52
|
blk.call(options)
|
|
45
53
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typst
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.15.1.
|
|
4
|
+
version: 0.15.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Flinn
|
|
@@ -117,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
117
117
|
- !ruby/object:Gem::Version
|
|
118
118
|
version: '0'
|
|
119
119
|
requirements: []
|
|
120
|
-
rubygems_version: 4.0.
|
|
120
|
+
rubygems_version: 4.0.20
|
|
121
121
|
specification_version: 4
|
|
122
122
|
summary: Ruby binding to typst, a new markup-based typesetting system that is powerful
|
|
123
123
|
and easy to learn.
|