mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
Tagged Text: decode only the escapes we write; other backslashes stay literal
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e1e9923471
commit
96a3290021
@@ -37,14 +37,20 @@ fn escape_value(v: &str) -> String {
|
||||
out
|
||||
}
|
||||
|
||||
/// A tag value with backslash escapes removed.
|
||||
/// A tag value with the escapes `escape_value` writes (`\\`, `\<`, `\>`) decoded. Any other
|
||||
/// backslash, including a trailing one, stays literal, as older files and InDesign's `\:` expect.
|
||||
fn unescape_value(v: &str) -> String {
|
||||
let mut out = String::with_capacity(v.len());
|
||||
let mut it = v.chars();
|
||||
let mut it = v.chars().peekable();
|
||||
while let Some(c) = it.next() {
|
||||
match c {
|
||||
'\\' => out.extend(it.next()),
|
||||
c => out.push(c),
|
||||
if c == '\\'
|
||||
&& let Some(&n) = it.peek()
|
||||
&& matches!(n, '\\' | '<' | '>')
|
||||
{
|
||||
out.push(n);
|
||||
it.next();
|
||||
} else {
|
||||
out.push(c);
|
||||
}
|
||||
}
|
||||
out
|
||||
@@ -312,6 +318,15 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A backslash that isn't one of our escapes (older files, InDesign's `\:`) stays literal.
|
||||
#[test]
|
||||
fn unknown_backslashes_in_style_names_stay_literal() {
|
||||
assert_eq!(unescape_value(r"x\y"), r"x\y");
|
||||
assert_eq!(unescape_value(r"a\:b"), r"a\:b");
|
||||
assert_eq!(unescape_value("end\\"), "end\\");
|
||||
assert_eq!(unescape_value(r"\<a\>\\"), r"<a>\");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tagged_text_round_trips() {
|
||||
let src = "<ASCII-WIN>\r\n<Version:7>\r\n<ParaStyle:Head>Caf<0x00E9> \\<1\\>\r\n<ParaStyle:Body>A <CharStyle:Em>word<CharStyle:> and <cSize:18.000000>big<cSize:> text";
|
||||
|
||||
Reference in New Issue
Block a user