diff options
author | Norbert Preining <norbert@preining.info> | 2022-07-04 03:03:43 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-07-04 03:03:43 +0000 |
commit | 1c10375ec46d7d83b2f1efc2a71b7ea114c889f0 (patch) | |
tree | 47b3469111105b7767111dcb89858fbc1e73377f /support/texlab/src/features | |
parent | 34d318af65decbdb242ae03b64bf3f53266067b6 (diff) |
CTAN sync 202207040303
Diffstat (limited to 'support/texlab/src/features')
-rw-r--r-- | support/texlab/src/features/build.rs | 8 | ||||
-rw-r--r-- | support/texlab/src/features/forward_search.rs | 74 |
2 files changed, 74 insertions, 8 deletions
diff --git a/support/texlab/src/features/build.rs b/support/texlab/src/features/build.rs index ae465590fc..d961052061 100644 --- a/support/texlab/src/features/build.rs +++ b/support/texlab/src/features/build.rs @@ -164,12 +164,12 @@ impl BuildEngine { let args: Vec<_> = options .build - .args() - .into_iter() - .map(|arg| replace_placeholder(arg, &path)) + .args + .iter() + .map(|arg| replace_placeholder(arg.clone(), &path)) .collect(); - let mut process = Command::new(options.build.executable()) + let mut process = Command::new(&options.build.executable) .args(args) .stdin(Stdio::null()) .stdout(Stdio::piped()) diff --git a/support/texlab/src/features/forward_search.rs b/support/texlab/src/features/forward_search.rs index 521cc31a59..54629d0dc0 100644 --- a/support/texlab/src/features/forward_search.rs +++ b/support/texlab/src/features/forward_search.rs @@ -86,6 +86,73 @@ pub fn execute_forward_search( Some(ForwardSearchResult { status }) } +/// Iterate overs chunks of a string. Either returns a slice of the +/// original string, or the placeholder replacement. +pub struct PlaceHolderIterator<'a> { + remainder: &'a str, + tex_file: &'a str, + pdf_file: &'a str, + line_number: &'a str, +} + +impl<'a> PlaceHolderIterator<'a> { + pub fn new(s: &'a str, tex_file: &'a str, pdf_file: &'a str, line_number: &'a str) -> Self { + Self { + remainder: s, + tex_file, + pdf_file, + line_number, + } + } + + pub fn yield_remainder(&mut self) -> Option<&'a str> { + let chunk = self.remainder; + self.remainder = ""; + Some(chunk) + } + + pub fn yield_placeholder(&mut self) -> Option<&'a str> { + if self.remainder.len() >= 2 { + let placeholder = self.remainder; + self.remainder = &self.remainder[2..]; + match &placeholder[1..2] { + "f" => Some(self.tex_file), + "p" => Some(self.pdf_file), + "l" => Some(self.line_number), + "%" => Some("%"), // escape % + _ => Some(&placeholder[0..2]), + } + } else { + self.remainder = &self.remainder[1..]; + Some("%") + } + } + + pub fn yield_str(&mut self, end: usize) -> Option<&'a str> { + let chunk = &self.remainder[..end]; + self.remainder = &self.remainder[end..]; + Some(chunk) + } +} + +impl<'a> Iterator for PlaceHolderIterator<'a> { + type Item = &'a str; + + fn next(&mut self) -> Option<Self::Item> { + return if self.remainder.is_empty() { + None + } else if self.remainder.starts_with('%') { + self.yield_placeholder() + } else { + // yield up to the next % or to the end + match self.remainder.find('%') { + None => self.yield_remainder(), + Some(end) => self.yield_str(end), + } + }; + } +} + fn replace_placeholder( tex_file: &Path, pdf_file: &Path, @@ -95,10 +162,9 @@ fn replace_placeholder( let result = if argument.starts_with('"') || argument.ends_with('"') { argument.to_string() } else { - argument - .replace("%f", tex_file.to_str()?) - .replace("%p", pdf_file.to_str()?) - .replace("%l", &(line_number + 1).to_string()) + let line = &(line_number + 1).to_string(); + let it = PlaceHolderIterator::new(argument, tex_file.to_str()?, pdf_file.to_str()?, line); + it.collect::<Vec<&str>>().join("") }; Some(result) } |