banner/
banner.rs

1use std::{
2    io::{BufRead, stdin},
3};
4use unifont_bitmap::Unifont;
5
6fn banner_print(unifont: &mut Unifont, ink: char, wat: &str) {
7    for c in wat.chars() {
8	let bitmap = unifont.load_bitmap(c as u32);
9	let pitch = if bitmap.is_wide() { 2 } else { 1 };
10	for x in 0..bitmap.get_dimensions().0 {
11	    for _ in 0 .. 2 {
12		for y in (0..16).rev() {
13		    for _ in 0 .. 2 {
14			let bi = (x/8) + y*pitch;
15			let shift = x%8;
16			let b = bitmap.get_bytes()[bi];
17			if (128 >> shift) & b == 0 {
18			    print!(" ");
19			}
20			else {
21			    print!("{}", ink);
22			}
23		    }
24		}
25		println!("");
26	    }
27	}
28    }
29}
30
31fn main() {
32    let args: Vec<String> = std::env::args().collect();
33    if args.len() < 2 {
34	eprintln!("At least one argument must be specified.\n\
35		   \n\
36		   Usage: banner [--blocks] [--] [text to output...]\n\
37		   \n\
38		   If no text is given as arguments, will print text from \
39		   standard input.\n\
40		   \n\
41		   If you want to just do a banner from standard input, \
42		   without using --blocks,\ndo: \"banner --\"\n\
43		   \n\
44		   --blocks: Use a U+2588 FULL BLOCK as \"ink\" instead of \
45		   #. May break some\nterminals.\n\
46		   \n\
47		   Please note that this example makes no attempt to account \
48		   for combining\ncharacters or invisibles!");
49	std::process::exit(1);
50    }
51    let mut args = &args[1..];
52    let ink = if args.get(0).map(String::as_str) == Some("--blocks") {
53	args = &args[1..];
54	'\u{2588}'
55    } else { '#' };
56    let mut unifont = Unifont::open();
57    if args.get(0).map(String::as_str) == Some("--") {
58	args = &args[1..];
59    }
60    if args.len() == 0 {
61	// read lines and print those as banner
62	let stdin = stdin();
63	let mut lines = stdin.lock().lines();
64	let mut first = true;
65	while let Some(line) = lines.next() {
66	    let line = line.unwrap();
67	    if !first {
68		banner_print(&mut unifont, ink, " ");
69	    } else { first = true }
70	    banner_print(&mut unifont, ink, &line);
71	}
72    }
73    else {
74	// print args as banner, separated by space
75	let mut first = true;
76	for arg in args {
77	    if !first {
78		banner_print(&mut unifont, ink, " ");
79	    } else { first = true }
80	    banner_print(&mut unifont, ink, arg);
81	}
82    }
83}