From a2f98eb4a2b827323e24ec57b4ce1f1dfa91e0da Mon Sep 17 00:00:00 2001 From: Vomitblood Date: Mon, 22 Apr 2024 16:22:35 +0800 Subject: [PATCH] i hate ansi escape codes --- Cargo.lock | 39 +++++++++++++++++++++++++ Cargo.toml | 1 + src/print.rs | 82 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 101 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18fc858..953111e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "aligned-vec" version = "0.5.0" @@ -1462,6 +1471,35 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + [[package]] name = "reqwest" version = "0.11.27" @@ -1583,6 +1621,7 @@ dependencies = [ "image", "once_cell", "rand", + "regex", "reqwest", "rust-embed", "serde", diff --git a/Cargo.toml b/Cargo.toml index 703f2c9..2634426 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ dirs = "5.0.1" image = "0.25.1" once_cell = "1.19.0" rand = { version = "0.8.4", features = ["small_rng"] } +regex = "1.10.4" reqwest = { version = "0.11", features = ["blocking", "json"] } rust-embed = "8.3.0" serde = { version = "1.0.197", features = ["derive"] } diff --git a/src/print.rs b/src/print.rs index a6cc97f..ddb6b2a 100644 --- a/src/print.rs +++ b/src/print.rs @@ -259,31 +259,71 @@ fn print_name(paths: &[std::path::PathBuf]) { println!("{}", output); } -fn print_colorscripts(paths: &[std::path::PathBuf], spacing: u8) -> std::io::Result<()> { - // open all files and create BufReaders - let mut readers: Vec<_> = paths - .iter() - .map(std::fs::File::open) - .filter_map(|result| result.ok()) - .map(std::io::BufReader::new) - .collect(); +// I HATE ANSI ESCAPE CHARACTERS +fn print_colorscripts( + paths: &Vec, + spacing: u8, +) -> Result<(), Box> { + let mut max_widths = vec![]; + let mut max_height = 0; + let mut file_contents: Vec> = vec![]; - // create a string for spacing + // first read all files and calculate maximum widths and heights by iterating through + // MUST IGNORE ANSI ESCAPE CODES❗❗❗ + for path in paths { + let file = std::fs::File::open(path)?; + let reader = std::io::BufReader::new(file); + // put all the lines in a vector + let mut lines: Vec = vec![]; + let mut max_width = 0; + + // get the longest line length + for line in reader.lines() { + let line = line?; + // remove ansi escape codes for width calculation + let plain_line = regex::Regex::new("\x1b\\[[^m]*m")?.replace_all(&line, ""); + max_width = max_width.max(plain_line.chars().count()); + lines.push(line); + } + + // push the max width and lines to the respective vectors + max_widths.push(max_width); + max_height = max_height.max(lines.len()); + file_contents.push(lines); + } + + // construct spacing string let separator = " ".repeat(spacing as usize); - // one line by one line - let mut lines: Vec = vec![]; - loop { - lines.clear(); - for reader in &mut readers { - let mut line = String::new(); - if reader.read_line(&mut line)? > 0 { - lines.push(line.trim_end().to_string()); - } else { - // End of file reached - return Ok(()); + // print each combined line + for line_index in 0..max_height { + let mut line_to_print = String::new(); + + // construct the combined line + for (file_index, lines) in file_contents.iter().enumerate() { + if line_index < lines.len() { + line_to_print.push_str(&lines[line_index]); + } + + // pad the rest of the line if this artwork is shorter + if line_index >= lines.len() + || line_index < lines.len() + && lines[line_index].chars().count() < max_widths[file_index] + { + let current_length = lines.get(line_index).map_or(0, |l| l.chars().count()); + line_to_print.push_str(&" ".repeat(max_widths[file_index] - current_length)); + } + + // check if this is the last file to print + if file_index < file_contents.len() - 1 { + // do not add separator to the last file + line_to_print.push_str(&separator); } } - println!("{}", lines.join(&separator)); + + // finally print the thing + println!("{}", line_to_print); } + + Ok(()) }