diff options
Diffstat (limited to 'support/texlab/crates/parser/src/latexmkrc.rs')
-rw-r--r-- | support/texlab/crates/parser/src/latexmkrc.rs | 52 |
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))) +} |