@@ -2,7 +2,7 @@ use super::{Error, Result};
2
2
use crate :: ipc:: commands:: project;
3
3
use crate :: ipc:: model:: TypstRenderResponse ;
4
4
use crate :: ipc:: {
5
- TypstCompileEvent , TypstDiagnosticSeverity , TypstDocument , TypstPage , TypstSourceDiagnostic
5
+ TypstCompileEvent , TypstDiagnosticSeverity , TypstDocument , TypstPage , TypstSourceDiagnostic ,
6
6
} ;
7
7
use crate :: project:: ProjectManager ;
8
8
use base64:: Engine ;
@@ -11,6 +11,7 @@ use serde::Serialize;
11
11
use serde_repr:: Serialize_repr ;
12
12
use siphasher:: sip128:: { Hasher128 , SipHasher } ;
13
13
use std:: hash:: Hash ;
14
+ use std:: ops:: Range ;
14
15
use std:: path:: PathBuf ;
15
16
use std:: sync:: Arc ;
16
17
use std:: time:: Instant ;
@@ -72,7 +73,7 @@ pub async fn typst_slot_update<R: Runtime>(
72
73
content : String ,
73
74
) -> Result < ( ) > {
74
75
let project = project ( & window, & project_manager) ?;
75
-
76
+
76
77
let mut world = project. world . lock ( ) . unwrap ( ) ;
77
78
let _ = world
78
79
. slot_update ( & path, Some ( content) )
@@ -86,7 +87,7 @@ pub async fn typst_compile_doc<R: Runtime>(
86
87
project_manager : tauri:: State < ' _ , Arc < ProjectManager < R > > > ,
87
88
path : PathBuf ,
88
89
content : String ,
89
- ) -> Result < Vec < TypstPage > > {
90
+ ) -> Result < ( Vec < TypstPage > , Vec < TypstSourceDiagnostic > ) > {
90
91
let project = project ( & window, & project_manager) ?;
91
92
92
93
let mut world = project. world . lock ( ) . unwrap ( ) ;
@@ -105,7 +106,8 @@ pub async fn typst_compile_doc<R: Runtime>(
105
106
debug ! ( "compiling {:?}: {:?}" , path, project) ;
106
107
let now = Instant :: now ( ) ;
107
108
let mut tracer = Tracer :: new ( ) ;
108
- let mut res: Vec < TypstPage > = Vec :: new ( ) ;
109
+ let mut pages: Vec < TypstPage > = Vec :: new ( ) ;
110
+ let mut diags: Vec < TypstSourceDiagnostic > = Vec :: new ( ) ;
109
111
match typst:: compile ( & * world, & mut tracer) {
110
112
Ok ( doc) => {
111
113
let elapsed = now. elapsed ( ) ;
@@ -114,31 +116,27 @@ pub async fn typst_compile_doc<R: Runtime>(
114
116
project,
115
117
elapsed. as_millis( )
116
118
) ;
117
- let mut idx: u32 = 0 ;
119
+ let mut idx: u32 = 0 ;
118
120
for page in & doc. pages {
119
121
let mut hasher = SipHasher :: new ( ) ;
120
122
page. frame . hash ( & mut hasher) ;
121
123
let hash = hex:: encode ( hasher. finish128 ( ) . as_bytes ( ) ) ;
122
- let width = page. frame . width ( ) . to_pt ( ) ;
124
+ let width = page. frame . width ( ) . to_pt ( ) ;
123
125
let height = page. frame . height ( ) . to_pt ( ) ;
124
- idx +=1 ;
125
- let pag = TypstPage {
126
+ idx += 1 ;
127
+ let pag = TypstPage {
126
128
num : idx,
127
129
width,
128
130
height,
129
- hash : hash. clone ( )
131
+ hash : hash. clone ( ) ,
130
132
} ;
131
- res . push ( pag) ;
133
+ pages . push ( pag) ;
132
134
}
133
135
134
136
project. cache . write ( ) . unwrap ( ) . document = Some ( doc) ;
135
-
136
137
}
137
138
Err ( diagnostics) => {
138
- debug ! (
139
- "compilation failed with {:?} diagnostics" ,
140
- & diagnostics
141
- ) ;
139
+ debug ! ( "compilation failed with {:?} diagnostics" , & diagnostics) ;
142
140
143
141
let source = world. source ( source_id) ;
144
142
let diagnostics: Vec < TypstSourceDiagnostic > = match source {
@@ -148,13 +146,11 @@ pub async fn typst_compile_doc<R: Runtime>(
148
146
. filter_map ( |d| {
149
147
let span = source. find ( d. span ) ?;
150
148
let range = span. range ( ) ;
151
- let start = content[ ..range. start ] . chars ( ) . count ( ) ;
152
- let size = content[ range. start ..range. end ] . chars ( ) . count ( ) ;
153
149
154
150
let message = d. message . to_string ( ) ;
155
- info ! ( "############## {}" , & message) ;
156
151
Some ( TypstSourceDiagnostic {
157
- range : start..start + size,
152
+ pos : get_range_position ( & content, range. clone ( ) ) ,
153
+ range,
158
154
severity : match d. severity {
159
155
Severity :: Error => TypstDiagnosticSeverity :: Error ,
160
156
Severity :: Warning => TypstDiagnosticSeverity :: Warning ,
@@ -167,123 +163,32 @@ pub async fn typst_compile_doc<R: Runtime>(
167
163
Err ( _) => vec ! [ ] ,
168
164
} ;
169
165
170
- info ! ( "############## {:?}" , & diagnostics) ;
171
-
166
+ diags = diagnostics. clone ( ) ;
172
167
173
-
174
-
168
+ info ! ( "############## {:?}" , & diags) ;
175
169
}
176
170
}
177
171
178
- Ok ( res )
172
+ Ok ( ( pages , diags ) )
179
173
}
180
174
181
- #[ tauri:: command]
182
- pub async fn typst_compile < R : Runtime > (
183
- window : tauri:: Window < R > ,
184
- project_manager : tauri:: State < ' _ , Arc < ProjectManager < R > > > ,
185
- path : PathBuf ,
186
- content : String ,
187
- ) -> Result < ( ) > {
188
- let project = project ( & window, & project_manager) ?;
189
-
190
- let mut world = project. world . lock ( ) . unwrap ( ) ;
191
- let source_id = world
192
- . slot_update ( & path, Some ( content. clone ( ) ) )
193
- . map_err ( Into :: < Error > :: into) ?;
194
-
195
- if !world. is_main_set ( ) {
196
- let config = project. config . read ( ) . unwrap ( ) ;
197
- if config. apply_main ( & project, & mut world) . is_err ( ) {
198
- debug ! ( "skipped compilation for {:?} (main not set)" , project) ;
199
- return Ok ( ( ) ) ;
200
- }
201
- }
202
-
203
- debug ! ( "compiling {:?}: {:?}" , path, project) ;
204
- let now = Instant :: now ( ) ;
205
- let mut tracer = Tracer :: new ( ) ;
206
- match typst:: compile ( & * world, & mut tracer) {
207
- Ok ( doc) => {
208
- let elapsed = now. elapsed ( ) ;
209
- debug ! (
210
- "compilation succeeded for {:?} in {:?} ms" ,
211
- project,
212
- elapsed. as_millis( )
213
- ) ;
214
-
215
- let pages = doc. pages . len ( ) ;
216
-
217
- let mut hasher = SipHasher :: new ( ) ;
218
- for page in & doc. pages {
219
- page. frame . hash ( & mut hasher) ;
220
- }
221
- let hash = hex:: encode ( hasher. finish128 ( ) . as_bytes ( ) ) ;
222
-
223
- // Assume all pages have the same size
224
- // TODO: Improve this?
225
- let first_page = & doc. pages [ 0 ] ;
226
- let width = first_page. frame . width ( ) ;
227
- let height = first_page. frame . height ( ) ;
228
-
229
- project. cache . write ( ) . unwrap ( ) . document = Some ( doc) ;
230
-
231
- let _ = window. emit (
232
- "typst_compile" ,
233
- TypstCompileEvent {
234
- document : Some ( TypstDocument {
235
- pages,
236
- hash,
237
- width : width. to_pt ( ) ,
238
- height : height. to_pt ( ) ,
239
- } ) ,
240
- diagnostics : None ,
241
- } ,
242
- ) ;
175
+ pub fn get_range_position ( text : & str , rang : Range < usize > ) -> ( usize , usize ) {
176
+ let mut ln = 0 ;
177
+ let mut cn = 0 ;
178
+ let mut total: usize = 0 ;
179
+ for line in text. lines ( ) {
180
+
181
+ ln += 1 ;
182
+ let row = line. chars ( ) . count ( ) + 1 ;
183
+
184
+ if total <= rang. start && rang. start <= total + row {
185
+ cn = rang. start - total;
186
+ break ;
243
187
}
244
- Err ( diagnostics) => {
245
- debug ! (
246
- "compilation failed with {:?} diagnostics" ,
247
- diagnostics. len( )
248
- ) ;
249
-
250
- let source = world. source ( source_id) ;
251
- let diagnostics: Vec < TypstSourceDiagnostic > = match source {
252
- Ok ( source) => diagnostics
253
- . iter ( )
254
- . filter ( |d| d. span . id ( ) == Some ( source_id) )
255
- . filter_map ( |d| {
256
- let span = source. find ( d. span ) ?;
257
- let range = span. range ( ) ;
258
- let start = content[ ..range. start ] . chars ( ) . count ( ) ;
259
- let size = content[ range. start ..range. end ] . chars ( ) . count ( ) ;
260
-
261
- let message = d. message . to_string ( ) ;
262
- Some ( TypstSourceDiagnostic {
263
- range : start..start + size,
264
- severity : match d. severity {
265
- Severity :: Error => TypstDiagnosticSeverity :: Error ,
266
- Severity :: Warning => TypstDiagnosticSeverity :: Warning ,
267
- } ,
268
- message,
269
- hints : d. hints . iter ( ) . map ( |hint| hint. to_string ( ) ) . collect ( ) ,
270
- } )
271
- } )
272
- . collect ( ) ,
273
- Err ( _) => vec ! [ ] ,
274
- } ;
275
188
276
- let _ = window. emit (
277
- "typst_compile" ,
278
- TypstCompileEvent {
279
- document : None ,
280
- diagnostics : Some ( diagnostics) ,
281
- } ,
282
- ) ;
283
- }
189
+ total += row;
284
190
}
285
-
286
- Ok ( ( ) )
191
+ return ( ln, cn) ;
287
192
}
288
193
289
194
#[ tauri:: command]
@@ -294,17 +199,23 @@ pub async fn typst_render<R: Runtime>(
294
199
scale : f32 ,
295
200
nonce : u32 ,
296
201
) -> Result < TypstRenderResponse > {
297
-
298
- info ! ( "typst_render page:{} scale: {} nonce: {}" , page, scale, nonce) ;
202
+ info ! (
203
+ "typst_render page:{} scale: {} nonce: {}" ,
204
+ page, scale, nonce
205
+ ) ;
299
206
let project = project_manager
300
207
. get_project ( & window)
301
208
. ok_or ( Error :: UnknownProject ) ?;
302
-
209
+
303
210
let cache = project. cache . read ( ) . unwrap ( ) ;
304
-
305
- if let Some ( p) = cache. document . as_ref ( ) . and_then ( |doc| doc. pages . get ( page-1 ) ) {
211
+
212
+ if let Some ( p) = cache
213
+ . document
214
+ . as_ref ( )
215
+ . and_then ( |doc| doc. pages . get ( page - 1 ) )
216
+ {
306
217
let now = Instant :: now ( ) ;
307
-
218
+
308
219
let bmp = typst_render:: render ( & p. frame , scale, Color :: WHITE ) ;
309
220
if let Ok ( image) = bmp. encode_png ( ) {
310
221
let elapsed = now. elapsed ( ) ;
0 commit comments