mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-08 11:52:10 +00:00
.ai import: data with no end outside a section does not hide a later section's end
When the scan for swatch names searched data outside a section and found no `~>`, it stopped searching for the end of all later data. Data in a later section then was not skipped, so a `(` on a `%_` line of it opened a string that ran past the section's end marker, and a color named after the section did not reserve its name. The scan now records the search that found nothing per section's end marker, so a search in another section still stops at that section's markers.
This commit is contained in:
@@ -1143,8 +1143,9 @@ pub(super) struct Dictionaries<'s> {
|
||||
name: Option<&'s [u8]>,
|
||||
/// Whether the string just before the token taken is a key that ASCII85 data follows.
|
||||
string_key: bool,
|
||||
/// The rest of the data has no `~>` or marker to stop at, so they aren't searched for again.
|
||||
no_end: bool,
|
||||
/// The end markers of the sections being scanned (`None`: no section) where the rest of the data
|
||||
/// had no `~>` or marker to stop at, so they aren't searched for again in those sections.
|
||||
no_end: Vec<Option<String>>,
|
||||
}
|
||||
|
||||
/// Where the ASCII85 data at the start of `rest` stops: just past its `~>`, or at the comment that
|
||||
@@ -1176,10 +1177,11 @@ impl<'s> Dictionaries<'s> {
|
||||
/// Take `tok`, the token `lex` just gave, and skip the ASCII85 data that follows it, up to where
|
||||
/// [`data_end`] stops for `section`, so the scan still finds that section's markers.
|
||||
pub(super) fn pass(&mut self, tok: &super::Tok<'s>, lex: &mut super::Lexer<'s>, section: Option<(&str, &str)>) {
|
||||
if self.data_follows(tok) && !self.no_end {
|
||||
let end = section.map(|(_, end)| end);
|
||||
if self.data_follows(tok) && !self.no_end.iter().any(|e| e.as_deref() == end) {
|
||||
match data_end(lex.rest(), section) {
|
||||
Some(stop) => lex.seek(lex.offset() + stop),
|
||||
None => self.no_end = true,
|
||||
None => self.no_end.push(end.map(str::to_owned)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4632,6 +4632,25 @@ fn swatch_names_are_found_past_data_in_versioned_content_that_does_not_end() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A search for where data stops that found nothing outside a section doesn't stop a later
|
||||
/// section's data at that section's end, so the named color after it still takes its name first.
|
||||
/// The `/Binary` holds a group, where the reader doesn't take what follows its key as data.
|
||||
#[test]
|
||||
fn swatch_names_are_found_past_data_in_a_section_after_a_search_outside_sections_found_nothing() {
|
||||
let sea = format!("0 1 1 0 (Sea) 0 x\n{}f\n", rect_path(0.0, 0.0, 5.0, 5.0));
|
||||
let before = "/Binary :\nu\n/ASCII85Decode ,\nU\n;\n";
|
||||
for section in [
|
||||
"%AI17_Begin_Content_if_version_gt:24 4\n%AI17_Alternate_Content\n/Binary : /ASCII85Decode ,\n%_(]<[%\n%AI17_End_Versioned_Content\n",
|
||||
"%AI11_BeginTextDocument\n/AI11TextDocument : /ASCII85Decode ,\n%_(]<[%\n%AI11_EndTextDocument\n",
|
||||
] {
|
||||
let art_text = format!("{before}{section}{sea}");
|
||||
let body = format!("{}{}", DOTS.replace("(Dots)", "(Sea\\n1)"), layer(&art_text));
|
||||
let d = read(stream(&body).as_bytes()).unwrap().doc;
|
||||
let names: Vec<&str> = d.patterns.iter().map(|p| p.name.as_str()).collect();
|
||||
assert_eq!(names, ["Sea 2"], "{art_text}");
|
||||
}
|
||||
}
|
||||
|
||||
/// The names the swatches take are found past the same data: a named color after it still takes
|
||||
/// its name first, and the pattern named after it is numbered.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user