Compare commits

..

No commits in common. "d6370da9e2d66d43cf68c4d629a1fb41ec91d2f7" and "1332a306bc436725858e244c13b9486a9842f0aa" have entirely different histories.

9 changed files with 101 additions and 522 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "pride" name = "pride"
version = "0.2.0" version = "0.1.5"
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

@ -3,12 +3,14 @@
A Rust utility to display pride flags in the terminal. A Rust utility to display pride flags in the terminal.
A list of currently implemented flags is available on the [project wiki](https://git.vwolfe.io/valerie/pride/wiki/Flags). **This project is under heavy construction! It is subject to major structural and
architectural changes. There are no issues with functionality, but I will continue
to make major changes and refactors until the main roadmap is complete.**
## Dependencies Currently supports a variety of stripe flags.
Some Complex renderers utilize [Powerline's](https://github.com/ryanoasis/powerline-extra-symbols) Under Construction features:
slant symbols, and therefore require use of a Powerline font, such as [Fira Code](https://github.com/tonsky/FiraCode). - [Complex Drawing](https://git.vwolfe.io/valerie/pride/src/branch/complex)
## Libraries ## Libraries

View file

@ -1,5 +1,5 @@
use termion::color::{ Bg, Fg, Rgb, Reset }; use termion::color::{ Fg, Rgb, Reset };
pub type Color = Fg<Rgb>; pub type Color = Fg<Rgb>;
pub type Colors = Vec<Fg<Rgb>>; pub type Colors = Vec<Fg<Rgb>>;
@ -8,9 +8,8 @@ pub static BLACK: Color = Fg(Rgb(0x00, 0x00, 0x00));
pub static WHITE: Color = Fg(Rgb(0xFF, 0xFF, 0xFF)); pub static WHITE: Color = Fg(Rgb(0xFF, 0xFF, 0xFF));
pub static RESET: Fg<Reset> = Fg(Reset); pub static RESET: Fg<Reset> = Fg(Reset);
pub static RESET_BG: Bg<Reset> = Bg(Reset);
/// produces a termion foreground color from the provided integer /// converts a hex integer to Fg(Rgb)
pub fn rgb(hex: u32) -> Color { pub fn rgb(hex: u32) -> Color {
// colors should be 0xrrggbb = 0x__rrggbb; drop the most significant byte // colors should be 0xrrggbb = 0x__rrggbb; drop the most significant byte
let [_, r, g, b] = hex.to_be_bytes(); let [_, r, g, b] = hex.to_be_bytes();
@ -18,10 +17,3 @@ pub fn rgb(hex: u32) -> Color {
Fg(Rgb(r, g, b)) Fg(Rgb(r, g, b))
} }
/// produces a termion background color from the provided integer
pub fn bg(hex: u32) -> Bg<Rgb> {
let [_, r, g, b] = hex.to_be_bytes();
Bg(Rgb(r, g, b))
}

View file

@ -1,292 +0,0 @@
//! flags that require more complex rendering than just scaling colored stripes
use termion::{
terminal_size,
color::{ Bg, Rgb }
};
use crate::{
color::*,
draw,
flag::{ self, Flag },
util::{ ansi_len, ansi_substr }
};
/// vertically stacking eighths
pub static V_EIGHTH: [char; 7] = ['▁', '▂', '▃', '▄', '▅', '▆', '▇'];
/// horizontally stacking eighths
pub static H_EIGHTH: [char; 7] = ['▏', '▎', '▍', '▌', '▋', '▊', '▉'];
/// shading by intensity
pub static SHADING: [char; 3] = ['░', '▒', '▓'];
/// 2/1 slope triangle cut in
pub static TRIANGLE_21: [char; 3] = ['', '🭬', ''];
/// 2/3 slope slant
pub static SLANT_23: [char; 2] = ['🭒', '🭏'];
pub fn progress(small: bool) -> Flag {
let red = bg(0xE50000);
let orange = bg(0xFF8D00);
let yellow = bg(0xFFEE00);
let green = bg(0x028121);
let blue = bg(0x004CFF);
let purple = bg(0x770088);
// we need these colors in both fg & bg; just hold the integers for now
let black: u32 = 0;
let brown: u32 = 0x784F17;
let ltblue: u32 = 0xEAACB8;
let pink: u32 = 0x7ACBF5;
let white: u32 = 0xFFFFFF;
let (width, height) = if small { (18, 6) } else { terminal_size().unwrap() };
// create color slices and line buffer
let stripes = [red, orange, yellow, green, blue, purple];
let chevrons = [white, ltblue, pink, brown, black];
let mut lines: Vec<String> = Vec::new();
// set up stripe index
let mut index = 0;
/* ok, coming up with procedure:
* - can't rely on bg_stripes; line count, threshold, etc., will need to happen here
* - line count will always be the largest multiple of 6 smaller than height; c = h - (h % 6)
* - chevrons may have larger widths: TODO calc
* - depth will be funky; line depth will need to use "full" depth; (Df - Dl) / Wc = Ic (TODO verify?)
* - switch stripe index on *absolute* line number rather than n
* - chevron building will be BLOCK.repeat(width) + TRIANGLE_21[0] (fg Ic, bg Ic + 1)
* - chevrons[len - 1] will need unique handling to draw stripes
*/
// set up constraints
let linecount = height - (height % 6); // largest multiple of 6 smaller than height
let full_depth = width / 3;
let chevron_width = (full_depth / 6) - 1;
let direction_thresh = linecount / 2;
let corner = linecount % 2 == 1;
let thresh = linecount / 6; // stripe threshold; no bg_stripes call!
let mut line_no = 0; // absolute line number; n is relative
// chevron helper
let build_chevron = | separator: char | -> String {
let mut output = format!(
"{fg}{bg}{stripe}{separator}",
fg = rgb(chevrons[0]),
bg = bg(chevrons[1]),
stripe = draw::BLOCK.repeat( usize::max(chevron_width as usize * 2, 1) )
);
let stripe = draw::BLOCK.repeat(chevron_width as usize);
for i in 1..4 {
output += &format!(
"{fg}{bg}{stripe}{separator}",
fg = rgb(chevrons[i]),
bg = bg(chevrons[i + 1])
);
}
output += &format!(
"{fg}{stripe}",
fg = rgb(chevrons[4])
);
output
};
// piecewise functions: ascent -> peak -> descent
let mut base = build_chevron(TRIANGLE_21[0]);
let base_length = base.len();
let display_length = ansi_len(&base) + 1; // chevron width will always stay the same; add 1 for the last separator
for n in 0..direction_thresh {
// advance stripe color at stripe threshold by line number
if line_no != 0 && line_no % thresh == 0 { index += 1; }
// grab our substring constraints
let start = (direction_thresh - n) as usize - 1;
let diff = display_length - start;
// take substring of chevron line...
let mut line = ansi_substr(&base, start as usize, base_length);
// ... and add the colored stripe
line += &format!(
"{stripe}{separator}{line}",
stripe = stripes[index],
separator = TRIANGLE_21[0],
line = " ".repeat(width as usize - diff)
);
lines.push(line);
line_no += 1;
}
if corner {
if line_no % thresh == 0 { index += 1; }
let base = build_chevron(TRIANGLE_21[1]);
let mut line = ansi_substr(&base, 0, base_length);
line += &format!(
"{stripe}{separator}{line}",
stripe = stripes[index],
separator = TRIANGLE_21[1],
line = " ".repeat(width as usize - display_length)
);
lines.push(line);
line_no += 1;
}
base = build_chevron(TRIANGLE_21[2]);
for n in 0..direction_thresh {
if line_no % thresh == 0 { index += 1; }
if index > 5 { break; }
let start = n as usize;
let diff = display_length - start;
let mut line = ansi_substr(&base, start, base_length);
line += &format!(
"{stripe}{separator}{line}",
stripe = stripes[index],
separator = TRIANGLE_21[2],
line = " ".repeat(width as usize - diff)
);
lines.push(line);
line_no += 1;
}
Flag::Lines(lines)
}
// everything below this point is in alphabetical order
pub fn aroace(small: bool) -> Flag {
// pull colors from aro & ace stripe flags
let Flag::Stripes(aro) = flag::aromantic() else { panic!() };
let Flag::Stripes(ace) = flag::asexual() else { panic!() };
let (width, height) = if small { (60, 20) } else { terminal_size().unwrap() };
let mut lines: Vec<String> = Vec::new();
// set up constraints
let linecount = height - (height % 20);
let aro_thresh = linecount / 5; // threshold for aromantic colors
let ace_thresh = linecount / 4; // threshold for asexual colors
let stripe = draw::BLOCK.repeat((width / 2) as usize);
let mut aro_index = 0;
let mut ace_index = 0;
for n in 0..linecount {
// switch colors on thresholds
if n != 0 {
if n % aro_thresh == 0 { aro_index += 1; }
if n % ace_thresh == 0 { ace_index += 1; }
}
let line = format!("{}{stripe}{}{stripe}", aro[aro_index], ace[ace_index]);
lines.push(line);
}
Flag::Lines(lines)
}
fn demi_orientation_render(middle: Bg<Rgb>, bottom: Bg<Rgb>, width: u16, height: u16) -> Vec<String> {
let white = bg(0xFFFFFF);
let stripes = vec![white, white, middle, bottom, bottom];
// initial stripe output buffer
let mut lines: Vec<String> = draw::bg_stripes(stripes, width, height);
// assemble triangle cut-in
let linecount = lines.len();
let depth = linecount / 2;
let corner = linecount % 2 == 1;
// piecewise functions: ascending -> peak -> descending
for n in 0..depth {
let line = lines[n].clone();
let replacement = format!("{BLACK}{}{}", draw::BLOCK.repeat(n), TRIANGLE_21[0]);
lines[n] = line.replacen(&" ".repeat(n + 1), &replacement, 1);
}
if corner {
let line = lines[depth].clone();
let replacement = format!("{BLACK}{}{}", draw::BLOCK.repeat(depth), TRIANGLE_21[1]);
lines[depth] = line.replacen(&" ".repeat(depth + 1), &replacement, 1);
}
let start = depth + (linecount % 2);
for n in 0..depth {
let line = lines[start + n].clone();
let size = depth - n - 1;
let replacement = format!("{BLACK}{}{}", draw::BLOCK.repeat(size), TRIANGLE_21[2]);
lines[start + n] = line.replacen(&" ".repeat(size + 1), &replacement, 1);
}
lines
}
pub fn demiromantic(small: bool) -> Flag {
let green = bg(0x3DA542);
let gray = bg(0xD2D2D2);
let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() };
let lines = demi_orientation_render(green, gray, width, height);
Flag::Lines(lines)
}
pub fn demisexual(small: bool) -> Flag {
let purple = bg(0x832FA8);
let grey = bg(0x7B868C);
let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() };
let lines = demi_orientation_render(purple, grey, width, height);
Flag::Lines(lines)
}
pub fn disability() {
let gray = bg(0x575757);
let green: u32 = 0x3AAD7D;
let blue: u32 = 0x79BFE0;
let white: u32 = 0xE8E8E8;
let yellow: u32 = 0xEDDB76;
let red: u32 = 0xCD7281;
let stripes = [red, yellow, white, blue, green];
// 2/3 slant stripes with gray background
}
pub fn intersex() -> Flag {
let yellow = bg(0xFFDA00);
let purple = rgb(0x7A00AC);
let block = " ";
let stripe = block.repeat(9);
let part = block.repeat(4);
let lines = vec![
format!("{yellow}{stripe}"),
format!("{part}{purple}O{part}"),
format!("{stripe}")
];
Flag::Lines(lines)
}
pub fn polyamorous() {
let blue = rgb(0x019FE3);
let magenta = rgb(0xE50051);
let purple = rgb(0x340C46);
let yellow = rgb(0x00FCBF);
// blue / magenta / purple vert
// WHITE isosceles cutin with yellow heart pointed right
}

View file

@ -4,110 +4,76 @@ use termion::{
terminal_size, terminal_size,
clear, clear,
color::{ Bg, Fg, Rgb },
cursor, cursor,
input::TermRead, input::TermRead,
raw::IntoRawMode raw::IntoRawMode
}; };
use crate::{ use crate::color::{ RESET, Colors };
color::{ RESET, RESET_BG }, use crate::flag::BLOCK;
flag::Flag
};
pub static BLOCK: &str = ""; /// draw a fullscreen stripe flag and hold for keypress
pub static UHALF: &str = ""; pub fn full(colors: Colors) {
// prepare stdin and stdout
pub fn draw_lines(lines: Vec<String>, hold: bool) {
let mut stdout = io::stdout().into_raw_mode().unwrap(); let mut stdout = io::stdout().into_raw_mode().unwrap();
let count = lines.len() as u16;
for _ in 0..count { write!(stdout, "\n").ok(); }
write!(stdout, "{}", cursor::Up(count)).ok();
if hold { write!(stdout, "{}{}", cursor::Hide, clear::All).ok(); }
let down = cursor::Down(1);
for line in lines {
let left = cursor::Left(line.len() as u16);
write!(stdout, "{line}{left}{down}").ok();
}
write!(stdout, "{RESET}{RESET_BG}").ok();
stdout.flush().ok();
if hold {
let stdin = io::stdin(); let stdin = io::stdin();
for _ in stdin.keys() { break; }
write!(stdout, "{}", clear::All).ok();
}
write!(stdout, "{}", cursor::Show).ok();
stdout.flush().ok();
}
pub fn fg_stripes(colors: Vec<Fg<Rgb>>, width: u16, height: u16) -> Vec<String> { // get constraints
let width = width as usize;
let height = height as usize;
let count = colors.len(); let count = colors.len();
let (width, height) = terminal_size().unwrap();
let thresh = height as usize / count;
let thresh = height / count; // clear the terminal
write!(stdout, "{}{}", cursor::Hide, clear::All).ok();
stdout.flush().ok();
let stripe = BLOCK.repeat(width); // build terminal width stripe string
let mut output = Vec::new(); let stripe = BLOCK.repeat(width as usize);
// create our color index // create our color index
let mut index = 0; let mut index = 0;
for n in 0..height { // for every terminal row...
for n in 0..(height as usize) {
// ... increment our index at color change threshold
if n != 0 && n % thresh == 0 { if n != 0 && n % thresh == 0 {
index += 1; index += 1;
// and break if out of bounds // and break if out of bounds
if index >= count { break; } if index >= count { break; }
} }
let color = colors[index]; // ... draw the stripe with color at index
output.push(format!("{color}{stripe}")); write!(
stdout,
"{color}{stripe}{RESET}",
color = colors[index]
).ok();
} }
// flush stdout
stdout.flush().ok();
output // wait for keypress
for _ in stdin.keys() { break; }
write!(stdout, "{}{}", cursor::Show, clear::All).ok();
stdout.flush().ok();
} }
pub fn bg_stripes(colors: Vec<Bg<Rgb>>, width: u16, height: u16) -> Vec<String> {
let width = width as usize; /// draws a small stripe flag
let height = height as usize; pub fn small(colors: Colors) {
// prepare stdout
let mut stdout = io::stdout();
// get constraints
let count = colors.len(); let count = colors.len();
let width = count * 3;
let thresh = height / count; // build small stripe string
let stripe = BLOCK.repeat(width);
let stripe = " ".repeat(width); // print a stripe for all colors
let mut output = Vec::new(); for color in colors {
println!("{color}{stripe}");
let mut index = 0;
for n in 0..height {
if n != 0 && n % thresh == 0 {
index += 1;
if index >= count { break; }
}
let color = colors[index];
output.push(format!("{color}{stripe}"));
}
output
}
impl Flag {
pub fn draw(self, hold: bool) {
let lines = match self {
Flag::Stripes(colors)
=> {
let (width, height);
if hold { (width, height) = terminal_size().unwrap(); }
else {
height = colors.len() as u16;
width = height * 3;
}
fg_stripes(colors, width, height)
},
Flag::Lines(lines)
=> lines
};
draw_lines(lines, hold);
} }
// reset our foreground color to play nice and flush stdout
print!("{RESET}");
stdout.flush().ok();
} }

View file

@ -3,13 +3,9 @@
use crate::color::*; use crate::color::*;
pub enum Flag { pub static BLOCK: &str = "";
Stripes(Colors),
Lines(Vec<String>)
}
pub fn pride() -> Colors {
pub fn pride() -> Flag {
let red = rgb(0xE50000); let red = rgb(0xE50000);
let orange = rgb(0xFF8D00); let orange = rgb(0xFF8D00);
let yellow = rgb(0xFFEE00); let yellow = rgb(0xFFEE00);
@ -17,58 +13,58 @@ pub fn pride() -> Flag {
let blue = rgb(0x004CFF); let blue = rgb(0x004CFF);
let purple = rgb(0x770088); let purple = rgb(0x770088);
Flag::Stripes(vec![red, orange, yellow, green, blue, purple]) vec![red, orange, yellow, green, blue, purple]
} }
pub fn transgender() -> Flag { pub fn transgender() -> Colors {
let pink = rgb(0x7ACBF5); let pink = rgb(0x7ACBF5);
let blue = rgb(0xEAACB8); let blue = rgb(0xEAACB8);
Flag::Stripes(vec![pink, blue, WHITE, blue, pink]) vec![pink, blue, WHITE, blue, pink]
} }
// everything below here is alphabetical // everything below here is alphabetical
pub fn agender() -> Flag { pub fn agender() -> Colors {
let gray = rgb(0xB9B9B9); let gray = rgb(0xB9B9B9);
let green = rgb(0xB8F483); let green = rgb(0xB8F483);
Flag::Stripes(vec![BLACK, gray, WHITE, green, WHITE, gray, BLACK]) vec![BLACK, gray, WHITE, green, WHITE, gray, BLACK]
} }
pub fn aromantic() -> Flag { pub fn aromantic() -> Colors {
let green = rgb(0x3BA740); let green = rgb(0x3BA740);
let lime = rgb(0xA8D47A); let lime = rgb(0xA8D47A);
let grey = rgb(0xABABAB); let grey = rgb(0xABABAB);
Flag::Stripes(vec![green, lime, WHITE, grey, BLACK]) vec![green, lime, WHITE, grey, BLACK]
} }
pub fn asexual() -> Flag { pub fn asexual() -> Colors {
let grey = rgb(0xA4A4A4); let grey = rgb(0xA4A4A4);
let purple = rgb(0x810081); let purple = rgb(0x810081);
Flag::Stripes(vec![BLACK, grey, WHITE, purple]) vec![BLACK, grey, WHITE, purple]
} }
pub fn bigender() -> Flag { pub fn bigender() -> Colors {
let pink = rgb(0xE676A6); let pink = rgb(0xE676A6);
let yellow = rgb(0xF9F04C); let yellow = rgb(0xF9F04C);
let purple = rgb(0xAB6BBB); let purple = rgb(0xAB6BBB);
let blue = rgb(0x6D96DC); let blue = rgb(0x6D96DC);
Flag::Stripes(vec![pink, yellow, WHITE, purple, blue]) vec![pink, yellow, WHITE, purple, blue]
} }
pub fn bisexual() -> Flag { pub fn bisexual() -> Colors {
let magenta = rgb(0xC42A6F); let magenta = rgb(0xC42A6F);
let purple = rgb(0x915392); let purple = rgb(0x915392);
let blue = rgb(0x1437A2); let blue = rgb(0x1437A2);
Flag::Stripes(vec![magenta, magenta, purple, blue, blue]) vec![magenta, magenta, purple, blue, blue]
} }
pub fn gay() -> Flag { pub fn gay() -> Colors {
let green1 = rgb(0x00906D); let green1 = rgb(0x00906D);
let green2 = rgb(0x00D1A7); let green2 = rgb(0x00D1A7);
let green3 = rgb(0x7EEBC1); let green3 = rgb(0x7EEBC1);
@ -76,68 +72,68 @@ pub fn gay() -> Flag {
let blue2 = rgb(0x5543D3); let blue2 = rgb(0x5543D3);
let blue3 = rgb(0x461280); let blue3 = rgb(0x461280);
Flag::Stripes(vec![green1, green2, green3, WHITE, blue1, blue2, blue3]) vec![green1, green2, green3, WHITE, blue1, blue2, blue3]
} }
pub fn genderfluid() -> Flag { pub fn genderfluid() -> Colors {
let pink = rgb(0xFF75A2); let pink = rgb(0xFF75A2);
let violet = rgb(0xBE18D6); let violet = rgb(0xBE18D6);
let blue = rgb(0x333EBD); let blue = rgb(0x333EBD);
Flag::Stripes(vec![pink, WHITE, violet, BLACK, blue]) vec![pink, WHITE, violet, BLACK, blue]
} }
pub fn gender_nonconforming() -> Flag { pub fn gender_nonconforming() -> Colors {
let purple = rgb(0x50284D); let purple = rgb(0x50284D);
let magenta = rgb(0x96467B); let magenta = rgb(0x96467B);
let blue = rgb(0x5C96F7); let blue = rgb(0x5C96F7);
Flag::Stripes(vec![purple, purple, magenta, blue, WHITE, blue, magenta, purple, purple]) vec![purple, purple, magenta, blue, WHITE, blue, magenta, purple, purple]
} }
pub fn genderqueer() -> Flag { pub fn genderqueer() -> Colors {
let purple = rgb(0xB899DF); let purple = rgb(0xB899DF);
let green = rgb(0x6B8E3B); let green = rgb(0x6B8E3B);
Flag::Stripes(vec![purple, WHITE, green]) vec![purple, WHITE, green]
} }
pub fn gendervoid() -> Flag { pub fn gendervoid() -> Colors {
let navy = rgb(0x08114A); let navy = rgb(0x08114A);
let gray = rgb(0x4A484B); let gray = rgb(0x4A484B);
Flag::Stripes(vec![navy, gray, BLACK, gray, navy]) vec![navy, gray, BLACK, gray, navy]
} }
pub fn lesbian() -> Flag { pub fn lesbian() -> Colors {
let red = rgb(0xD62800); let red = rgb(0xD62800);
let orange = rgb(0xFF9B56); let orange = rgb(0xFF9B56);
let pink = rgb(0xD462A6); let pink = rgb(0xD462A6);
let magenta = rgb(0xA40062); let magenta = rgb(0xA40062);
Flag::Stripes(vec![red, orange, WHITE, pink, magenta]) vec![red, orange, WHITE, pink, magenta]
} }
pub fn multigender() -> Flag { pub fn multigender() -> Colors {
let blue = rgb(0x3F47CC); let blue = rgb(0x3F47CC);
let ltblue = rgb(0x01A4E9); let ltblue = rgb(0x01A4E9);
let orange = rgb(0xFB7F27); let orange = rgb(0xFB7F27);
Flag::Stripes(vec![blue, ltblue, orange, ltblue, blue]) vec![blue, ltblue, orange, ltblue, blue]
} }
pub fn nonbinary() -> Flag { pub fn nonbinary() -> Colors {
let yellow = rgb(0xFFF433); let yellow = rgb(0xFFF433);
let purple = rgb(0x9B59D0); let purple = rgb(0x9B59D0);
Flag::Stripes(vec![yellow, WHITE, purple, BLACK]) vec![yellow, WHITE, purple, BLACK]
} }
pub fn pansexual() -> Flag { pub fn pansexual() -> Colors {
let magenta = rgb(0xFF1B8D); let magenta = rgb(0xFF1B8D);
let yellow = rgb(0xFFDA00); let yellow = rgb(0xFFDA00);
let cyan = rgb(0x1BB3FF); let cyan = rgb(0x1BB3FF);
Flag::Stripes(vec![magenta, yellow, cyan]) vec![magenta, yellow, cyan]
} }

View file

@ -3,13 +3,11 @@ use std::process::exit;
use pico_args::Arguments; use pico_args::Arguments;
mod color; mod color;
mod complex;
mod draw; mod draw;
mod flag; mod flag;
mod util;
mod variant; mod variant;
use crate::flag::Flag; use crate::color::Colors;
static VERSION: &str = env!("CARGO_PKG_VERSION"); static VERSION: &str = env!("CARGO_PKG_VERSION");
@ -41,7 +39,7 @@ fn main() {
let subcommand = args.subcommand().unwrap(); let subcommand = args.subcommand().unwrap();
// get color vec from matched flag // get color vec from matched flag
let flag: Flag = match subcommand.as_deref() { let colors: Colors = match subcommand.as_deref() {
Some("pride" | "rainbow") Some("pride" | "rainbow")
| None | None
=> { => {
@ -51,8 +49,6 @@ fn main() {
=> variant::gilbert_baker(), => variant::gilbert_baker(),
Some("philadelphia") Some("philadelphia")
=> variant::philadelphia(), => variant::philadelphia(),
Some("progress")
=> complex::progress(small),
_ _
=> flag::pride() => flag::pride()
} }
@ -71,24 +67,12 @@ fn main() {
Some("asexual" | "ace") Some("asexual" | "ace")
=> flag::asexual(), => flag::asexual(),
Some("aroace" | "aromantic-asexual")
=> complex::aroace(small),
Some("bigender") Some("bigender")
=> flag::bigender(), => flag::bigender(),
Some("bisexual" | "bi") Some("bisexual" | "bi")
=> flag::bisexual(), => flag::bisexual(),
Some("demiromantic")
=> complex::demiromantic(small),
Some("demisexual")
=> complex::demisexual(small),
// Some("disability")
// => complex::disability();
Some("gay" | "mlm") Some("gay" | "mlm")
=> flag::gay(), => flag::gay(),
@ -104,9 +88,6 @@ fn main() {
Some("gendervoid") Some("gendervoid")
=> flag::gendervoid(), => flag::gendervoid(),
Some("intersex")
=> complex::intersex(),
Some("lesbian") Some("lesbian")
=> flag::lesbian(), => flag::lesbian(),
@ -119,13 +100,11 @@ fn main() {
Some("pansexual" | "pan") Some("pansexual" | "pan")
=> flag::pansexual(), => flag::pansexual(),
// Some("poly" | "polyamorous" | "polyamory") _ => { help_text(); exit(1) } // (or die)
// => complex::polyamorous(),
_ => { help_text(); exit(1) }
}; };
flag.draw(!small); if small { draw::small(colors); }
else { draw::full(colors); }
} }
@ -155,25 +134,19 @@ fn list_text() {
println!(" agender agender pride flag"); println!(" agender agender 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!(" aroace aromantic/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!(" demiromantic demiromantic pride flag");
println!(" demisexual demisexual pride flag");
// println!(" disability disability pride flag");
println!(" gay, mlm gay men pride flag"); println!(" gay, mlm gay men pride flag");
println!(" genderfluid genderfluid pride flag"); println!(" genderfluid genderfluid pride flag");
println!(" gender-nonconforming gender nonconforming pride flag"); println!(" gender-nonconforming gender nonconforming pride flag");
println!(" genderqueer genderqueer pride flag"); println!(" genderqueer genderqueer pride 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!(" poly, polyamorous polyamorous pride flag");
println!(" pride, rainbow six-color rainbow flag"); println!(" pride, rainbow six-color rainbow flag");
println!(" progress progress arrow flag"); // println!(" progress progress arrow flag");
println!(" trans, transgender transgender pride flag"); println!(" trans, transgender transgender pride flag");
} }

View file

@ -1,52 +0,0 @@
/// gets the substring of displayed characters of an ANSI formatted string
pub fn ansi_substr(source: &str, start: usize, end: usize) -> String {
// init output string
let mut output = String::new();
// trackers
let mut escaped = false;
let mut index = 0;
for character in source.chars() {
// escape character delimits start and end of ansi sequences
if character == '\u{1B}' {
escaped = true;
output.push(character);
}
// push ALL escaped characters
if escaped {
output.push(character);
// and unset esc on m
if character == 'm' { escaped = false; }
}
// non-escaped characters must obey bounds
else {
if index < start {
index += 1;
continue;
}
output.push(character);
index += 1;
if index > end { break; }
}
}
output
}
/// gets the number of displayed characters in an ANSI formatted string
pub fn ansi_len(source: &str) -> usize {
let mut output = 0;
let mut escaped = false;
for character in source.chars() {
if character == '\u{1B}' { escaped = true; }
if !escaped { output += 1; }
else if character == 'm' { escaped = false; }
}
output
}

View file

@ -3,10 +3,10 @@
use crate::{ use crate::{
color::*, color::*,
flag::{ self, Flag } flag
}; };
pub fn gilbert_baker() -> Flag { pub fn gilbert_baker() -> Colors {
let pink = rgb(0xFF69B4); // sex let pink = rgb(0xFF69B4); // sex
let red = rgb(0xFF0000); // life let red = rgb(0xFF0000); // life
let orange = rgb(0xFF8F00); // healing let orange = rgb(0xFF8F00); // healing
@ -16,22 +16,16 @@ pub fn gilbert_baker() -> Flag {
let indigo = rgb(0x3E0099); // serenity let indigo = rgb(0x3E0099); // serenity
let purple = rgb(0x8F008F); // spirit let purple = rgb(0x8F008F); // spirit
Flag::Stripes(vec![pink, red, orange, yellow, green, cyan, indigo, purple]) vec![pink, red, orange, yellow, green, cyan, indigo, purple]
} }
pub fn philadelphia() -> Flag { pub fn philadelphia() -> Colors {
let brown = rgb(0x784F17); let brown = rgb(0x784F17);
let base = flag::pride(); let mut output = flag::pride();
let mut colors = match base { output.insert(0, BLACK);
Flag::Stripes(inner) output.insert(1, brown);
=> inner,
_
=> { panic!("impossible enum variant"); }
};
colors.insert(0, BLACK);
colors.insert(1, brown);
Flag::Stripes(colors) output
} }