typst 0.14.2.1 → 0.14.2.3
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/README.md +104 -37
- data/README.typ +110 -38
- data/ext/typst/Cargo.toml +1 -1
- data/ext/typst/src/compiler.rs +0 -1
- data/ext/typst/src/download.rs +1 -1
- data/ext/typst/src/lib.rs +41 -4
- data/ext/typst/src/query.rs +1 -1
- data/ext/typst/src/world.rs +0 -1
- data/lib/base.rb +45 -72
- data/lib/document.rb +15 -7
- data/lib/formats/html_experimental.rb +3 -1
- data/lib/formats/pdf.rb +4 -2
- data/lib/formats/png.rb +4 -2
- data/lib/formats/svg.rb +3 -1
- data/lib/query.rb +6 -3
- data/lib/typst.rb +68 -5
- metadata +32 -6
- data/lib/formats/html.rb +0 -35
- data/lib/typst/typst.bundle +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bdc56381647f2be411648ebbf5525576c5c6a259257cafd29de225dbd50da25c
|
|
4
|
+
data.tar.gz: 414023a808e3081a46e5e3ca64aa44920aedc41bbeca7c7004557e2a76b682f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf751aa8cfe5c0cb9f7433728f61ef1882af9fdea3b0aa031fa87e906a6be1880b1832a74597871911751fc912fb93f2f8946d4b8fd022c175828865d428938c
|
|
7
|
+
data.tar.gz: 62d507c32cdd32be9cf125350953a57971968e5aff1b43604d506e640901a327b940ab51c5becb6e4890ce1c8f656c4adb0a8bae19e1b3b217a6d82c8cddfb80
|
data/README.md
CHANGED
|
@@ -16,56 +16,82 @@ require "typst"
|
|
|
16
16
|
|
|
17
17
|
# Compile a typst file and write the output to a PDF file
|
|
18
18
|
Typst("readme.typ").compile(:pdf).write("readme.pdf")
|
|
19
|
+
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
### Use a typst file `readme.typ`
|
|
22
|
+
```ruby
|
|
21
23
|
t = Typst("readme.typ")
|
|
24
|
+
```
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
### Use a typst string
|
|
27
|
+
```ruby
|
|
24
28
|
t = Typst(body: %{hello world})
|
|
29
|
+
```
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
### Use a typst file in a zip file
|
|
32
|
+
```ruby
|
|
27
33
|
t = Typst(zip: "test/main.typ.zip")
|
|
34
|
+
```
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
### Compile to PDF
|
|
37
|
+
```ruby
|
|
38
|
+
doc = t.compile(:pdf)
|
|
39
|
+
```
|
|
31
40
|
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
### Compile to PDF selecting the typst supported PdfStandard
|
|
42
|
+
```ruby
|
|
43
|
+
doc = t.compile(:pdf, pdf_standards: ["2.0"])
|
|
44
|
+
```
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
### Compile to SVG
|
|
47
|
+
```ruby
|
|
48
|
+
doc = t.compile(:svg)
|
|
49
|
+
```
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
### Compile to PNG
|
|
52
|
+
```ruby
|
|
53
|
+
doc = t.compile(:png)
|
|
54
|
+
```
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
### Compile to PNG and set PPI
|
|
57
|
+
```ruby
|
|
58
|
+
doc = t.compile(:png, ppi: 72)
|
|
59
|
+
```
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Typst("readme.typ").compile(:html).document
|
|
50
|
-
# => "\n<!DOCTYPE html>\n<html>\n<head>\n<title>main</title>\n</head>\n<body>\n<svg class=\"typst-doc\" ...
|
|
61
|
+
### Compile to HTML (using Typst expirmental HTML)
|
|
62
|
+
```ruby
|
|
63
|
+
doc = t.compile(:html_experimental)
|
|
64
|
+
```
|
|
51
65
|
|
|
52
|
-
|
|
66
|
+
### Or return content as an array of bytes
|
|
67
|
+
```ruby
|
|
53
68
|
pdf_bytes = Typst("readme.typ").compile(:pdf).bytes
|
|
54
69
|
# => [37, 80, 68, 70, 45, 49, 46, 55, 10, 37, 128 ...]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Write the output to a file
|
|
73
|
+
Note: for multi-page documents using formats other than PDF and HTML, pages write to multiple files, e.g. `readme_0.png`, `readme_1.png`
|
|
74
|
+
```ruby
|
|
75
|
+
doc.write("filename.pdf")
|
|
76
|
+
```
|
|
55
77
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
78
|
+
### Return PDF, SVG, PNG or HTML content as an array of pages
|
|
79
|
+
```ruby
|
|
80
|
+
Typst("readme.typ").compile(:pdf).pages
|
|
81
|
+
# => ["%PDF-1.7\n%\x80\x80\x80\x80\n\n1 0 obj\n<<\n /Type /Pages\n /Count 3\n /Kids [160 0 R 162 ...
|
|
59
82
|
|
|
60
|
-
# Return SVG, HTML or PNG content as an array of pages
|
|
61
83
|
Typst("readme.typ").compile(:svg).pages
|
|
62
|
-
# => ["<svg class=\"typst-doc\" viewBox=\"0 0 595.2764999999999 841.89105\" ...
|
|
63
|
-
|
|
64
|
-
# => ["<svg class=\"typst-doc\" viewBox=\"0 0 595.2764999999999 841.89105\" ..."
|
|
84
|
+
# => ["<svg class=\"typst-doc\" viewBox=\"0 0 595.2764999999999 841.89105\" ...
|
|
85
|
+
|
|
65
86
|
Typst("readme.typ").compile(:png).pages
|
|
66
87
|
# => ["\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x04\xA7\x00\x00\x06\x94\b\ ...
|
|
67
88
|
|
|
68
|
-
|
|
89
|
+
Typst("readme.typ").compile(:html_experimental).pages
|
|
90
|
+
# => ["<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" ...
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Pass values into typst using sys_inputs
|
|
94
|
+
```ruby
|
|
69
95
|
sys_inputs_example = %{
|
|
70
96
|
#let persons = json(bytes(sys.inputs.persons))
|
|
71
97
|
|
|
@@ -76,15 +102,18 @@ sys_inputs_example = %{
|
|
|
76
102
|
people = [{"name" => "John", "age" => 35}, {"name" => "Xoliswa", "age" => 45}]
|
|
77
103
|
data = { "persons" => people.to_json }
|
|
78
104
|
Typst(body: sys_inputs_example, sys_inputs: data).compile(:pdf).write("sys_inputs_example.pdf")
|
|
105
|
+
```
|
|
79
106
|
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
### Apply inputs to typst to product multiple PDFs
|
|
108
|
+
```ruby
|
|
82
109
|
t = Typst(body: sys_inputs_example)
|
|
83
110
|
people.each do |person|
|
|
84
111
|
t.with_inputs({ "persons" => [person].to_json }).compile(:pdf).write("#{person['name']}.pdf")
|
|
85
112
|
end
|
|
113
|
+
```
|
|
86
114
|
|
|
87
|
-
|
|
115
|
+
### A more complex example of compiling from string using other dependency typst template, svg and font resources all in memory
|
|
116
|
+
```ruby
|
|
88
117
|
main = %{
|
|
89
118
|
#import "template.typ": *
|
|
90
119
|
|
|
@@ -106,27 +135,65 @@ icon = File.read("icon.svg")
|
|
|
106
135
|
font_bytes = File.read("Example.ttf")
|
|
107
136
|
|
|
108
137
|
Typst(body: main, dependencies: { "template.typ" => template, "icon.svg" => icon }, fonts: { "Example.ttf" => font_bytes }).compile(:pdf)
|
|
138
|
+
```
|
|
109
139
|
|
|
110
|
-
|
|
140
|
+
### From a zip with a named main typst file
|
|
141
|
+
```ruby
|
|
111
142
|
Typst(zip: "test/main.typ.zip", main_file: "hello.typ").compile(:pdf)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Use a package from the [Typst Universe](https://typst.app/universe)
|
|
146
|
+
Your package_example.typ file...
|
|
147
|
+
```typst
|
|
148
|
+
#import "@preview/wordometer:0.1.5": word-count, total-words
|
|
149
|
+
#show: word-count
|
|
150
|
+
|
|
151
|
+
In this document, there are #total-words words all up.
|
|
152
|
+
|
|
153
|
+
#word-count(total => [
|
|
154
|
+
The number of words in this block is #total.words
|
|
155
|
+
and there are #total.characters letters.
|
|
156
|
+
])
|
|
157
|
+
```
|
|
158
|
+
...compiles just like anything else
|
|
159
|
+
```ruby
|
|
160
|
+
Typst("package_example.typ").compile(:pdf).write("package_example.pdf")
|
|
161
|
+
```
|
|
112
162
|
|
|
113
|
-
|
|
163
|
+
### Query a typst document
|
|
164
|
+
```ruby
|
|
165
|
+
Typst("readme.typ").query("heading").result
|
|
114
166
|
# =>
|
|
115
167
|
# [{"func" => "heading",
|
|
116
168
|
# "level" => 1,
|
|
117
169
|
# "depth" => 1,
|
|
118
170
|
# ...
|
|
119
171
|
|
|
120
|
-
Typst
|
|
172
|
+
Typst("readme.typ").query("heading", format: "json").result(raw: true)
|
|
121
173
|
# => "[\n {\n \"func\": \"heading\",\n \"level\": 1,\n \"depth\": ..."
|
|
122
174
|
|
|
123
|
-
Typst
|
|
175
|
+
Typst("readme.typ").query("heading", format: "yaml").result(raw: true)
|
|
124
176
|
# => "- func: heading\n level: 1\n depth: 1\n offset: 0\n numbering: ..."
|
|
125
177
|
|
|
178
|
+
# Query results as JSON string
|
|
179
|
+
Typst("test/test.typ").query("heading").to_s
|
|
180
|
+
# => "[\n {\n \"func\": \"heading\",\n \"level\": 1,\n \"depth\": 1,\n \"offset\": 0,\n ...
|
|
181
|
+
|
|
182
|
+
# Query results as YAML string
|
|
183
|
+
Typst("test/test.typ").query("heading", format: "yaml").to_s
|
|
184
|
+
# => "- func: heading\n level: 1\n depth: 1\n offset: 0\n numbering: null\n supplement:\n ...
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### clear the compilation cache
|
|
188
|
+
```ruby
|
|
189
|
+
# Evict all entries whose age is larger than or equal to `max_age`
|
|
190
|
+
max_age = 10
|
|
191
|
+
Typst::clear_cache(max_age)
|
|
126
192
|
```
|
|
127
193
|
|
|
128
194
|
## Contributors & Acknowledgements
|
|
129
|
-
typst-rb is based on [typst-py](https://github.com/messense/typst-py) by [messense](https://github.com/messense)
|
|
195
|
+
typst-rb is based on [typst-py](https://github.com/messense/typst-py) by [messense](https://github.com/messense)\
|
|
196
|
+
clear_cache was contributed by [NRicciVestmark](https://github.com/NRicciVestmark)
|
|
130
197
|
|
|
131
198
|
## License
|
|
132
199
|
|
data/README.typ
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
#set document(title: [typst.rb README])
|
|
2
2
|
#show link: underline
|
|
3
3
|
#show link: set text(blue)
|
|
4
|
+
#show raw.where(block: true): block.with(
|
|
5
|
+
fill: luma(240),
|
|
6
|
+
inset: 10pt,
|
|
7
|
+
radius: 4pt,
|
|
8
|
+
)
|
|
4
9
|
|
|
5
10
|
= typst-rb
|
|
6
11
|
|
|
@@ -19,56 +24,82 @@ require "typst"
|
|
|
19
24
|
|
|
20
25
|
# Compile a typst file and write the output to a PDF file
|
|
21
26
|
Typst("readme.typ").compile(:pdf).write("readme.pdf")
|
|
27
|
+
```
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
=== Use a typst file `readme.typ`
|
|
30
|
+
```ruby
|
|
24
31
|
t = Typst("readme.typ")
|
|
32
|
+
```
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
=== Use a typst string
|
|
35
|
+
```ruby
|
|
27
36
|
t = Typst(body: %{hello world})
|
|
37
|
+
```
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
=== Use a typst file in a zip file
|
|
40
|
+
```ruby
|
|
30
41
|
t = Typst(zip: "test/main.typ.zip")
|
|
42
|
+
```
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
44
|
+
=== Compile to PDF
|
|
45
|
+
```ruby
|
|
46
|
+
doc = t.compile(:pdf)
|
|
47
|
+
```
|
|
34
48
|
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
=== Compile to PDF selecting the typst supported PdfStandard
|
|
50
|
+
```ruby
|
|
51
|
+
doc = t.compile(:pdf, pdf_standards: ["2.0"])
|
|
52
|
+
```
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
=== Compile to SVG
|
|
55
|
+
```ruby
|
|
56
|
+
doc = t.compile(:svg)
|
|
57
|
+
```
|
|
40
58
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
59
|
+
=== Compile to PNG
|
|
60
|
+
```ruby
|
|
61
|
+
doc = t.compile(:png)
|
|
62
|
+
```
|
|
44
63
|
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
=== Compile to PNG and set PPI
|
|
65
|
+
```ruby
|
|
66
|
+
doc = t.compile(:png, ppi: 72)
|
|
67
|
+
```
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Typst("readme.typ").compile(:html).document
|
|
53
|
-
# => "\n<!DOCTYPE html>\n<html>\n<head>\n<title>main</title>\n</head>\n<body>\n<svg class=\"typst-doc\" ...
|
|
69
|
+
=== Compile to HTML (using Typst expirmental HTML)
|
|
70
|
+
```ruby
|
|
71
|
+
doc = t.compile(:html_experimental)
|
|
72
|
+
```
|
|
54
73
|
|
|
55
|
-
|
|
74
|
+
=== Or return content as an array of bytes
|
|
75
|
+
```ruby
|
|
56
76
|
pdf_bytes = Typst("readme.typ").compile(:pdf).bytes
|
|
57
77
|
# => [37, 80, 68, 70, 45, 49, 46, 55, 10, 37, 128 ...]
|
|
78
|
+
```
|
|
58
79
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
=== Write the output to a file
|
|
81
|
+
Note: for multi-page documents using formats other than PDF and HTML, pages write to multiple files, e.g. `readme_0.png`, `readme_1.png`
|
|
82
|
+
```ruby
|
|
83
|
+
doc.write("filename.pdf")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
=== Return PDF, SVG, PNG or HTML content as an array of pages
|
|
87
|
+
```ruby
|
|
88
|
+
Typst("readme.typ").compile(:pdf).pages
|
|
89
|
+
# => ["%PDF-1.7\n%\x80\x80\x80\x80\n\n1 0 obj\n<<\n /Type /Pages\n /Count 3\n /Kids [160 0 R 162 ...
|
|
62
90
|
|
|
63
|
-
# Return SVG, HTML or PNG content as an array of pages
|
|
64
91
|
Typst("readme.typ").compile(:svg).pages
|
|
65
|
-
# => ["<svg class=\"typst-doc\" viewBox=\"0 0 595.2764999999999 841.89105\" ...
|
|
66
|
-
|
|
67
|
-
# => ["<svg class=\"typst-doc\" viewBox=\"0 0 595.2764999999999 841.89105\" ..."
|
|
92
|
+
# => ["<svg class=\"typst-doc\" viewBox=\"0 0 595.2764999999999 841.89105\" ...
|
|
93
|
+
|
|
68
94
|
Typst("readme.typ").compile(:png).pages
|
|
69
95
|
# => ["\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x04\xA7\x00\x00\x06\x94\b\ ...
|
|
70
96
|
|
|
71
|
-
|
|
97
|
+
Typst("readme.typ").compile(:html_experimental).pages
|
|
98
|
+
# => ["<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" ...
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
=== Pass values into typst using sys_inputs
|
|
102
|
+
```ruby
|
|
72
103
|
sys_inputs_example = %{
|
|
73
104
|
#let persons = json(bytes(sys.inputs.persons))
|
|
74
105
|
|
|
@@ -79,15 +110,18 @@ sys_inputs_example = %{
|
|
|
79
110
|
people = [{"name" => "John", "age" => 35}, {"name" => "Xoliswa", "age" => 45}]
|
|
80
111
|
data = { "persons" => people.to_json }
|
|
81
112
|
Typst(body: sys_inputs_example, sys_inputs: data).compile(:pdf).write("sys_inputs_example.pdf")
|
|
113
|
+
```
|
|
82
114
|
|
|
83
|
-
|
|
84
|
-
|
|
115
|
+
=== Apply inputs to typst to product multiple PDFs
|
|
116
|
+
```ruby
|
|
85
117
|
t = Typst(body: sys_inputs_example)
|
|
86
118
|
people.each do |person|
|
|
87
119
|
t.with_inputs({ "persons" => [person].to_json }).compile(:pdf).write("#{person['name']}.pdf")
|
|
88
120
|
end
|
|
121
|
+
```
|
|
89
122
|
|
|
90
|
-
|
|
123
|
+
=== A more complex example of compiling from string using other dependency typst template, svg and font resources all in memory
|
|
124
|
+
```ruby
|
|
91
125
|
main = %{
|
|
92
126
|
#import "template.typ": *
|
|
93
127
|
|
|
@@ -109,27 +143,65 @@ icon = File.read("icon.svg")
|
|
|
109
143
|
font_bytes = File.read("Example.ttf")
|
|
110
144
|
|
|
111
145
|
Typst(body: main, dependencies: { "template.typ" => template, "icon.svg" => icon }, fonts: { "Example.ttf" => font_bytes }).compile(:pdf)
|
|
146
|
+
```
|
|
112
147
|
|
|
113
|
-
|
|
148
|
+
=== From a zip with a named main typst file
|
|
149
|
+
```ruby
|
|
114
150
|
Typst(zip: "test/main.typ.zip", main_file: "hello.typ").compile(:pdf)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
=== Use a package from the #link("https://typst.app/universe")[Typst Universe]
|
|
154
|
+
Your package_example.typ file...
|
|
155
|
+
```typst
|
|
156
|
+
#import "@preview/wordometer:0.1.5": word-count, total-words
|
|
157
|
+
#show: word-count
|
|
158
|
+
|
|
159
|
+
In this document, there are #total-words words all up.
|
|
160
|
+
|
|
161
|
+
#word-count(total => [
|
|
162
|
+
The number of words in this block is #total.words
|
|
163
|
+
and there are #total.characters letters.
|
|
164
|
+
])
|
|
165
|
+
```
|
|
166
|
+
...compiles just like anything else
|
|
167
|
+
```ruby
|
|
168
|
+
Typst("package_example.typ").compile(:pdf).write("package_example.pdf")
|
|
169
|
+
```
|
|
115
170
|
|
|
116
|
-
|
|
171
|
+
=== Query a typst document
|
|
172
|
+
```ruby
|
|
173
|
+
Typst("readme.typ").query("heading").result
|
|
117
174
|
# =>
|
|
118
175
|
# [{"func" => "heading",
|
|
119
176
|
# "level" => 1,
|
|
120
177
|
# "depth" => 1,
|
|
121
178
|
# ...
|
|
122
179
|
|
|
123
|
-
Typst
|
|
180
|
+
Typst("readme.typ").query("heading", format: "json").result(raw: true)
|
|
124
181
|
# => "[\n {\n \"func\": \"heading\",\n \"level\": 1,\n \"depth\": ..."
|
|
125
182
|
|
|
126
|
-
Typst
|
|
183
|
+
Typst("readme.typ").query("heading", format: "yaml").result(raw: true)
|
|
127
184
|
# => "- func: heading\n level: 1\n depth: 1\n offset: 0\n numbering: ..."
|
|
128
185
|
|
|
186
|
+
# Query results as JSON string
|
|
187
|
+
Typst("test/test.typ").query("heading").to_s
|
|
188
|
+
# => "[\n {\n \"func\": \"heading\",\n \"level\": 1,\n \"depth\": 1,\n \"offset\": 0,\n ...
|
|
189
|
+
|
|
190
|
+
# Query results as YAML string
|
|
191
|
+
Typst("test/test.typ").query("heading", format: "yaml").to_s
|
|
192
|
+
# => "- func: heading\n level: 1\n depth: 1\n offset: 0\n numbering: null\n supplement:\n ...
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
=== clear the compilation cache
|
|
196
|
+
```ruby
|
|
197
|
+
# Evict all entries whose age is larger than or equal to `max_age`
|
|
198
|
+
max_age = 10
|
|
199
|
+
Typst::clear_cache(max_age)
|
|
129
200
|
```
|
|
130
201
|
|
|
131
202
|
== Contributors & Acknowledgements
|
|
132
|
-
typst-rb is based on #link("https://github.com/messense/typst-py")[typst-py] by #link("https://github.com/messense")[messense]
|
|
203
|
+
typst-rb is based on #link("https://github.com/messense/typst-py")[typst-py] by #link("https://github.com/messense")[messense]\
|
|
204
|
+
clear_cache was contributed by #link("https://github.com/NRicciVestmark")[NRicciVestmark]
|
|
133
205
|
|
|
134
206
|
== License
|
|
135
207
|
|
data/ext/typst/Cargo.toml
CHANGED
|
@@ -49,4 +49,4 @@ walkdir = "2.4.0"
|
|
|
49
49
|
|
|
50
50
|
# enable rb-sys feature to test against Ruby head. This is only needed if you
|
|
51
51
|
# want to work with the unreleased, in-development, next version of Ruby
|
|
52
|
-
rb-sys = { version = "0.9.
|
|
52
|
+
rb-sys = { version = "0.9.124", default-features = false, features = ["stable-api-compiled-fallback"] }
|
data/ext/typst/src/compiler.rs
CHANGED
|
@@ -6,7 +6,6 @@ use typst::diag::{Severity, SourceDiagnostic, StrResult, Warned};
|
|
|
6
6
|
use typst::foundations::Datetime;
|
|
7
7
|
use typst_html::HtmlDocument;
|
|
8
8
|
use typst::layout::PagedDocument;
|
|
9
|
-
//use typst::syntax::{FileId, Source, Span};
|
|
10
9
|
use typst::syntax::{FileId, Lines, Span};
|
|
11
10
|
use typst::{World, WorldExt};
|
|
12
11
|
|
data/ext/typst/src/download.rs
CHANGED
|
@@ -14,6 +14,6 @@ impl<T: Display> Progress for SlientDownload<T> {
|
|
|
14
14
|
|
|
15
15
|
/// Returns a new downloader.
|
|
16
16
|
pub fn downloader() -> Downloader {
|
|
17
|
-
let user_agent = concat!("typst-
|
|
17
|
+
let user_agent = concat!("typst-rb/", env!("CARGO_PKG_VERSION"));
|
|
18
18
|
Downloader::new(user_agent)
|
|
19
19
|
}
|
data/ext/typst/src/lib.rs
CHANGED
|
@@ -6,6 +6,7 @@ use std::collections::HashMap;
|
|
|
6
6
|
use query::{query as typst_query, QueryCommand, SerializationFormat};
|
|
7
7
|
use typst::foundations::{Dict, Value};
|
|
8
8
|
use typst_library::Feature;
|
|
9
|
+
use typst_pdf::PdfStandard;
|
|
9
10
|
use world::SystemWorld;
|
|
10
11
|
|
|
11
12
|
mod compiler;
|
|
@@ -144,6 +145,7 @@ fn to_png(
|
|
|
144
145
|
resource_path: PathBuf,
|
|
145
146
|
ignore_system_fonts: bool,
|
|
146
147
|
sys_inputs: HashMap<String, String>,
|
|
148
|
+
ppi: Option<f32>,
|
|
147
149
|
) -> Result<Vec<Vec<u8>>, Error> {
|
|
148
150
|
let input = input.canonicalize()
|
|
149
151
|
.map_err(|err| magnus::Error::new(ruby.exception_arg_error(), err.to_string()))?;
|
|
@@ -185,7 +187,7 @@ fn to_png(
|
|
|
185
187
|
.map_err(|msg| magnus::Error::new(ruby.exception_arg_error(), msg.to_string()))?;
|
|
186
188
|
|
|
187
189
|
let bytes = world
|
|
188
|
-
.compile(Some("png"),
|
|
190
|
+
.compile(Some("png"), ppi, &Vec::new())
|
|
189
191
|
.map_err(|msg| magnus::Error::new(ruby.exception_arg_error(), msg.to_string()))?;
|
|
190
192
|
|
|
191
193
|
Ok(bytes)
|
|
@@ -199,6 +201,7 @@ fn to_pdf(
|
|
|
199
201
|
resource_path: PathBuf,
|
|
200
202
|
ignore_system_fonts: bool,
|
|
201
203
|
sys_inputs: HashMap<String, String>,
|
|
204
|
+
pdf_standards: Vec<String>,
|
|
202
205
|
) -> Result<Vec<Vec<u8>>, Error> {
|
|
203
206
|
let input = input.canonicalize()
|
|
204
207
|
.map_err(|err| magnus::Error::new(ruby.exception_arg_error(), err.to_string()))?;
|
|
@@ -239,8 +242,37 @@ fn to_pdf(
|
|
|
239
242
|
.build()
|
|
240
243
|
.map_err(|msg| magnus::Error::new(ruby.exception_arg_error(), msg.to_string()))?;
|
|
241
244
|
|
|
245
|
+
let pdf_standards_lookup: HashMap::<&str, PdfStandard> = HashMap::from([
|
|
246
|
+
("1.4", PdfStandard::V_1_4),
|
|
247
|
+
("1.5", PdfStandard::V_1_5),
|
|
248
|
+
("1.6", PdfStandard::V_1_6),
|
|
249
|
+
("1.7", PdfStandard::V_1_7),
|
|
250
|
+
("2.0", PdfStandard::V_2_0),
|
|
251
|
+
("a-1a", PdfStandard::A_1a),
|
|
252
|
+
("a-1b", PdfStandard::A_1b),
|
|
253
|
+
("a-2a", PdfStandard::A_2a),
|
|
254
|
+
("a-2b", PdfStandard::A_2b),
|
|
255
|
+
("a-2u", PdfStandard::A_2u),
|
|
256
|
+
("a-3a", PdfStandard::A_3a),
|
|
257
|
+
("a-3b", PdfStandard::A_3b),
|
|
258
|
+
("a-3u", PdfStandard::A_3u),
|
|
259
|
+
("a-4", PdfStandard::A_4),
|
|
260
|
+
("a-4e", PdfStandard::A_4e),
|
|
261
|
+
("a-4f", PdfStandard::A_4f),
|
|
262
|
+
("ua-1", PdfStandard::Ua_1),
|
|
263
|
+
]);
|
|
264
|
+
|
|
265
|
+
let mut pdf_standards_vec = Vec::<PdfStandard>::new();
|
|
266
|
+
for pdf_standard in pdf_standards.iter() {
|
|
267
|
+
let result = pdf_standards_lookup.get(pdf_standard.as_str());
|
|
268
|
+
match result {
|
|
269
|
+
Some(value) => pdf_standards_vec.push(*value),
|
|
270
|
+
_ => return Err(magnus::Error::new(ruby.exception_arg_error(), "Unknown PdfStandard")),
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
242
274
|
let pdf_bytes = world
|
|
243
|
-
.compile(Some("pdf"), None, &
|
|
275
|
+
.compile(Some("pdf"), None, &pdf_standards_vec)
|
|
244
276
|
.map_err(|msg| magnus::Error::new(ruby.exception_arg_error(), msg.to_string()))?;
|
|
245
277
|
|
|
246
278
|
Ok(pdf_bytes)
|
|
@@ -320,15 +352,20 @@ fn query(
|
|
|
320
352
|
}
|
|
321
353
|
}
|
|
322
354
|
|
|
355
|
+
fn clear_cache(_ruby: &Ruby, max_age: usize) {
|
|
356
|
+
comemo::evict(max_age);
|
|
357
|
+
}
|
|
358
|
+
|
|
323
359
|
#[magnus::init]
|
|
324
360
|
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
325
361
|
env_logger::init();
|
|
326
362
|
|
|
327
363
|
let module = ruby.define_module("Typst")?;
|
|
328
|
-
module.define_singleton_method("_to_pdf", function!(to_pdf,
|
|
364
|
+
module.define_singleton_method("_to_pdf", function!(to_pdf, 7))?;
|
|
329
365
|
module.define_singleton_method("_to_svg", function!(to_svg, 6))?;
|
|
330
|
-
module.define_singleton_method("_to_png", function!(to_png,
|
|
366
|
+
module.define_singleton_method("_to_png", function!(to_png, 7))?;
|
|
331
367
|
module.define_singleton_method("_to_html", function!(to_html, 6))?;
|
|
332
368
|
module.define_singleton_method("_query", function!(query, 10))?;
|
|
369
|
+
module.define_singleton_method("_clear_cache", function!(clear_cache, 1))?;
|
|
333
370
|
Ok(())
|
|
334
371
|
}
|
data/ext/typst/src/query.rs
CHANGED
data/ext/typst/src/world.rs
CHANGED
|
@@ -3,7 +3,6 @@ use std::path::{Path, PathBuf};
|
|
|
3
3
|
use std::sync::{Mutex, OnceLock};
|
|
4
4
|
|
|
5
5
|
use chrono::{DateTime, Datelike, Local};
|
|
6
|
-
//use rustc_hash::FxHashMap;
|
|
7
6
|
use ecow::eco_format;
|
|
8
7
|
use typst::diag::{FileError, FileResult, StrResult};
|
|
9
8
|
use typst::foundations::{Bytes, Datetime, Dict};
|
data/lib/base.rb
CHANGED
|
@@ -34,74 +34,44 @@ module Typst
|
|
|
34
34
|
options[:dependencies] ||= {}
|
|
35
35
|
options[:fonts] ||= {}
|
|
36
36
|
options[:sys_inputs] ||= {}
|
|
37
|
+
options[:resource_path] ||= File.dirname(__FILE__)
|
|
38
|
+
options[:ignore_system_fonts] ||= false
|
|
37
39
|
|
|
38
40
|
self.options = options
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def typst_args
|
|
42
|
-
[options[:file], options[:root], options[:font_paths],
|
|
44
|
+
[options[:file], options[:root], options[:font_paths], options[:resource_path], options[:ignore_system_fonts], options[:sys_inputs].map{ |k,v| [k.to_s,v.to_s] }.to_h]
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Dir.mktmpdir do |tmp_dir|
|
|
50
|
-
tmp_main_file = Pathname.new(tmp_dir).join("main.typ")
|
|
51
|
-
File.write(tmp_main_file, main_source)
|
|
52
|
-
|
|
53
|
-
dependencies.each do |dep_name, dep_source|
|
|
54
|
-
tmp_dep_file = Pathname.new(tmp_dir).join(dep_name)
|
|
55
|
-
File.write(tmp_dep_file, dep_source)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
relative_font_path = Pathname.new(tmp_dir).join("fonts")
|
|
59
|
-
fonts.each do |font_name, font_bytes|
|
|
60
|
-
Pathname.new(relative_font_path).mkpath
|
|
61
|
-
tmp_font_file = relative_font_path.join(font_name)
|
|
62
|
-
File.write(tmp_font_file, font_bytes)
|
|
63
|
-
end
|
|
47
|
+
def typst_pdf_args
|
|
48
|
+
options[:pdf_standards] ||= []
|
|
49
|
+
[*typst_args, options[:pdf_standards]]
|
|
50
|
+
end
|
|
64
51
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
52
|
+
def typst_png_args
|
|
53
|
+
[*typst_args, options[:ppi]]
|
|
54
|
+
end
|
|
68
55
|
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
def self.from_s(main_source, **options)
|
|
57
|
+
Typst::build_world_from_s(main_source, **options) do |opts|
|
|
58
|
+
from_options = options.merge(opts)
|
|
59
|
+
if from_options[:format]
|
|
60
|
+
Typst::formats[from_options[:format]].new(**from_options)
|
|
71
61
|
else
|
|
72
|
-
new(**
|
|
62
|
+
new(**from_options)
|
|
73
63
|
end
|
|
74
64
|
end
|
|
75
65
|
end
|
|
76
66
|
|
|
77
|
-
def self.from_zip(zip_file_path, main_file =
|
|
78
|
-
options
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
when file_names.include?(main_file) then tmp_main_file = main_file
|
|
85
|
-
when file_names.include?("main.typ") then tmp_main_file = "main.typ"
|
|
86
|
-
when file_names.size == 1 then tmp_main_file = file_names.first
|
|
87
|
-
else raise "no main file found"
|
|
88
|
-
end
|
|
89
|
-
main_source = zipfile.file.read(tmp_main_file)
|
|
90
|
-
file_names.delete(tmp_main_file)
|
|
91
|
-
file_names.delete("fonts/")
|
|
92
|
-
|
|
93
|
-
file_names.each do |dep_name|
|
|
94
|
-
options[:dependencies][dep_name] = zipfile.file.read(dep_name)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
font_file_names = zipfile.dir.glob("fonts/*").collect{ |f| f.name }
|
|
98
|
-
font_file_names.each do |font_name|
|
|
99
|
-
options[:fonts][Pathname.new(font_name).basename.to_s] = zipfile.file.read(font_name)
|
|
67
|
+
def self.from_zip(zip_file_path, main_file = "main.typ", **options)
|
|
68
|
+
Typst::build_world_from_zip(zip_file_path, main_file, **options) do |opts|
|
|
69
|
+
from_options = options.merge(opts)
|
|
70
|
+
if from_options[:format]
|
|
71
|
+
Typst::formats[from_options[:format]].new(**from_options)
|
|
72
|
+
else
|
|
73
|
+
new(**from_options)
|
|
100
74
|
end
|
|
101
|
-
|
|
102
|
-
options[:main_file] = tmp_main_file
|
|
103
|
-
|
|
104
|
-
from_s(main_source, **options)
|
|
105
75
|
end
|
|
106
76
|
end
|
|
107
77
|
|
|
@@ -138,32 +108,35 @@ module Typst
|
|
|
138
108
|
if options.has_key?(:file)
|
|
139
109
|
Typst::formats[format].new(**options).compiled
|
|
140
110
|
elsif options.has_key?(:body)
|
|
141
|
-
Typst::
|
|
111
|
+
Typst::build_world_from_s(self.options[:body], **options) do |opts|
|
|
112
|
+
Typst::formats[format].new(**options.merge(opts)).compiled
|
|
113
|
+
end
|
|
142
114
|
elsif options.has_key?(:zip)
|
|
143
|
-
|
|
115
|
+
main_file = options[:main_file]
|
|
116
|
+
Typst::build_world_from_zip(options[:zip], main_file, **options) do |opts|
|
|
117
|
+
Typst::formats[format].new(**options.merge(opts)).compiled
|
|
118
|
+
end
|
|
144
119
|
else
|
|
145
120
|
raise "No input given"
|
|
146
121
|
end
|
|
147
122
|
end
|
|
148
123
|
|
|
149
|
-
def
|
|
150
|
-
|
|
151
|
-
compiled.write(output)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def document
|
|
155
|
-
STDERR.puts "DEPRECATION WARNING: this method will go away in a future version"
|
|
156
|
-
compiled.document
|
|
157
|
-
end
|
|
124
|
+
def query(selector, field: nil, one: false, format: "json")
|
|
125
|
+
query_options = { field: field, one: one, format: format }
|
|
158
126
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
127
|
+
if self.options.has_key?(:file)
|
|
128
|
+
Typst::Query.new(selector, self.options[:file], **query_options.merge(self.options.slice(:root, :font_paths, :resource_path, :ignore_system_fonts, :sys_inputs)))
|
|
129
|
+
elsif self.options.has_key?(:body)
|
|
130
|
+
Typst::build_world_from_s(self.options[:body], **self.options) do |opts|
|
|
131
|
+
Typst::Query.new(selector, opts[:file], **query_options.merge(opts.slice(:root, :font_paths, :resource_path, :ignore_system_fonts, :sys_inputs)))
|
|
132
|
+
end
|
|
133
|
+
elsif self.options.has_key?(:zip)
|
|
134
|
+
Typst::build_world_from_zip(self.options[:zip], **self.options) do |opts|
|
|
135
|
+
Typst::Query.new(selector, opts[:file], **query_options.merge(opts.slice(:root, :font_paths, :resource_path, :ignore_system_fonts, :sys_inputs)))
|
|
136
|
+
end
|
|
137
|
+
else
|
|
138
|
+
raise "No input given"
|
|
139
|
+
end
|
|
167
140
|
end
|
|
168
141
|
end
|
|
169
142
|
end
|
data/lib/document.rb
CHANGED
|
@@ -6,15 +6,23 @@ module Typst
|
|
|
6
6
|
@bytes = bytes
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def
|
|
9
|
+
def write_some(filename)
|
|
10
10
|
if pages.size == 1
|
|
11
|
-
|
|
11
|
+
write_one(filename)
|
|
12
12
|
else
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
write_paged(filename)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def write_one(filename)
|
|
18
|
+
File.write(filename, pages.first, mode: "wb")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def write_paged(base_filename)
|
|
22
|
+
pages.each_with_index do |page, i|
|
|
23
|
+
paged_filename = File.basename(base_filename, ".*") + "_{{n}}" + File.extname(base_filename) unless base_filename.include?("{{n}}")
|
|
24
|
+
paged_filename = paged_filename.gsub("{{n}}", (i+1).to_s)
|
|
25
|
+
File.write(paged_filename, page, mode: "wb")
|
|
18
26
|
end
|
|
19
27
|
end
|
|
20
28
|
|
|
@@ -5,7 +5,9 @@ module Typst
|
|
|
5
5
|
@compiled = HtmlExperimentalDocument.new(Typst::_to_html(*self.typst_args))
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
|
-
class HtmlExperimentalDocument < Document
|
|
8
|
+
class HtmlExperimentalDocument < Document
|
|
9
|
+
alias_method :write, :write_one
|
|
10
|
+
end
|
|
9
11
|
|
|
10
12
|
register_format(html_experimental: HtmlExperimental)
|
|
11
13
|
end
|
data/lib/formats/pdf.rb
CHANGED
|
@@ -2,10 +2,12 @@ module Typst
|
|
|
2
2
|
class Pdf < Base
|
|
3
3
|
def initialize(*options)
|
|
4
4
|
super(*options)
|
|
5
|
-
@compiled = PdfDocument.new(Typst::_to_pdf(*self.
|
|
5
|
+
@compiled = PdfDocument.new(Typst::_to_pdf(*self.typst_pdf_args))
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
|
-
class PdfDocument < Document
|
|
8
|
+
class PdfDocument < Document
|
|
9
|
+
alias_method :write, :write_one
|
|
10
|
+
end
|
|
9
11
|
|
|
10
12
|
register_format(pdf: Pdf)
|
|
11
13
|
end
|
data/lib/formats/png.rb
CHANGED
|
@@ -2,10 +2,12 @@ module Typst
|
|
|
2
2
|
class Png < Base
|
|
3
3
|
def initialize(*options)
|
|
4
4
|
super(*options)
|
|
5
|
-
@compiled = PngDocument.new(Typst::_to_png(*self.
|
|
5
|
+
@compiled = PngDocument.new(Typst::_to_png(*self.typst_png_args))
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
|
-
class PngDocument < Document
|
|
8
|
+
class PngDocument < Document
|
|
9
|
+
alias_method :write, :write_some
|
|
10
|
+
end
|
|
9
11
|
|
|
10
12
|
register_format(png: Png)
|
|
11
13
|
end
|
data/lib/formats/svg.rb
CHANGED
data/lib/query.rb
CHANGED
|
@@ -2,10 +2,9 @@ module Typst
|
|
|
2
2
|
class Query < Base
|
|
3
3
|
attr_accessor :format
|
|
4
4
|
|
|
5
|
-
def initialize(selector, input, field: nil, one: false, format: "json", root: ".", font_paths: [], sys_inputs: {})
|
|
6
|
-
super(input, root: root, font_paths: font_paths, sys_inputs: sys_inputs)
|
|
5
|
+
def initialize(selector, input, field: nil, one: false, format: "json", root: ".", font_paths: [], resource_path: ".", ignore_system_fonts: false, sys_inputs: {})
|
|
7
6
|
self.format = format
|
|
8
|
-
@result = Typst::_query(selector, field, one, format, input, root, font_paths,
|
|
7
|
+
@result = Typst::_query(selector, field, one, format, input, root, font_paths, resource_path, ignore_system_fonts, sys_inputs)
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
def result(raw: false)
|
|
@@ -15,5 +14,9 @@ module Typst
|
|
|
15
14
|
else @result
|
|
16
15
|
end
|
|
17
16
|
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
@result
|
|
20
|
+
end
|
|
18
21
|
end
|
|
19
22
|
end
|
data/lib/typst.rb
CHANGED
|
@@ -8,23 +8,87 @@ module Typst
|
|
|
8
8
|
def self.register_format(**format)
|
|
9
9
|
@@formats.merge!(format)
|
|
10
10
|
end
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
def self.formats
|
|
13
13
|
@@formats
|
|
14
14
|
end
|
|
15
|
-
end
|
|
16
15
|
|
|
16
|
+
def self.clear_cache(max_age = 0)
|
|
17
|
+
Typst::_clear_cache(max_age)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.build_world_from_s(main_source, **options, &blk)
|
|
21
|
+
dependencies = options[:dependencies] ||= {}
|
|
22
|
+
fonts = options[:fonts] ||= {}
|
|
23
|
+
|
|
24
|
+
Dir.mktmpdir do |tmp_dir|
|
|
25
|
+
tmp_main_file = Pathname.new(tmp_dir).join("main.typ")
|
|
26
|
+
File.write(tmp_main_file, main_source)
|
|
27
|
+
|
|
28
|
+
dependencies.each do |dep_name, dep_source|
|
|
29
|
+
tmp_dep_file = Pathname.new(tmp_dir).join(dep_name)
|
|
30
|
+
File.binwrite(tmp_dep_file, dep_source)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
relative_font_path = Pathname.new(tmp_dir).join("fonts")
|
|
34
|
+
relative_font_path.mkpath
|
|
35
|
+
fonts.each do |font_name, font_bytes|
|
|
36
|
+
tmp_font_file = relative_font_path.join(font_name)
|
|
37
|
+
File.binwrite(tmp_font_file, font_bytes)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
options[:file] = tmp_main_file
|
|
41
|
+
options[:root] = tmp_dir
|
|
42
|
+
options[:font_paths] = [relative_font_path]
|
|
43
|
+
|
|
44
|
+
blk.call(options)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.build_world_from_zip(zip_file_path, main_file = "main.typ", **options, &blk)
|
|
49
|
+
options[:dependencies] ||= {}
|
|
50
|
+
options[:fonts] ||= {}
|
|
51
|
+
|
|
52
|
+
Zip::File.open(zip_file_path) do |zipfile|
|
|
53
|
+
file_names = zipfile.dir.glob("*").collect{ |f| f.name }
|
|
54
|
+
case
|
|
55
|
+
when file_names.include?(main_file) then tmp_main_file = main_file
|
|
56
|
+
when file_names.include?("main.typ") then tmp_main_file = "main.typ"
|
|
57
|
+
when file_names.size == 1 then tmp_main_file = file_names.first
|
|
58
|
+
else raise "no main file found"
|
|
59
|
+
end
|
|
60
|
+
main_source = zipfile.file.read(tmp_main_file)
|
|
61
|
+
file_names.delete(tmp_main_file)
|
|
62
|
+
file_names.delete("fonts/")
|
|
63
|
+
|
|
64
|
+
file_names.each do |dep_name|
|
|
65
|
+
options[:dependencies][dep_name] = zipfile.file.read(dep_name)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
font_file_names = zipfile.dir.glob("fonts/*").collect{ |f| f.name }
|
|
69
|
+
font_file_names.each do |font_name|
|
|
70
|
+
options[:fonts][Pathname.new(font_name).basename.to_s] = zipfile.file.read(font_name)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
options[:main_file] = tmp_main_file
|
|
74
|
+
|
|
75
|
+
build_world_from_s(main_source, **options, &blk)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
17
79
|
|
|
18
|
-
require "cgi"
|
|
80
|
+
require "cgi/escape"
|
|
19
81
|
require "pathname"
|
|
20
82
|
require "tmpdir"
|
|
21
83
|
require "zip/filesystem"
|
|
84
|
+
require "json"
|
|
85
|
+
require "yaml"
|
|
22
86
|
|
|
23
87
|
begin
|
|
24
88
|
# native precompiled gems package shared libraries in <gem_dir>/lib/typst/<ruby_version>
|
|
25
89
|
RUBY_VERSION =~ /(\d+\.\d+)/
|
|
26
90
|
require_relative "typst/#{Regexp.last_match(1)}/typst"
|
|
27
|
-
rescue LoadError
|
|
91
|
+
rescue LoadError
|
|
28
92
|
require_relative "typst/typst"
|
|
29
93
|
end
|
|
30
94
|
|
|
@@ -34,5 +98,4 @@ require_relative "document"
|
|
|
34
98
|
require_relative "formats/pdf"
|
|
35
99
|
require_relative "formats/svg"
|
|
36
100
|
require_relative "formats/png"
|
|
37
|
-
require_relative "formats/html"
|
|
38
101
|
require_relative "formats/html_experimental"
|
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.14.2.
|
|
4
|
+
version: 0.14.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Flinn
|
|
@@ -18,7 +18,7 @@ dependencies:
|
|
|
18
18
|
version: '0.9'
|
|
19
19
|
- - ">="
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 0.9.
|
|
21
|
+
version: 0.9.124
|
|
22
22
|
type: :runtime
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -28,7 +28,7 @@ dependencies:
|
|
|
28
28
|
version: '0.9'
|
|
29
29
|
- - ">="
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
|
-
version: 0.9.
|
|
31
|
+
version: 0.9.124
|
|
32
32
|
- !ruby/object:Gem::Dependency
|
|
33
33
|
name: rubyzip
|
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -71,6 +71,34 @@ dependencies:
|
|
|
71
71
|
- - "~>"
|
|
72
72
|
- !ruby/object:Gem::Version
|
|
73
73
|
version: '3.6'
|
|
74
|
+
- !ruby/object:Gem::Dependency
|
|
75
|
+
name: os
|
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - "~>"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '1.1'
|
|
81
|
+
type: :development
|
|
82
|
+
prerelease: false
|
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '1.1'
|
|
88
|
+
- !ruby/object:Gem::Dependency
|
|
89
|
+
name: pngcheck
|
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - "~>"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '0.3'
|
|
95
|
+
type: :development
|
|
96
|
+
prerelease: false
|
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - "~>"
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0.3'
|
|
74
102
|
email: flinn@actsasflinn.com
|
|
75
103
|
executables: []
|
|
76
104
|
extensions:
|
|
@@ -106,14 +134,12 @@ files:
|
|
|
106
134
|
- lib/fonts/NewCM10-Regular.otf
|
|
107
135
|
- lib/fonts/NewCMMath-Book.otf
|
|
108
136
|
- lib/fonts/NewCMMath-Regular.otf
|
|
109
|
-
- lib/formats/html.rb
|
|
110
137
|
- lib/formats/html_experimental.rb
|
|
111
138
|
- lib/formats/pdf.rb
|
|
112
139
|
- lib/formats/png.rb
|
|
113
140
|
- lib/formats/svg.rb
|
|
114
141
|
- lib/query.rb
|
|
115
142
|
- lib/typst.rb
|
|
116
|
-
- lib/typst/typst.bundle
|
|
117
143
|
homepage: https://github.com/actsasflinn/typst-rb
|
|
118
144
|
licenses:
|
|
119
145
|
- Apache-2.0
|
|
@@ -132,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
132
158
|
- !ruby/object:Gem::Version
|
|
133
159
|
version: '0'
|
|
134
160
|
requirements: []
|
|
135
|
-
rubygems_version:
|
|
161
|
+
rubygems_version: 4.0.4
|
|
136
162
|
specification_version: 4
|
|
137
163
|
summary: Ruby binding to typst, a new markup-based typesetting system that is powerful
|
|
138
164
|
and easy to learn.
|
data/lib/formats/html.rb
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module Typst
|
|
2
|
-
class Html < Base
|
|
3
|
-
def initialize(*options)
|
|
4
|
-
super(*options)
|
|
5
|
-
title = CGI::escapeHTML(@options[:title] || File.basename(@options[:file], ".*"))
|
|
6
|
-
@compiled = HtmlDocument.new(Typst::_to_svg(*self.typst_args), title)
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
class HtmlDocument < Document
|
|
11
|
-
attr_accessor :title
|
|
12
|
-
|
|
13
|
-
def initialize(bytes, title)
|
|
14
|
-
super(bytes)
|
|
15
|
-
self.title = title
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def markup
|
|
19
|
-
%{
|
|
20
|
-
<!DOCTYPE html>
|
|
21
|
-
<html>
|
|
22
|
-
<head>
|
|
23
|
-
<title>#{title}</title>
|
|
24
|
-
</head>
|
|
25
|
-
<body>
|
|
26
|
-
#{pages.join("<br />")}
|
|
27
|
-
</body>
|
|
28
|
-
</html>
|
|
29
|
-
}
|
|
30
|
-
end
|
|
31
|
-
alias_method :document, :markup
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
register_format(html: Html)
|
|
35
|
-
end
|
data/lib/typst/typst.bundle
DELETED
|
Binary file
|