typst 0.0.5 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -4
- data/README.typ +38 -4
- data/ext/typst/Cargo.toml +30 -15
- data/ext/typst/src/compiler.rs +100 -39
- data/ext/typst/src/download.rs +11 -71
- data/ext/typst/src/lib.rs +218 -21
- data/ext/typst/src/query.rs +131 -0
- data/ext/typst/src/world.rs +130 -136
- data/lib/typst.rb +61 -2
- metadata +4 -8
- data/ext/typst/src/lib.wip.rs +0 -203
data/ext/typst/src/lib.wip.rs
DELETED
@@ -1,203 +0,0 @@
|
|
1
|
-
use std::path::PathBuf;
|
2
|
-
use std::env;
|
3
|
-
|
4
|
-
use std::{
|
5
|
-
cell::RefCell,
|
6
|
-
fmt,
|
7
|
-
hash::{Hash, Hasher},
|
8
|
-
};
|
9
|
-
|
10
|
-
use magnus::r_string::IntoRString;
|
11
|
-
//use magnus::{function, exception, Error, IntoValue};
|
12
|
-
use magnus::{
|
13
|
-
class, define_class, exception, method, module, function,
|
14
|
-
prelude::*,
|
15
|
-
scan_args::{get_kwargs, scan_args},
|
16
|
-
typed_data, error::Error, Value, IntoValue, Symbol
|
17
|
-
};
|
18
|
-
|
19
|
-
use world::SystemWorld;
|
20
|
-
|
21
|
-
mod compiler;
|
22
|
-
mod download;
|
23
|
-
mod fonts;
|
24
|
-
mod package;
|
25
|
-
mod world;
|
26
|
-
|
27
|
-
fn compile(
|
28
|
-
input: PathBuf,
|
29
|
-
output: Option<PathBuf>,
|
30
|
-
root: Option<PathBuf>,
|
31
|
-
font_paths: Vec<PathBuf>,
|
32
|
-
) -> Result<magnus::Value, Error> {
|
33
|
-
let input = input.canonicalize()
|
34
|
-
.map_err(|err| magnus::Error::new(exception::arg_error(), err.to_string()))?;
|
35
|
-
|
36
|
-
let root = if let Some(root) = root {
|
37
|
-
root.canonicalize()
|
38
|
-
.map_err(|err| magnus::Error::new(exception::arg_error(), err.to_string()))?
|
39
|
-
} else if let Some(dir) = input.parent() {
|
40
|
-
dir.into()
|
41
|
-
} else {
|
42
|
-
PathBuf::new()
|
43
|
-
};
|
44
|
-
|
45
|
-
let resource_path = env::current_dir()
|
46
|
-
.map_err(|err| magnus::Error::new(exception::arg_error(), err.to_string()))?;
|
47
|
-
|
48
|
-
let mut default_fonts = Vec::new();
|
49
|
-
for entry in walkdir::WalkDir::new(resource_path.join("fonts")) {
|
50
|
-
let path = entry
|
51
|
-
.map_err(|err| magnus::Error::new(exception::arg_error(), err.to_string()))?
|
52
|
-
.into_path();
|
53
|
-
let Some(extension) = path.extension() else {
|
54
|
-
continue;
|
55
|
-
};
|
56
|
-
if extension == "ttf" || extension == "otf" {
|
57
|
-
default_fonts.push(path);
|
58
|
-
}
|
59
|
-
}
|
60
|
-
|
61
|
-
let mut world = SystemWorld::builder(root, input)
|
62
|
-
.font_paths(font_paths)
|
63
|
-
.font_files(default_fonts)
|
64
|
-
.build()
|
65
|
-
.map_err(|msg| magnus::Error::new(exception::arg_error(), msg.to_string()))?;
|
66
|
-
|
67
|
-
let pdf_bytes = world
|
68
|
-
.compile()
|
69
|
-
.map_err(|msg| magnus::Error::new(exception::arg_error(), msg.to_string()))?;
|
70
|
-
|
71
|
-
if let Some(output) = output {
|
72
|
-
std::fs::write(output, pdf_bytes)
|
73
|
-
.map_err(|_| magnus::Error::new(exception::arg_error(), "error"))?;
|
74
|
-
|
75
|
-
let value = true.into_value();
|
76
|
-
Ok(value)
|
77
|
-
} else {
|
78
|
-
let value = pdf_bytes.into_value();
|
79
|
-
Ok(value)
|
80
|
-
}
|
81
|
-
}
|
82
|
-
|
83
|
-
#[magnus::wrap(class = "Typst", free_immediately, size)]
|
84
|
-
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd)]
|
85
|
-
struct Typst {
|
86
|
-
input: PathBuf,
|
87
|
-
output: Option<PathBuf>,
|
88
|
-
root: PathBuf,
|
89
|
-
font_paths: Vec<PathBuf>,
|
90
|
-
}
|
91
|
-
|
92
|
-
// can't derive this due to needing to use RefCell to get mutability
|
93
|
-
impl Hash for Typst {
|
94
|
-
fn hash<H: Hasher>(&self, state: &mut H) {
|
95
|
-
self.input.hash(state)
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
//#[magnus::wrap(class = "Typst")]
|
100
|
-
impl Typst {
|
101
|
-
fn initialize(rb_self: typed_data::Obj<Self>, args: &[Value]) -> Result<Value, Error> {
|
102
|
-
let args = scan_args::<_, _, (), (), _, ()>(args)?;
|
103
|
-
let (input,): (PathBuf,) = args.required;
|
104
|
-
let (output,): (
|
105
|
-
Option<PathBuf>,
|
106
|
-
) = args.optional;
|
107
|
-
|
108
|
-
let kw = get_kwargs::<_, (), (Option<PathBuf>, Option<Vec<PathBuf>>), ()>(args.keywords, &[], &["root", "font_paths"])?;
|
109
|
-
let (root, font_paths) = kw.optional;
|
110
|
-
|
111
|
-
//*rb_self.input.borrow_mut() = input;
|
112
|
-
//*rb_self.output.borrow_mut() = output;
|
113
|
-
rb_self.input = input;
|
114
|
-
rb_self.output = output;
|
115
|
-
|
116
|
-
rb_self.root = if let Some(root) = root {
|
117
|
-
root
|
118
|
-
} else {
|
119
|
-
PathBuf::new()
|
120
|
-
};
|
121
|
-
|
122
|
-
rb_self.font_paths = if let Some(font_paths) = font_paths {
|
123
|
-
font_paths
|
124
|
-
} else {
|
125
|
-
let font_paths:Vec<PathBuf> = Vec::new();
|
126
|
-
font_paths
|
127
|
-
};
|
128
|
-
|
129
|
-
Ok(rb_self.into_value())
|
130
|
-
}
|
131
|
-
|
132
|
-
fn compile(rb_self: typed_data::Obj<Self>, args: &[Value]) -> Result<Value, Error> {
|
133
|
-
let resource_path = env::current_dir()
|
134
|
-
.map_err(|err| magnus::Error::new(exception::arg_error(), err.to_string()))?;
|
135
|
-
|
136
|
-
let mut default_fonts = Vec::new();
|
137
|
-
for entry in walkdir::WalkDir::new(resource_path.join("fonts")) {
|
138
|
-
let path = entry
|
139
|
-
.map_err(|err| magnus::Error::new(exception::arg_error(), err.to_string()))?
|
140
|
-
.into_path();
|
141
|
-
let Some(extension) = path.extension() else {
|
142
|
-
continue;
|
143
|
-
};
|
144
|
-
if extension == "ttf" || extension == "otf" {
|
145
|
-
default_fonts.push(path);
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
|
-
//let input = PathBuf::from(*rb_self.input.borrow());
|
150
|
-
//let root = PathBuf::from(*rb_self.root.borrow());
|
151
|
-
let input = PathBuf::from(&rb_self.input);
|
152
|
-
let root = PathBuf::from(&rb_self.root);
|
153
|
-
let font_paths: Vec<PathBuf> = Vec::new();
|
154
|
-
let mut world = SystemWorld::builder(root, input)
|
155
|
-
.font_paths(font_paths)
|
156
|
-
.font_files(default_fonts)
|
157
|
-
.build()
|
158
|
-
.map_err(|msg| magnus::Error::new(exception::arg_error(), msg.to_string()))?;
|
159
|
-
|
160
|
-
let pdf_bytes = world
|
161
|
-
.compile()
|
162
|
-
.map_err(|msg| magnus::Error::new(exception::arg_error(), msg.to_string()))?;
|
163
|
-
|
164
|
-
//let op: Option<PathBuf> = *rb_self.output.borrow();
|
165
|
-
//if let Some(output) = op {
|
166
|
-
// std::fs::write(output, pdf_bytes)
|
167
|
-
// .map_err(|_| magnus::Error::new(exception::arg_error(), "error"))?;
|
168
|
-
|
169
|
-
// let value = true.into_value();
|
170
|
-
// Ok(value)
|
171
|
-
//} else {
|
172
|
-
let value = pdf_bytes.into_value();
|
173
|
-
Ok(value)
|
174
|
-
//}
|
175
|
-
}
|
176
|
-
}
|
177
|
-
|
178
|
-
impl fmt::Display for Typst {
|
179
|
-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
180
|
-
write!(f, "{}", self.input.display())
|
181
|
-
}
|
182
|
-
}
|
183
|
-
|
184
|
-
#[magnus::init]
|
185
|
-
fn init() -> Result<(), Error> {
|
186
|
-
let class = define_class("Typst", class::object())?;
|
187
|
-
|
188
|
-
// Define alloc func based on the Default impl, plus an initialize method,
|
189
|
-
// rather than overwriting `new`, to allow class to be subclassed from Ruby
|
190
|
-
class.define_alloc_func::<Typst>();
|
191
|
-
class.define_method("initialize", method!(Typst::initialize, -1))?;
|
192
|
-
|
193
|
-
//class.define_singleton_method("foo", function!(foo, -1))?;
|
194
|
-
|
195
|
-
class.define_method("inspect",method!(<Typst as typed_data::Inspect>::inspect, 0))?;
|
196
|
-
|
197
|
-
class.define_method("to_s", method!(Typst::to_string, 0))?;
|
198
|
-
// class.define_method("barf", method!(Typst::barf, 0))?;
|
199
|
-
|
200
|
-
//let module = magnus::define_module("Typst").unwrap();
|
201
|
-
//module.define_module_function("compile", function!(compile, 4)).unwrap();
|
202
|
-
Ok(())
|
203
|
-
}
|