init
This commit is contained in:
commit
87266e7d54
8 changed files with 296 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "boxon"
|
||||||
|
version = "0.1.0"
|
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "boxon"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# boxon
|
||||||
|
|
||||||
|
Utility to convert ascii boxes into ansi boxes inside text files.
|
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
hard_tabs = true
|
||||||
|
max_width = 120
|
235
src/main.rs
Normal file
235
src/main.rs
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
use std::{env::args, fs};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let file = args().nth(1).expect("Usage : boxon <file>");
|
||||||
|
let content = fs::read_to_string(&file).unwrap_or_else(|_| panic!("Could not read file '{file}'."));
|
||||||
|
let mut grid = Grid::from(content);
|
||||||
|
grid.fix();
|
||||||
|
let content: String = grid.into();
|
||||||
|
fs::write(&file, content).unwrap_or_else(|_| panic!("Could not write result to file '{file}'."));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Grid(Vec<Vec<char>>);
|
||||||
|
|
||||||
|
impl<T: AsRef<str>> From<T> for Grid {
|
||||||
|
fn from(value: T) -> Self {
|
||||||
|
Self(value.as_ref().lines().map(str::chars).map(Iterator::collect).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Grid> for String {
|
||||||
|
fn from(val: Grid) -> Self {
|
||||||
|
val.0
|
||||||
|
.iter()
|
||||||
|
.map(|l| l.iter().collect::<String>())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Grid {
|
||||||
|
fn fix(&mut self) -> usize {
|
||||||
|
let mut result = 0;
|
||||||
|
let copy = self.clone();
|
||||||
|
for (y, line) in self.0.iter_mut().enumerate() {
|
||||||
|
for (x, character) in line.iter_mut().enumerate() {
|
||||||
|
if let Some(cross) = copy.cross_at(x as i32, y as i32) {
|
||||||
|
let new_char = match cross {
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '┼',
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '├',
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '┤',
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
) => '┴',
|
||||||
|
Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '┬',
|
||||||
|
Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
) => '─',
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '│',
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, F_), //
|
||||||
|
((), F_, ()), //
|
||||||
|
) => '┘',
|
||||||
|
Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '┐',
|
||||||
|
Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(F_, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
) => '┌',
|
||||||
|
Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
) => '└',
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
*character = new_char;
|
||||||
|
result += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn cross_at(&self, x: i32, y: i32) -> Option<Cross> {
|
||||||
|
fn at(g: &Grid, x: i32, y: i32) -> Option<Cross> {
|
||||||
|
if x < 0 || y < 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(connects(*g.0.get(y as usize)?.get(x as usize)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let get = |x: i32, y: i32| -> Cross {
|
||||||
|
at(self, x, y).unwrap_or(connects(' '))
|
||||||
|
};
|
||||||
|
let c = get(x, y);
|
||||||
|
let its_y = y;
|
||||||
|
Some(Cross(
|
||||||
|
( (), get(x, y - 1).d() && c.u(), ()),
|
||||||
|
(get(x - 1, y).r() && c.l(), get(x, its_y).c(), get(x + 1, y).l() && c.r()),
|
||||||
|
( (), get(x, y + 1).u() && c.d(), ()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connects(c: char) -> Cross {
|
||||||
|
match c {
|
||||||
|
'-' => Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
),
|
||||||
|
'|' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'+' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'┼' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'├' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'┤' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'┴' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
),
|
||||||
|
'┬' => Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'─' => Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
),
|
||||||
|
'│' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'┘' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(MM, MM, F_), //
|
||||||
|
((), F_, ()), //
|
||||||
|
),
|
||||||
|
'┐' => Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(MM, MM, F_), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'┌' => Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(F_, MM, MM), //
|
||||||
|
((), MM, ()), //
|
||||||
|
),
|
||||||
|
'└' => Cross(
|
||||||
|
((), MM, ()), //
|
||||||
|
(F_, MM, MM), //
|
||||||
|
((), F_, ()), //
|
||||||
|
),
|
||||||
|
_ => Cross(
|
||||||
|
((), F_, ()), //
|
||||||
|
(F_, F_, F_), //
|
||||||
|
((), F_, ()), //
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const F_: bool = false;
|
||||||
|
const MM: bool = true;
|
||||||
|
type Empt = ();
|
||||||
|
struct Cross(
|
||||||
|
(Empt, bool, Empt), //
|
||||||
|
(bool, bool, bool), //
|
||||||
|
(Empt, bool, Empt), //
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Cross {
|
||||||
|
fn u(&self) -> bool {
|
||||||
|
self.0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn d(&self) -> bool {
|
||||||
|
self.2.1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn l(&self) -> bool {
|
||||||
|
self.1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn r(&self) -> bool {
|
||||||
|
self.1.2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn c(&self) -> bool {
|
||||||
|
self.1.1
|
||||||
|
}
|
||||||
|
}
|
21
test/out.txt
Normal file
21
test/out.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
this is a normalized data table diagram.
|
||||||
|
|
||||||
|
+----------------+
|
||||||
|
|USERS BY EMAIL |
|
||||||
|
+--+-----+-------+
|
||||||
|
|id|email|user_id|
|
||||||
|
+--+-----+-------+
|
||||||
|
| 1|b@o.b| 1|
|
||||||
|
| 2|c@r.l| 2|
|
||||||
|
+--+-----+-------+
|
||||||
|
+---------------+
|
||||||
|
|USERS |
|
||||||
|
+--+--------+---+
|
||||||
|
|id| name|age|
|
||||||
|
+--+--------+---+
|
||||||
|
| 1| bob| 19|
|
||||||
|
| 2| charlie| 23|
|
||||||
|
+--+--------+---+
|
||||||
|
|
||||||
|
|
21
test/source.txt
Normal file
21
test/source.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
this is a normalized data table diagram.
|
||||||
|
|
||||||
|
+----------------+
|
||||||
|
|USERS BY EMAIL |
|
||||||
|
+--+-----+-------+
|
||||||
|
|id|email|user_id|
|
||||||
|
+--+-----+-------+
|
||||||
|
| 1|b@o.b| 1|
|
||||||
|
| 2|c@r.l| 2|
|
||||||
|
+--+-----+-------+
|
||||||
|
+---------------+
|
||||||
|
|USERS |
|
||||||
|
+--+--------+---+
|
||||||
|
|id| name|age|
|
||||||
|
+--+--------+---+
|
||||||
|
| 1| bob| 19|
|
||||||
|
| 2| charlie| 23|
|
||||||
|
+--+--------+---+
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue