mirror of
https://git.2ki.xyz/spiders/kijetesantakaluotokieni.git
synced 2024-11-10 04:00:26 +01:00
added project files
This commit is contained in:
commit
8cc83a4f10
5 changed files with 326 additions and 0 deletions
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "kijetesantakaluotokieni"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
voca_rs = " 1.14.0"
|
||||
|
123
src/bubbles.rs
Normal file
123
src/bubbles.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use voca_rs::*;
|
||||
|
||||
pub fn bubble_from_text(text: &str, bubble_anchor: usize, max_length: usize) -> String {
|
||||
bubble_from_lines(wrap_block(text, max_length), bubble_anchor)
|
||||
}
|
||||
|
||||
fn bubble_from_lines(lines: Vec<String>, min_length: usize) -> String {
|
||||
let longest_length: usize;
|
||||
let lengths: Vec<(&String, usize)> = lines
|
||||
.iter()
|
||||
.zip(lines.iter().map(|s| count::count_graphemes(s)))
|
||||
.collect();
|
||||
match lines.iter().map(|s| count::count_graphemes(s)).max() {
|
||||
None => return "".to_string(),
|
||||
Some(l) => longest_length = l,
|
||||
};
|
||||
|
||||
// let line_length = cmp::max(longest_length, min_length);
|
||||
let line_length = longest_length;
|
||||
let pad_length = if longest_length < min_length {
|
||||
min_length + (longest_length / 2) + 2
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let bubble_top = manipulate::pad_left(
|
||||
&format!(" _{}_ \n", "_".repeat(line_length)),
|
||||
pad_length,
|
||||
" ",
|
||||
);
|
||||
let bubble_bottom = manipulate::pad_left(
|
||||
&format!(" -{}- ", "-".repeat(line_length)),
|
||||
pad_length,
|
||||
" ",
|
||||
);
|
||||
let mut bubble_body = String::new();
|
||||
|
||||
match lines.len() {
|
||||
1 => {
|
||||
return format!(
|
||||
"{}{}{}",
|
||||
bubble_top,
|
||||
manipulate::pad_left(&format!("< {} >\n", lines[0]), pad_length, " "),
|
||||
bubble_bottom
|
||||
)
|
||||
}
|
||||
n => {
|
||||
bubble_body.push_str(&format!("/ {:<line_length$} \\\n", lines[0]));
|
||||
if n > 2 {
|
||||
for i in 1..n - 1 {
|
||||
bubble_body.push_str(&format!("| {:<line_length$} |\n", lines[i]));
|
||||
}
|
||||
}
|
||||
bubble_body.push_str(&format!("\\ {:<line_length$} /\n", lines[n - 1]));
|
||||
return format!("{}{}{}", bubble_top, bubble_body, bubble_bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_once(text: &str, max_length: usize) -> (String, Option<String>) {
|
||||
let whitespace_not_newline = |c: char| c.is_whitespace() && c != '\n';
|
||||
let mut length: usize = 0;
|
||||
let mut last_space: Option<usize> = None;
|
||||
|
||||
for s in split::graphemes(text) {
|
||||
length = length + 1;
|
||||
if s == "\n" {
|
||||
// chop::substring treats 0 as 'till the end of the string' so if we want to cut off initial
|
||||
// newlines into empty strings we need special handling
|
||||
let broken_line = if length == 1 {
|
||||
"".to_string()
|
||||
} else {
|
||||
chop::substring(text, 0, length - 1)
|
||||
};
|
||||
let rest = chop::substring(text, length, count::count_graphemes(text))
|
||||
.trim_start_matches(whitespace_not_newline)
|
||||
.to_string();
|
||||
return (broken_line, Some(rest));
|
||||
}
|
||||
if query::is_blank(s) {
|
||||
// minus one because last_space is an index
|
||||
last_space = Some(length - 1);
|
||||
}
|
||||
if length == max_length {
|
||||
match last_space {
|
||||
None => {
|
||||
// breaks in middle of word as in cowsay
|
||||
let broken_line = chop::substring(text, 0, length);
|
||||
let rest = chop::substring(text, length, count::count_graphemes(text))
|
||||
.trim_start_matches(whitespace_not_newline)
|
||||
.to_string();
|
||||
return (broken_line, Some(rest));
|
||||
}
|
||||
Some(last_space) => {
|
||||
// break at last whitespace, discarding it
|
||||
let broken_line = chop::substring(text, 0, last_space);
|
||||
let rest = chop::substring(text, last_space + 1, count::count_graphemes(text))
|
||||
.trim_start_matches(whitespace_not_newline)
|
||||
.to_string();
|
||||
return (broken_line, Some(rest));
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
// if we get here it means the string wasn't long enough to be broken
|
||||
return (text.to_string(), None);
|
||||
}
|
||||
|
||||
/*
|
||||
splits a bunch of text into wrapped lines
|
||||
*/
|
||||
fn wrap_block(text: &str, max_length: usize) -> Vec<String> {
|
||||
let mut lines: Vec<String> = vec![];
|
||||
let mut remaining = text.trim_end().to_string();
|
||||
loop {
|
||||
let (line, rest) = wrap_once(&remaining, max_length);
|
||||
lines.push(line);
|
||||
match rest {
|
||||
None => break,
|
||||
Some(rest) => remaining = rest,
|
||||
};
|
||||
}
|
||||
return lines;
|
||||
}
|
125
src/critters.rs
Normal file
125
src/critters.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
use voca_rs::*;
|
||||
|
||||
pub struct Critter<'a> {
|
||||
pub anchor: usize,
|
||||
pub critter: &'a str,
|
||||
}
|
||||
|
||||
pub struct CritterConfig {
|
||||
pub left_eye: String,
|
||||
pub right_eye: String,
|
||||
|
||||
pub left_tongue: String,
|
||||
pub right_tongue: String,
|
||||
|
||||
pub right_line: String,
|
||||
pub up_line: String,
|
||||
pub left_line: String,
|
||||
}
|
||||
|
||||
pub const KIJETESANTAKALU: Critter = Critter {
|
||||
anchor: 14,
|
||||
critter: r"
|
||||
$6
|
||||
/__ $6
|
||||
/ $1$2\ $7
|
||||
| |$3$4
|
||||
| |
|
||||
(III|\||",
|
||||
};
|
||||
|
||||
pub const KIJETESANTAKALU_LITTLE: Critter = Critter {
|
||||
anchor: 13,
|
||||
critter: r"
|
||||
$6
|
||||
/__ $6
|
||||
/ $1$2\ $5
|
||||
| |$3$4
|
||||
(I|\||",
|
||||
};
|
||||
|
||||
pub fn config_from_string(eyes: &str, tongue: &str, line: &str) -> CritterConfig {
|
||||
let default_config = CritterConfig {
|
||||
left_eye: String::from("."),
|
||||
right_eye: String::from("."),
|
||||
|
||||
left_tongue: String::from(" "),
|
||||
right_tongue: String::from(" "),
|
||||
|
||||
right_line: String::from("/"),
|
||||
up_line: String::from("|"),
|
||||
left_line: String::from("\\"),
|
||||
};
|
||||
|
||||
let (left_eye, right_eye);
|
||||
let (left_tongue, right_tongue);
|
||||
let (left_line, up_line, right_line);
|
||||
|
||||
match count::count_graphemes(eyes) {
|
||||
0 => (left_eye, right_eye) = (default_config.left_eye, default_config.right_eye),
|
||||
1 => (left_eye, right_eye) = (chop::grapheme_at(eyes, 0), chop::grapheme_at(eyes, 0)),
|
||||
_ => (left_eye, right_eye) = (chop::grapheme_at(eyes, 0), chop::grapheme_at(eyes, 1)),
|
||||
}
|
||||
match count::count_graphemes(tongue) {
|
||||
0 => {
|
||||
(left_tongue, right_tongue) = (default_config.left_tongue, default_config.right_tongue)
|
||||
}
|
||||
1 => (left_tongue, right_tongue) = (chop::grapheme_at(tongue, 0), " ".to_string()),
|
||||
_ => {
|
||||
(left_tongue, right_tongue) =
|
||||
(chop::grapheme_at(tongue, 0), chop::grapheme_at(tongue, 1))
|
||||
}
|
||||
}
|
||||
match count::count_graphemes(line) {
|
||||
0 => {
|
||||
(left_line, up_line, right_line) = (
|
||||
default_config.left_line,
|
||||
default_config.up_line,
|
||||
default_config.right_line,
|
||||
)
|
||||
}
|
||||
1 => {
|
||||
(left_line, up_line, right_line) = (
|
||||
chop::grapheme_at(line, 0),
|
||||
default_config.up_line,
|
||||
default_config.right_line,
|
||||
)
|
||||
}
|
||||
2 => {
|
||||
(left_line, up_line, right_line) = (
|
||||
chop::grapheme_at(line, 0),
|
||||
chop::grapheme_at(line, 1),
|
||||
default_config.right_line,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
(left_line, up_line, right_line) = (
|
||||
chop::grapheme_at(line, 0),
|
||||
chop::grapheme_at(line, 1),
|
||||
chop::grapheme_at(line, 2),
|
||||
)
|
||||
}
|
||||
}
|
||||
CritterConfig {
|
||||
left_eye,
|
||||
right_eye,
|
||||
|
||||
left_tongue,
|
||||
right_tongue,
|
||||
|
||||
right_line,
|
||||
up_line,
|
||||
left_line,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_critter(critter: &str, critter_config: CritterConfig) -> String {
|
||||
return critter
|
||||
.replace("$1", &critter_config.left_eye)
|
||||
.replace("$2", &critter_config.right_eye)
|
||||
.replace("$3", &critter_config.left_tongue)
|
||||
.replace("$4", &critter_config.right_tongue)
|
||||
.replace("$5", &critter_config.right_line)
|
||||
.replace("$6", &critter_config.up_line)
|
||||
.replace("$7", &critter_config.left_line);
|
||||
}
|
40
src/main.rs
Normal file
40
src/main.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
TO DO
|
||||
- options
|
||||
- kijefiles
|
||||
- other aminals
|
||||
*/
|
||||
|
||||
mod bubbles;
|
||||
mod critters;
|
||||
|
||||
use std::cmp;
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use voca_rs::*;
|
||||
|
||||
fn main() {
|
||||
let mut text = String::new();
|
||||
let default_config = critters::config_from_string("", "", "");
|
||||
|
||||
io::stdin()
|
||||
.read_to_string(&mut text)
|
||||
.expect("failed to read input");
|
||||
|
||||
print!(
|
||||
"{}",
|
||||
bubbles::bubble_from_text(
|
||||
&text,
|
||||
critters::KIJETESANTAKALU.anchor,
|
||||
DEFAULT_MAXIMUM_LINE_LENGTH
|
||||
)
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
critters::format_critter(critters::KIJETESANTAKALU_LITTLE.critter, default_config)
|
||||
);
|
||||
}
|
||||
|
||||
// functions for producing formatted text
|
||||
|
||||
const DEFAULT_MAXIMUM_LINE_LENGTH: usize = 40;
|
28
test
Executable file
28
test
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/fish
|
||||
|
||||
echo 1234567890123456789012345678901234567890123456789012345678901234567890 | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo -e "“Oh, you wicked little thing!” cried Alice, catching up the kitten, and giving it a little kiss to make it understand that it was in disgrace. “Really, Dinah ought to have taught you better manners!”\n\n“You ought, Dinah, you know you ought!” she added, looking reproachfully at the old cat, and speaking in as cross a voice as she could manage—and then she scrambled back into the arm-chair, taking the kitten and the worsted with her, and began winding up the ball again." | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
|
||||
#echo -e "'Oh, you wicked little thing!' cried Alice, catching up the kitten, and giving it a little kiss to make it understand that it was in disgrace. 'Really, Dinah ought to have taught you better manners!'\n\n'You ought, Dinah, you know you ought!' she added, looking reproachfully at the old cat, and speaking in as cross a voice as she could manage—and then she scrambled back into the arm-chair, taking the kitten and the worsted with her, and began winding up the ball again." | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo "Белеет парус одинокий
|
||||
В тумане моря голубом!..
|
||||
Что ищет он в стране далекой?
|
||||
Что кинул он в краю родном?..
|
||||
|
||||
A lonely sail is flashing white
|
||||
Amdist the blue mist of the sea!...
|
||||
What does it seek in foreign lands?
|
||||
What did it leave behind at home?.." | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo mu | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo 1234567890123 | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo Pingo pi n\'t go li sitelen | ./target/debug/kijetesantakaluotokieni
|
||||
|
||||
echo 420 lol | ./target/debug/kijetesantakaluotokieni
|
Loading…
Reference in a new issue