summaryrefslogtreecommitdiff
path: root/support/texlab/crates/parser/src/latexmkrc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/parser/src/latexmkrc.rs')
-rw-r--r--support/texlab/crates/parser/src/latexmkrc.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/support/texlab/crates/parser/src/latexmkrc.rs b/support/texlab/crates/parser/src/latexmkrc.rs
new file mode 100644
index 0000000000..63c92bd353
--- /dev/null
+++ b/support/texlab/crates/parser/src/latexmkrc.rs
@@ -0,0 +1,52 @@
+use syntax::latexmkrc::LatexmkrcData;
+use tempfile::tempdir;
+
+pub fn parse_latexmkrc(_input: &str) -> std::io::Result<LatexmkrcData> {
+ let temp_dir = tempdir()?;
+ let non_existent_tex = temp_dir.path().join("NONEXISTENT.tex");
+
+ // Run `latexmk -dir-report $TMPDIR/NONEXISTENT.tex` to obtain out_dir
+ // and aux_dir values. We pass nonexistent file to prevent latexmk from
+ // building anything, since we need this invocation only to extract the
+ // -dir-report variables.
+ //
+ // In the future, latexmk plans to implement -dir-report-only option and we
+ // won't have to resort to this hack with NONEXISTENT.tex.
+ let output = std::process::Command::new("latexmk")
+ .arg("-dir-report")
+ .arg(non_existent_tex)
+ .output()?;
+
+ let stderr = String::from_utf8_lossy(&output.stderr);
+
+ let (aux_dir, out_dir) = stderr.lines().find_map(extract_dirs).ok_or_else(|| {
+ std::io::Error::new(
+ std::io::ErrorKind::InvalidData,
+ "Normalized aux and out dir were not found in latexmk output",
+ )
+ })?;
+
+ Ok(LatexmkrcData {
+ aux_dir: Some(aux_dir),
+ out_dir: Some(out_dir),
+ })
+}
+
+/// Extracts $aux_dir and $out_dir from lines of the form
+///
+/// Latexmk: Normalized aux dir and out dir: '$aux_dir', '$out_dir'
+fn extract_dirs(line: &str) -> Option<(String, String)> {
+ let mut it = line
+ .strip_prefix("Latexmk: Normalized aux dir and out dir: ")?
+ .split(", ");
+
+ let aux_dir = it.next()?.strip_prefix('\'')?.strip_suffix('\'')?;
+ let out_dir = it.next()?.strip_prefix('\'')?.strip_suffix('\'')?;
+
+ // Ensure there's no more data
+ if it.next().is_some() {
+ return None;
+ }
+
+ Some((String::from(aux_dir), String::from(out_dir)))
+}