Skip to content

Commit 50bea01

Browse files
authored
Merge pull request #73 from rekka/feat-synctex
Add the --synctex command line option
2 parents 3cc0c8d + 45b777e commit 50bea01

File tree

10 files changed

+104
-94
lines changed

10 files changed

+104
-94
lines changed

src/cli_driver.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ struct ProcessingSession {
260260
keep_intermediates: bool,
261261
keep_logs: bool,
262262
noted_tex_warnings: bool,
263+
synctex_enabled: bool,
263264
}
264265

265266

@@ -345,6 +346,7 @@ impl ProcessingSession {
345346
keep_intermediates: args.is_present("keep_intermediates"),
346347
keep_logs: args.is_present("keep_logs"),
347348
noted_tex_warnings: false,
349+
synctex_enabled: args.is_present("synctex"),
348350
})
349351
}
350352

@@ -636,10 +638,10 @@ impl ProcessingSession {
636638

637639
let result = {
638640
let mut stack = self.io.as_stack(false);
639-
let mut engine = TexEngine::new();
640-
engine.set_halt_on_error_mode(true);
641-
engine.set_initex_mode(true);
642-
engine.process(&mut stack, &mut self.events, status, "UNUSED.fmt.gz",
641+
TexEngine::new()
642+
.halt_on_error_mode(true)
643+
.initex_mode(true)
644+
.process(&mut stack, &mut self.events, status, "UNUSED.fmt.gz",
643645
&format!("tectonic-format-{}.tex", stem))
644646
};
645647

@@ -697,16 +699,18 @@ impl ProcessingSession {
697699
fn tex_pass(&mut self, rerun_explanation: Option<&str>, status: &mut TermcolorStatusBackend) -> Result<i32> {
698700
let result = {
699701
let mut stack = self.io.as_stack(true);
700-
let mut engine = TexEngine::new();
701-
engine.set_halt_on_error_mode(true);
702-
engine.set_initex_mode(self.output_format == OutputFormat::Format);
703702
if let Some(s) = rerun_explanation {
704703
status.note_highlighted("Rerunning ", "TeX", &format!(" because {} ...", s));
705704
} else {
706705
status.note_highlighted("Running ", "TeX", " ...");
707706
}
708-
engine.process(&mut stack, &mut self.events, status,
709-
&self.format_path, &self.tex_path)
707+
708+
TexEngine::new()
709+
.halt_on_error_mode(true)
710+
.initex_mode(self.output_format == OutputFormat::Format)
711+
.synctex(self.synctex_enabled)
712+
.process(&mut stack, &mut self.events, status,
713+
&self.format_path, &self.tex_path)
710714
};
711715

712716
match result {
@@ -848,6 +852,9 @@ fn main() {
848852
.arg(Arg::with_name("keep_logs")
849853
.long("keep-logs")
850854
.help("Keep the log files generated during processing."))
855+
.arg(Arg::with_name("synctex")
856+
.long("synctex")
857+
.help("Generate SyncTeX data."))
851858
.arg(Arg::with_name("hide")
852859
.long("hide")
853860
.value_name("PATH")

src/engines/tex.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,48 @@ pub enum TexResult {
2121
Errors,
2222
}
2323

24-
24+
#[derive(Debug)]
2525
pub struct TexEngine {
2626
// One day, the engine will hold its own state. For the time being,
2727
// though, it's just a proxy for the global constants in the C code.
28+
29+
halt_on_error: bool,
30+
initex_mode: bool,
31+
synctex_enabled: bool,
2832
}
2933

34+
impl Default for TexEngine {
35+
fn default() -> Self {
36+
TexEngine {
37+
halt_on_error: true,
38+
initex_mode: false,
39+
synctex_enabled: false,
40+
}
41+
}
42+
}
3043

3144
impl TexEngine {
3245
pub fn new () -> TexEngine {
33-
TexEngine {}
46+
TexEngine::default()
3447
}
3548

36-
pub fn set_halt_on_error_mode (&mut self, halt_on_error: bool) {
37-
let v = if halt_on_error { 1 } else { 0 };
38-
unsafe { super::tt_set_int_variable(b"halt_on_error_p\0".as_ptr(), v); }
49+
pub fn halt_on_error_mode (&mut self, halt_on_error: bool) -> &mut Self {
50+
self.halt_on_error = halt_on_error;
51+
self
3952
}
4053

4154
/// Configure the engine to run in "initex" mode, in which it generates a
4255
/// "format" file that serializes the engine state rather than a PDF
4356
/// document.
44-
pub fn set_initex_mode (&mut self, initex: bool) {
45-
let v = if initex { 1 } else { 0 };
46-
unsafe { super::tt_set_int_variable(b"in_initex_mode\0".as_ptr(), v); }
57+
pub fn initex_mode (&mut self, initex: bool) -> &mut Self {
58+
self.initex_mode = initex;
59+
self
60+
}
61+
62+
/// Configure the engine to produce SyncTeX data.
63+
pub fn synctex (&mut self, synctex_enabled: bool) -> &mut Self {
64+
self.synctex_enabled = synctex_enabled;
65+
self
4766
}
4867

4968
// This function can't be generic across the IoProvider trait, for now,
@@ -60,6 +79,14 @@ impl TexEngine {
6079
let /*mut*/ state = ExecutionState::new(io, events, status);
6180
let bridge = TectonicBridgeApi::new(&state);
6281

82+
// initialize globals
83+
let v = if self.halt_on_error { 1 } else { 0 };
84+
unsafe { super::tt_set_int_variable(b"halt_on_error_p\0".as_ptr(), v); }
85+
let v = if self.initex_mode { 1 } else { 0 };
86+
unsafe { super::tt_set_int_variable(b"in_initex_mode\0".as_ptr(), v); }
87+
let v = if self.synctex_enabled { 1 } else { 0 };
88+
unsafe { super::tt_set_int_variable(b"synctex_enabled\0".as_ptr(), v); }
89+
6390
unsafe {
6491
match super::tex_simple_main(&bridge, cformat.as_ptr(), cinput.as_ptr()) {
6592
0 => Ok(TexResult::Spotless),

tectonic/engine-interface.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ tt_set_int_variable (char *var_name, int value)
1717
halt_on_error_p = value;
1818
else if (STREQ (var_name, "in_initex_mode"))
1919
in_initex_mode = (value != 0);
20+
else if (STREQ (var_name, "synctex_enabled"))
21+
synctex_enabled = (value != 0);
2022
else
2123
return 1; /* Uh oh: unrecognized variable */
2224

tectonic/synctex.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,11 @@ synctex_init_command(void)
151151
synctex_ctxt.flags.warn = 0;
152152
synctex_ctxt.flags.output_p = 0;
153153

154-
INTPAR(synctex) = 0; /* \synctex=0 : don't record stuff */
154+
if (synctex_enabled) {
155+
INTPAR(synctex) = 1;
156+
} else {
157+
INTPAR(synctex) = 0; /* \synctex=0 : don't record stuff */
158+
}
155159
}
156160

157161

@@ -233,10 +237,11 @@ synctex_dot_open(void)
233237
+ 1);
234238
strcpy(the_name, tmp);
235239
strcat(the_name, synctex_suffix);
240+
strcat(the_name, synctex_suffix_gz);
236241
free(tmp);
237242
tmp = NULL;
238243

239-
synctex_ctxt.file = ttstub_output_open(the_name, 0);
244+
synctex_ctxt.file = ttstub_output_open(the_name, 1);
240245
if (synctex_ctxt.file == NULL)
241246
goto fail;
242247

tectonic/xetexd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ scaled base_x_height;
687687
scaled base_width, base_height;
688688
scaled accent_width, accent_height;
689689
scaled delta;
690+
int synctex_enabled;
690691

691692
/*:1683*/
692693

tests/formats.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ fn test_format_generation(subdir: &str, texname: &str, fmtname: &str, sha256: &s
111111
])
112112
};
113113

114-
let mut e = TexEngine::new();
115-
e.set_initex_mode(true);
116-
e.process(&mut io, &mut events,
117-
&mut NoopStatusBackend::new(), "unused.fmt.gz", texname).unwrap();
114+
TexEngine::new()
115+
.initex_mode(true)
116+
.process(&mut io, &mut events,
117+
&mut NoopStatusBackend::new(), "unused.fmt.gz", texname).unwrap();
118118
}
119119

120120
// Did we get what we expected?

tests/tex-outputs.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Copyright 2016-2017 the Tectonic Project
22
// Licensed under the MIT License.
33

4+
extern crate flate2;
45
#[macro_use] extern crate lazy_static;
56
extern crate tectonic;
67

8+
use flate2::read::GzDecoder;
79
use std::collections::HashSet;
810
use std::ffi::OsStr;
911
use std::fs::File;
@@ -44,11 +46,11 @@ fn set_up_format_file(tests_dir: &Path) -> Result<SingleInputFileIo> {
4446
&mut fs,
4547
]);
4648

47-
let mut e = TexEngine::new();
48-
e.set_halt_on_error_mode(true);
49-
e.set_initex_mode(true);
50-
e.process(&mut io, &mut NoopIoEventBackend::new(),
51-
&mut NoopStatusBackend::new(), "UNUSED.fmt.gz", "plain.tex")?;
49+
TexEngine::new()
50+
.halt_on_error_mode(true)
51+
.initex_mode(true)
52+
.process(&mut io, &mut NoopIoEventBackend::new(),
53+
&mut NoopStatusBackend::new(), "UNUSED.fmt.gz", "plain.tex")?;
5254
}
5355

5456
let mut fmt_file = File::create(&fmt_path)?;
@@ -131,10 +133,9 @@ fn do_one(stem: &str, check_synctex: bool) {
131133
&mut tex,
132134
&mut fmt,
133135
]);
134-
let mut e = TexEngine::new();
135-
e.set_initex_mode(false); // TODO: this shouldn't be necessary
136-
e.process(&mut io, &mut NoopIoEventBackend::new(),
137-
&mut NoopStatusBackend::new(), "plain.fmt.gz", &texname).unwrap();
136+
TexEngine::new()
137+
.process(&mut io, &mut NoopIoEventBackend::new(),
138+
&mut NoopStatusBackend::new(), "plain.fmt.gz", &texname).unwrap();
138139
}
139140

140141
// Check that log and xdv match expectations.
@@ -148,11 +149,16 @@ fn do_one(stem: &str, check_synctex: bool) {
148149
test_file(&xdvname, &expected_xdv, observed_xdv);
149150

150151
if check_synctex {
151-
p.set_extension("synctex");
152-
let expected_synctex = read_file(&p);
152+
p.set_extension("synctex.gz");
153+
// Gzipped files seem to be platform dependent and so we decompress them first.
154+
let mut expected_synctex = Vec::new();
155+
GzDecoder::new(File::open(&p).unwrap()).unwrap()
156+
.read_to_end(&mut expected_synctex).unwrap();
153157
let synctexname = p.file_name().unwrap().to_owned();
154-
let observed_synctex = files.get(&synctexname).unwrap();
155-
test_file(&synctexname, &expected_synctex, observed_synctex);
158+
let mut observed_synctex = Vec::new();
159+
GzDecoder::new(&files.get(&synctexname).unwrap()[..]).unwrap()
160+
.read_to_end(&mut observed_synctex).unwrap();
161+
test_file(&synctexname, &expected_synctex, &observed_synctex);
156162
}
157163
}
158164

tests/tex-outputs/synctex.synctex

Lines changed: 0 additions & 38 deletions
This file was deleted.

tests/tex-outputs/synctex.synctex.gz

333 Bytes
Binary file not shown.

tests/trip.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ fn trip_test() {
118118
&mut tex,
119119
&mut tfm,
120120
]);
121-
let mut e = TexEngine::new();
122-
e.set_halt_on_error_mode(false);
123-
e.set_initex_mode(true);
124-
e.process(&mut io, &mut NoopIoEventBackend::new(),
125-
&mut NoopStatusBackend::new(), "INITEX", "trip").unwrap();
121+
TexEngine::new()
122+
.halt_on_error_mode(false)
123+
.initex_mode(true)
124+
.process(&mut io, &mut NoopIoEventBackend::new(),
125+
&mut NoopStatusBackend::new(), "INITEX", "trip").unwrap();
126126
}
127127

128128
// Second pass -- process it
@@ -132,11 +132,11 @@ fn trip_test() {
132132
&mut tex,
133133
&mut tfm,
134134
]);
135-
let mut e = TexEngine::new();
136-
e.set_halt_on_error_mode(false);
137-
e.set_initex_mode(false);
138-
e.process(&mut io, &mut NoopIoEventBackend::new(),
139-
&mut NoopStatusBackend::new(), "trip.fmt.gz", "trip").unwrap();
135+
TexEngine::new()
136+
.halt_on_error_mode(false)
137+
.initex_mode(false)
138+
.process(&mut io, &mut NoopIoEventBackend::new(),
139+
&mut NoopStatusBackend::new(), "trip.fmt.gz", "trip").unwrap();
140140
}
141141

