diff options
Diffstat (limited to '')
-rw-r--r-- | isabelle-unicode/Cargo.toml | 10 | ||||
-rw-r--r-- | isabelle-unicode/src/lib.rs | 70 |
2 files changed, 80 insertions, 0 deletions
diff --git a/isabelle-unicode/Cargo.toml b/isabelle-unicode/Cargo.toml new file mode 100644 index 0000000..2e5ff9f --- /dev/null +++ b/isabelle-unicode/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "isabelle-unicode" +version = "0.1.0" +authors = ["stuebinm <stuebinm@disroot.org>"] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +symbolmacro = { path = "../symbolmacro" } diff --git a/isabelle-unicode/src/lib.rs b/isabelle-unicode/src/lib.rs new file mode 100644 index 0000000..8394e57 --- /dev/null +++ b/isabelle-unicode/src/lib.rs @@ -0,0 +1,70 @@ + +symbolmacro::make_symbols!(); + +// TODO: is it possible to be polymorphic over slice types here? +pub trait PrettyUnicode { + fn to_pretty_unicode(self) -> Option<String>; +} + +impl PrettyUnicode for &str { + fn to_pretty_unicode(self) -> Option<String> { + // split at escape sequences + let mut chunks = self.split("\\<"); + + // first chunk contains no escape + let prefix = chunks.next()?; + + // line with escape sequences replaced by unicode + let mut pretty = chunks + .filter_map(|chunk| { + // extract this symbol's name + let ident : Option<&str> = chunk + .split(">") + .next(); + + // get this symbol's unicode representation + let symbol : char = ident + .map(symbol) + .flatten() + .unwrap_or('�'); + + // how much of the rest do we need? + let offset = ident? + .len() + + 1; + Some((symbol, &chunk[offset..])) + }) + .fold(prefix.to_owned(), |mut acc, (symbol, rest)| { + // TODO: this may cause some unnecessary reallocs + // (since the line length is known in advance) + acc.push(symbol); + acc.push_str(rest); + // lol rust is sufficiently imperative to have mutable + // strings but also sufficiently functional that this + // version of fold pretends like it doesn't + acc + }); + + // add a newline + pretty.push('\n'); + Some(pretty) + } +} + +// fn main() { + +// let stdin = io::stdin(); + +// stdin.lock() +// .lines() +// .filter_map(|line| match line { +// Ok(line) if line.trim().is_empty() +// => Some("\n".to_string()), +// Ok(line) +// => line.to_pretty_unicode(), +// Err(_) +// => None +// }) +// .for_each(|line| print!("{}", line)); + +// } |