this repo has no description

fix: preserve spaces between text and inline links

diogocastro.net 7161c1e2 1368fd07

verified
Changed files
+22 -32
src
+22 -32
src/minify.rs
··· 1 1 pub fn minify_html(input: &str) -> String { 2 2 let mut out = String::with_capacity(input.len()); 3 3 let mut in_tag = false; 4 - let mut last = ' '; 4 + let mut last_was_space = false; 5 5 6 - let chars: Vec<char> = input.chars().collect(); 7 - 8 - for (i, c) in chars.iter().enumerate() { 6 + for c in input.chars() { 9 7 match c { 10 8 '<' => { 11 9 in_tag = true; 12 - 13 - // remove space before '<' 14 - if last.is_whitespace() && !out.ends_with('>') { 15 - // trim trailing space 16 - while out.ends_with(' ') { 17 - out.pop(); 18 - } 19 - } 20 - 10 + // Do not trim potential preceding text space here; that can 11 + // break patterns like "on " + "<a>" into "on<a>". 21 12 out.push('<'); 22 - last = '<'; 13 + last_was_space = false; 23 14 } 24 15 25 16 '>' => { 26 17 in_tag = false; 27 18 out.push('>'); 28 - last = '>'; 19 + last_was_space = false; 29 20 } 30 21 31 - c if c.is_whitespace() => { 22 + ch if ch.is_whitespace() => { 32 23 if in_tag { 33 - // inside a tag collapse to a single space 34 - if last != ' ' { 24 + // Inside a tag: collapse any whitespace run to a single space 25 + // so attributes stay tidy. 26 + if !last_was_space { 35 27 out.push(' '); 36 - last = ' '; 28 + last_was_space = true; 37 29 } 38 30 } else { 39 - // outside a tag 40 - // remove text spaces *between tags* 41 - let next = chars.get(i + 1).copied().unwrap_or('x'); 42 - if last == '>' && next == '<' { 43 - // skip whitespace entirely 44 - continue; 45 - } 46 - 47 - // otherwise allow a single space 48 - if last != ' ' { 31 + // Outside a tag (text content): 32 + // - Collapse runs of whitespace to a single space, 33 + // - but never remove the space entirely. 34 + // 35 + // This preserves spaces like: 36 + // "on " + "<a>tangled</a>" => "on <a>tangled</a>" 37 + // instead of "on<a>tangled</a>". 38 + if !last_was_space { 49 39 out.push(' '); 50 - last = ' '; 40 + last_was_space = true; 51 41 } 52 42 } 53 43 } 54 44 55 45 _ => { 56 - out.push(*c); 57 - last = *c; 46 + out.push(c); 47 + last_was_space = false; 58 48 } 59 49 } 60 50 }