142142
// Check that outputs match expectations.
@@ -183,11 +183,11 @@ fn etrip_test() {
183183
&mut tex,
184184
&mut tfm,
185185
]);
186-
let mut e = TexEngine::new();
187-
e.set_halt_on_error_mode(false);
188-
e.set_initex_mode(true);
189-
e.process(&mut io, &mut NoopIoEventBackend::new(),
190-
&mut NoopStatusBackend::new(), "INITEX", "etrip").unwrap();
186+
TexEngine::new()
187+
.halt_on_error_mode(false)
188+
.initex_mode(true)
189+
.process(&mut io, &mut NoopIoEventBackend::new(),
190+
&mut NoopStatusBackend::new(), "INITEX", "etrip").unwrap();
191191
}
192192

193193
// Second pass -- process it
@@ -197,11 +197,11 @@ fn etrip_test() {
197197
&mut tex,
198198
&mut tfm,
199199
]);
200-
let mut e = TexEngine::new();
201-
e.set_halt_on_error_mode(false);
202-
e.set_initex_mode(false);
203-
e.process(&mut io, &mut NoopIoEventBackend::new(),
204-
&mut NoopStatusBackend::new(), "etrip.fmt.gz", "etrip").unwrap();
200+
TexEngine::new()
201+
.halt_on_error_mode(false)
202+
.initex_mode(false)
203+
.process(&mut io, &mut NoopIoEventBackend::new(),
204+
&mut NoopStatusBackend::new(), "etrip.fmt.gz", "etrip").unwrap();
205205
}
206206

207207
// Check that outputs match expectations.

0 commit comments

Comments
 (0)