Compare commits

...

7 commits

8 changed files with 267 additions and 168 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pride" name = "pride"
version = "0.0.1" version = "0.1.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -10,7 +10,13 @@ continue to refer to it as pre-release until I am happy with it.**
Currently supports a variety of stripe flags. Currently supports a variety of stripe flags.
Under Construction features: ## "Complex" Flag Branch
- [Variant Flags](https://git.vwolfe.io/valerie/pride/src/branch/variant)
- ["Complex" Flags](https://git.vwolfe.io/valerie/pride/src/branch/complex) This branch adds "complex" flags that require a little more effort to render than
iterating over an array of colors. Currently, the branch aims to add the following
flags:
- Progress: 2018 rainbow pride flag with black and brown and transgender flag chevrons
- Aro/Ace: side-by-side aromantic and asexual combination flag
- Intersex: a yellow flag with a purple circle
- Polyamorous: three-stripe flag with an isosceles triangle cut-in and a heart

103
src/complex.rs Normal file
View file

@ -0,0 +1,103 @@
use std::io::{
stdin, stdout,
Write
};
use termion::{
terminal_size,
color,
cursor,
color::{ Fg, Bg, Rgb },
raw::IntoRawMode
};
use crate::{ error, util };
use crate::flag::BLOCK;
pub static UHALF: &str = "";
//pub static LHALF: &str = "▄";
pub fn progress(small: bool) {
let red = color::Rgb(0xE5, 0x00, 0x00);
let orange = color::Rgb(0xFF, 0x8D, 0x00);
let yellow = color::Rgb(0xFF, 0xEE, 0x00);
let green = color::Rgb(0x02, 0x81, 0x21);
let blue = color::Rgb(0x00, 0x4C, 0xFF);
let purple = color::Rgb(0x77, 0x00, 0x88);
let white = color::Rgb(0xFF, 0xFF, 0xFF);
let pink = color::Rgb(0x7A, 0xCB, 0xF5);
let ltblue = color::Rgb(0xEA, 0xAC, 0xB8);
let brown = color::Rgb(0x61, 0x39, 0x15);
let black = color::Rgb(0x00, 0x00, 0x00);
}
// everything below here is alphabetical
pub fn aroace(small: bool) {
// set up colors
// shared colors
let black = color::Rgb(0x00, 0x00, 0x00);
let white = color::Rgb(0xFF, 0xFF, 0xFF);
// aro colors
let green = Fg(Rgb(0x3B, 0xA7, 0x40));
let lime = Fg(Rgb(0xA8, 0xD4, 0x7A));
let gray = Fg(Rgb(0xAB, 0xAB, 0xAB));
// ace colors
let grey = color::Rgb(0xA4, 0xA4, 0xA4);
let purple = color::Rgb(0x81, 0x00, 0x81);
// draw small
if small {
let solid = BLOCK.repeat(15);
let split = UHALF.repeat(15);
let reset = Bg(color::Reset);
for _ in 0..2 { println!("{green}{solid}{b}{solid}", b = Fg(black)); }
println!("{lime}{solid}{b}{g}{split}{reset}", b = Fg(black), g = Bg(grey));
println!("{lime}{solid}{g}{solid}", g = Fg(grey));
println!("{w}{solid}{g}{solid}", w = Fg(white), g = Fg(grey));
println!("{w}{solid}{solid}", w = Fg(white));
println!("{gray}{solid}{w}{solid}", w = Fg(white));
println!("{gray}{solid}{w}{p}{split}{reset}", w = Fg(white), p = Bg(purple));
for _ in 0..2 { println!("{b}{solid}{p}{solid}", b = Fg(black), p = Fg(purple)); }
print!("{}", termion::style::Reset);
return;
}
// draw full-size
/* the 4 and 5 stripe flags MUST line up; this means
* there have to be at least 20 steps; if we use half
* block characters, we can work this down to a minimum
* height of 10 by utilizing fg and bg.
*/
let min = 10;
let width: usize;
let height: usize;
let (twidth, theight) = terminal_size().unwrap();
if theight < min { error::too_small(Some("10 rows")); }
}
pub fn intersex(small: bool) {
let yellow = color::Rgb(0xFF, 0xDA, 0x00);
let purple = color::Rgb(0x7A, 0x00, 0xAC);
}
pub fn polyamorous(small: bool) {
let blue = color::Rgb(0x01, 0x9F, 0xE3);
let magenta = color::Rgb(0xE5, 0x00, 0x51);
let purple = color::Rgb(0x34, 0x0C, 0x46);
let white = color::Rgb(0xFF, 0xFF, 0xFF);
let yellow = color::Rgb(0x00, 0xFC, 0xBF);
}

View file

@ -10,43 +10,60 @@ use termion::{
color::{ Fg, Rgb }, color::{ Fg, Rgb },
cursor, cursor,
input::TermRead, input::TermRead,
raw::IntoRawMode, raw::IntoRawMode
style
}; };
use crate::flag::BLOCK; use crate::flag::BLOCK;
pub fn draw(colors: &[Fg<Rgb>]) { pub fn wait(stdin: io::Stdin) { for _ in stdin.keys() { return; } }
pub fn simple(colors: &[Fg<Rgb>]) {
let mut stdout = io::stdout().into_raw_mode().unwrap(); let mut stdout = io::stdout().into_raw_mode().unwrap();
let stdin = io::stdin(); let stdin = io::stdin();
let count = colors.len();
let (width, height) = terminal_size().unwrap();
let thresh = height as usize / count;
write!(stdout, "{}{}", cursor::Hide, clear::All).ok(); write!(stdout, "{}{}", cursor::Hide, clear::All).ok();
stdout.flush().ok(); stdout.flush().ok();
let stripe = BLOCK.repeat(width as usize); let (width, height) = terminal_size().unwrap();
let reset = style::Reset; stripes(&mut stdout, colors, (width as usize, height as usize));
wait(stdin);
write!(stdout, "{}{}", cursor::Show, clear::All).ok();
stdout.flush().ok();
}
pub fn small(colors: &[Fg<Rgb>]) {
let mut stdout = io::stdout().into_raw_mode().unwrap();
let height = colors.len();
let width = height * 3;
stripes(&mut stdout, colors, (width, height));
}
pub fn stripes(stdout: &mut io::Stdout, colors: &[Fg<Rgb>], size: (usize, usize)) {
let mut stdout = stdout.into_raw_mode().unwrap();
let count = colors.len();
let (width, height) = size;
let thresh = height / count;
let stripe = BLOCK.repeat(width);
let mut index = 0; let mut index = 0;
for n in 0..(height as usize) { for n in 0..height {
if n!= 0 && n % thresh == 0 { if n!= 0 && n % thresh == 0 {
index += 1; index += 1;
if index >= count { break; } if index >= count { break; }
} }
write!( write!(
stdout, stdout,
"{color}{stripe}{reset}", "{color}{stripe}\n{repos}",
color = colors[index] color = colors[index],
repos = cursor::Left(width as u16)
).ok(); ).ok();
}
stdout.flush().ok(); stdout.flush().ok();
}
for _ in stdin.keys() { break; }
write!(stdout, "{}{}", cursor::Show, clear::All).ok();
stdout.flush().ok(); stdout.flush().ok();
} }

8
src/error.rs Normal file
View file

@ -0,0 +1,8 @@
use std::process::exit;
pub fn too_small(spec: Option<&str>) {
println!("pride: terminal is too small!");
if spec.is_some() { println!("must be at least {}", spec.unwrap()); }
exit(2);
}

View file

@ -1,196 +1,129 @@
use termion::color; use termion::color::{ Fg, Rgb };
use crate::draw::draw; use crate::draw;
pub static BLOCK: &str = ""; pub static BLOCK: &str = "";
pub fn pride(small: bool) { pub fn pride(small: bool) {
let red = color::Fg(color::Rgb(0xE5, 0x00, 0x00)); let red =Fg(Rgb(0xE5, 0x00, 0x00));
let orange = color::Fg(color::Rgb(0xFF, 0x8D, 0x00)); let orange = Fg(Rgb(0xFF, 0x8D, 0x00));
let yellow = color::Fg(color::Rgb(0xFF, 0xEE, 0x00)); let yellow = Fg(Rgb(0xFF, 0xEE, 0x00));
let green = color::Fg(color::Rgb(0x02, 0x81, 0x21)); let green = Fg(Rgb(0x02, 0x81, 0x21));
let blue = color::Fg(color::Rgb(0x00, 0x4C, 0xFF)); let blue = Fg(Rgb(0x00, 0x4C, 0xFF));
let purple = color::Fg(color::Rgb(0x77, 0x00, 0x88)); let purple = Fg(Rgb(0x77, 0x00, 0x88));
if small { // small flag: 18x6 let stripes = &[red, orange, yellow, green, blue, purple];
let width = 18; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{red}{stripe}\n{orange}{stripe}\n{yellow}{stripe}\n{green}{stripe}\n{blue}{stripe}\n{purple}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[red, orange, yellow, green, blue, purple]); }
} }
pub fn transgender(small: bool) { pub fn transgender(small: bool) {
let pink = color::Fg(color::Rgb(0x7A, 0xCB, 0xF5)); let pink = Fg(Rgb(0x7A, 0xCB, 0xF5));
let blue = color::Fg(color::Rgb(0xEA, 0xAC, 0xB8)); let blue = Fg(Rgb(0xEA, 0xAC, 0xB8));
let white = color::Fg(color::Rgb(0xFF, 0xFF, 0xFF)); let white = Fg(Rgb(0xFF, 0xFF, 0xFF));
if small { let stripes = &[pink, blue, white, blue, pink];
let width = 15; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{pink}{stripe}\n{blue}{stripe}\n{white}{stripe}\n{blue}{stripe}\n{pink}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[pink, blue, white, blue, pink]); }
} }
// everything below here is alphabetical // everything below here is alphabetical
pub fn aromantic(small: bool) { pub fn aromantic(small: bool) {
let green = color::Fg(color::Rgb(0x3B, 0xA7, 0x40)); let green = Fg(Rgb(0x3B, 0xA7, 0x40));
let lime = color::Fg(color::Rgb(0xA8, 0xD4, 0x7A)); let lime = Fg(Rgb(0xA8, 0xD4, 0x7A));
let white = color::Fg(color::Rgb(0xFF, 0xFF, 0xFF)); let white = Fg(Rgb(0xFF, 0xFF, 0xFF));
let grey = color::Fg(color::Rgb(0xAB, 0xAB, 0xAB)); let grey = Fg(Rgb(0xAB, 0xAB, 0xAB));
let black = color::Fg(color::Rgb(0x00, 0x00, 0x00)); let black = Fg(Rgb(0x00, 0x00, 0x00));
if small { let stripes = &[green, lime, white, grey, black];
let width = 15; if small { }
else { draw::simple(stripes); }
println!(
"{green}{stripe}\n{lime}{stripe}\n{white}{stripe}\n{grey}{stripe}\n{black}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[green, lime, white, grey, black]); }
} }
pub fn asexual(small: bool) { pub fn asexual(small: bool) {
let black = color::Fg(color::Rgb(0x00, 0x00, 0x00)); let black = Fg(Rgb(0x00, 0x00, 0x00));
let grey = color::Fg(color::Rgb(0xA4, 0xA4, 0xA4)); let grey = Fg(Rgb(0xA4, 0xA4, 0xA4));
let white = color::Fg(color::Rgb(0xFF, 0xFF, 0xFF)); let white = Fg(Rgb(0xFF, 0xFF, 0xFF));
let purple = color::Fg(color::Rgb(0x81, 0x00, 0x81)); let purple = Fg(Rgb(0x81, 0x00, 0x81));
if small { let stripes = &[black, grey, white, purple];
let width = 12; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{black}{stripe}\n{grey}{stripe}\n{white}{stripe}\n{purple}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[black, grey, white, purple]); }
} }
pub fn bigender(small: bool) { pub fn bigender(small: bool) {
let pink = color::Fg(color::Rgb(0xE6, 0x76, 0xA6)); let pink = Fg(Rgb(0xE6, 0x76, 0xA6));
let yellow = color::Fg(color::Rgb(0xF9, 0xF0, 0x4C)); let yellow = Fg(Rgb(0xF9, 0xF0, 0x4C));
let white = color::Fg(color::Rgb(0xFF, 0xFF, 0xFF)); let white = Fg(Rgb(0xFF, 0xFF, 0xFF));
let purple = color::Fg(color::Rgb(0xAB, 0x6B, 0xBB)); let purple = Fg(Rgb(0xAB, 0x6B, 0xBB));
let blue = color::Fg(color::Rgb(0x6D, 0x96, 0xDC)); let blue = Fg(Rgb(0x6D, 0x96, 0xDC));
if small { let stripes = &[pink, yellow, white, purple, blue];
let width = 15; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{pink}{stripe}\n{yellow}{stripe}\n{white}{stripe}\n{purple}{stripe}\n{blue}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[pink, yellow, white, purple, blue]); }
} }
pub fn bisexual(small: bool) { pub fn bisexual(small: bool) {
let magenta = color::Fg(color::Rgb(0xC4, 0x2A, 0x6F)); let magenta = Fg(Rgb(0xC4, 0x2A, 0x6F));
let purple = color::Fg(color::Rgb(0x91, 0x53, 0x92)); let purple = Fg(Rgb(0x91, 0x53, 0x92));
let blue = color::Fg(color::Rgb(0x14, 0x37, 0xA2)); let blue = Fg(Rgb(0x14, 0x37, 0xA2));
if small { let stripes = &[magenta, magenta, purple, blue, blue];
let width = 15; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{magenta}{stripe}\n{stripe}\n{purple}{stripe}\n{blue}{stripe}\n{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[magenta, magenta, purple, blue, blue]); }
} }
pub fn gendervoid(small: bool) { pub fn gendervoid(small: bool) {
let navy = color::Fg(color::Rgb(0x08, 0x11, 0x4A)); let navy = Fg(Rgb(0x08, 0x11, 0x4A));
let gray = color::Fg(color::Rgb(0x4A, 0x48, 0x4B)); let gray = Fg(Rgb(0x4A, 0x48, 0x4B));
let black = color::Fg(color::Rgb(0x00, 0x00, 0x00)); let black = Fg(Rgb(0x00, 0x00, 0x00));
if small { let stripes = &[navy, gray, black, gray, navy];
let width = 15; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{navy}{stripe}\n{gray}{stripe}\n{black}{stripe}\n{gray}{stripe}\n{navy}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[navy, gray, black, gray, navy]); }
} }
pub fn lesbian(small: bool) { pub fn lesbian(small: bool) {
let red = color::Fg(color::Rgb(0xD6, 0x28, 0x00)); let red = Fg(Rgb(0xD6, 0x28, 0x00));
let orange = color::Fg(color::Rgb(0xFF, 0x9B, 0x56)); let orange = Fg(Rgb(0xFF, 0x9B, 0x56));
let white = color::Fg(color::Rgb(0xFF, 0xFF, 0xFF)); let white = Fg(Rgb(0xFF, 0xFF, 0xFF));
let pink = color::Fg(color::Rgb(0xD4, 0x62, 0xA6)); let pink = Fg(Rgb(0xD4, 0x62, 0xA6));
let magenta = color::Fg(color::Rgb(0xA4, 0x00, 0x62)); let magenta = Fg(Rgb(0xA4, 0x00, 0x62));
if small { let stripes = &[red, orange, white, pink, magenta];
let width = 15; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{red}{stripe}\n{orange}{stripe}\n{white}{stripe}\n{pink}{stripe}\n{magenta}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[red, orange, white, pink, magenta]); }
} }
pub fn multigender(small: bool) { pub fn multigender(small: bool) {
let blue = color::Fg(color::Rgb(0x3F, 0x47, 0xCC)); let blue = Fg(Rgb(0x3F, 0x47, 0xCC));
let ltblue = color::Fg(color::Rgb(0x01, 0xA4, 0xE9)); let ltblue = Fg(Rgb(0x01, 0xA4, 0xE9));
let orange = color::Fg(color::Rgb(0xFB, 0x7F, 0x27)); let orange = Fg(Rgb(0xFB, 0x7F, 0x27));
if small { let stripes = &[blue, ltblue, orange, ltblue, blue];
let width = 15; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{blue}{stripe}\n{ltblue}{stripe}\n{orange}{stripe}\n{ltblue}{stripe}\n{blue}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[blue, ltblue, orange, ltblue, blue]); }
} }
pub fn nonbinary(small: bool) { pub fn nonbinary(small: bool) {
let yellow = color::Fg(color::Rgb(0xFF, 0xF4, 0x33)); let yellow = Fg(Rgb(0xFF, 0xF4, 0x33));
let white = color::Fg(color::Rgb(0xFF, 0xFF, 0xFF)); let white = Fg(Rgb(0xFF, 0xFF, 0xFF));
let purple = color::Fg(color::Rgb(0x9B, 0x59, 0xD0)); let purple = Fg(Rgb(0x9B, 0x59, 0xD0));
let black = color::Fg(color::Rgb(0x00, 0x00, 0x00)); let black = Fg(Rgb(0x00, 0x00, 0x00));
if small { let stripes = &[yellow, white, purple, black];
let width = 12; if small { draw::small(stripes); }
else { draw::simple(stripes); }
println!(
"{yellow}{stripe}\n{white}{stripe}\n{purple}{stripe}\n{black}{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[yellow, white, purple, black]); }
} }
pub fn pansexual(small: bool) { pub fn pansexual(small: bool) {
let magenta = color::Fg(color::Rgb(0xFF, 0x1B, 0x8D)); let magenta = Fg(Rgb(0xFF, 0x1B, 0x8D));
let yellow = color::Fg(color::Rgb(0xFF, 0xDA, 0x00)); let yellow = Fg(Rgb(0xFF, 0xDA, 0x00));
let cyan = color::Fg(color::Rgb(0x1B, 0xB3, 0xFF)); let cyan = Fg(Rgb(0x1B, 0xB3, 0xFF));
if small { if small { draw::small(&[magenta, magenta, yellow, yellow, cyan, cyan]); }
let width = 18; else { draw::simple(&[magenta, yellow, cyan]); }
println!(
"{magenta}{stripe}\n{stripe}\n{yellow}{stripe}\n{stripe}\n{cyan}{stripe}\n{stripe}{reset}",
reset = color::Fg(color::Reset),
stripe = BLOCK.repeat(width)
);
} else { draw(&[magenta, yellow, cyan]); }
} }

View file

@ -2,8 +2,11 @@ use std::process::exit;
use pico_args::Arguments; use pico_args::Arguments;
mod complex;
mod draw; mod draw;
mod error;
mod flag; mod flag;
mod util;
fn main() { fn main() {
let mut args = Arguments::from_env(); let mut args = Arguments::from_env();
@ -25,6 +28,8 @@ fn main() {
let subcommand = args.subcommand().unwrap(); let subcommand = args.subcommand().unwrap();
match subcommand.as_deref() { match subcommand.as_deref() {
Some("progress") => complex::progress(small),
Some("pride") | Some("pride") |
Some("gay") => flag::pride(small), Some("gay") => flag::pride(small),
@ -32,6 +37,8 @@ fn main() {
Some("transgender") => flag::transgender(small), Some("transgender") => flag::transgender(small),
Some("aroace") => complex::aroace(small),
Some("aro") | Some("aro") |
Some("aromantic") => flag::aromantic(small), Some("aromantic") => flag::aromantic(small),
@ -45,6 +52,8 @@ fn main() {
Some("gendervoid") => flag::gendervoid(small), Some("gendervoid") => flag::gendervoid(small),
Some("intersex") => complex::intersex(small),
Some("lesbian") => flag::lesbian(small), Some("lesbian") => flag::lesbian(small),
Some("multigender") => flag::multigender(small), Some("multigender") => flag::multigender(small),
@ -55,6 +64,11 @@ fn main() {
Some("pan") | Some("pan") |
Some("pansexual") => flag::pansexual(small), Some("pansexual") => flag::pansexual(small),
Some("poly") |
Some("polyam") |
Some("polyamory") |
Some("polyamorous") => complex::polyamorous(small),
_ => { help_text(); exit(1) } _ => { help_text(); exit(1) }
} }
} }
@ -81,17 +95,20 @@ fn help_text() {
fn list_text() { fn list_text() {
println!("pride v{}", env!("CARGO_PKG_VERSION")); println!("pride v{}", env!("CARGO_PKG_VERSION"));
println!("\nFlag list:"); println!("\nFlag list:");
println!(" aroace aromantic asexual pride flag");
println!(" aro, aromantic aromantic pride flag"); println!(" aro, aromantic aromantic pride flag");
println!(" ace, asexual asexual pride flag"); println!(" ace, asexual asexual pride flag");
println!(" bigender bigender pride flag"); println!(" bigender bigender pride flag");
println!(" bi, bisexual bisexual pride flag"); println!(" bi, bisexual bisexual pride flag");
println!(" gay, pride six-color rainbow flag"); println!(" gay, pride six-color rainbow flag");
println!(" gendervoid gendervoid pride flag"); println!(" gendervoid gendervoid pride flag");
println!(" intersex intersex pride flag");
println!(" lesbian lesbian pride flag"); println!(" lesbian lesbian pride flag");
println!(" multigender multigender pride flag"); println!(" multigender multigender pride flag");
println!(" nb, nonbinary nonbinary pride flag"); println!(" nb, nonbinary nonbinary pride flag");
println!(" pan, pansexual pansexual pride flag"); println!(" pan, pansexual pansexual pride flag");
// println!(" progress progress arrow flag"); println!(" poly, polyamory polyamorous pride flag");
println!(" progress progress arrow flag");
println!(" trans, transgender transgender pride flag"); println!(" trans, transgender transgender pride flag");
} }

15
src/util.rs Normal file
View file

@ -0,0 +1,15 @@
pub fn gcd(a: usize, b: usize) -> usize {
if a == 0 || b == 0 { return 0; }
let min = usize::min(a, b);
let max = usize::max(a, b);
let remainder = max % min;
if remainder == 0 { return min; }
else { return gcd(min, remainder); }
}
pub fn lcm(a: usize, b: usize) -> usize {
return ( a * b ) / gcd(a, b);
}