Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple different fonts on the same line #78

Open
frederic-loui opened this issue May 3, 2024 · 7 comments
Open

Multiple different fonts on the same line #78

frederic-loui opened this issue May 3, 2024 · 7 comments

Comments

@frederic-loui
Copy link

First of all, thanks for this awesome piece of code !
I could not see a previous question related to that, hence, here it is:
Is it possible:

  • to specify multiple values at the same time with cfonts
  • each value would have different option style
  • and have them displayed on the same line ?

For example:

cfonts "hello" -f "simple3d" -c "red" "world" -f "3d" -c "green"

I'm using rust crate but this can be applicable to all cfonts flavor ?
(I tried multiple tests with render but did not succeed on reaching the result described above )

@dominikwilkowski
Copy link
Owner

dominikwilkowski commented May 3, 2024

Hi @frederic-loui

Do you mean putting two different fonts on the same line?

That's not supported out of the box right now but you could do it yourself in code by using the lines Vec you get and merging them yourself? (Just append the strings to each other)

Doing this for the CLI interface would be an interesting challenge. You'd have to deal with the differences in line heights and supported colors for each font and how I parse the CLI arguments would have to change. I think that's probably too much work though I have been wishing for putting another line next to a cfonts generated logo in the past. I actually just did this in my coup code game here:
https://github.com/dominikwilkowski/coup/blob/main/src/lib.rs#L1146-L1152

let output = render(Options {
	text: String::from("Coup"),
	colors: vec![Colors::White, Colors::Yellow],
	spaceless: true,
	..Options::default()
});
println!("\n\n{}\x1b[4Dv{}\n\n", output.text, env!("CARGO_PKG_VERSION"));

Which looks like this:
image

(The ANSI escape sequence \x1b[4D will move the cursor 4 spaces to the left.)

@frederic-loui
Copy link
Author

frederic-loui commented May 4, 2024

Thanks for the sample code... After your email yesterday I was looking at which vec of string to concatenate and i presume it is vec in RenderedString.

WRT your sample code i tried the same thing with Simple3d and both words were in different lines:

fn display_banner(text: &str, font: Fonts, color: Colors) {
    let banner = render(Options {
        text: String::from(text),
        font: font,         
        colors: vec![color],
        ..Options::default()
    });
    let banner_2 = render(Options {
        text: String::from("rocks !"),
        font: Fonts::FontBlock, 
        colors: vec![Colors::RedBright],
        ..Options::default()
    });
    print!("{}{}", banner.text, banner_2.text);
}

The result below:

cfonts-multiple-words

GitHub seems to have some issues to render this image so you can get it via this link

In order to simplify the problem I can try to use the same font but different colors ?

@dominikwilkowski
Copy link
Owner

Out of the RenderString use the vec field instead and merge both vecs together.

Here is a quick example:

use cfonts::{render, Colors, Fonts, Options};

fn display_banner(text: &str, font: Fonts, color: Colors) {
	let banner = render(Options {
		text: String::from(text),
		font: font,
		spaceless: true,
		colors: vec![color],
		..Options::default()
	});
	let banner_2 = render(Options {
		text: String::from("rocks !"),
		font: Fonts::FontBlock,
		colors: vec![Colors::RedBright],
		spaceless: true,
		..Options::default()
	});

	let output = banner
		.vec
		.iter()
		.enumerate()
		.map(|(index, line)| {
			if let Some(banner_2_line) = banner_2.vec.get(index) {
				format!("{}  {}", line, banner_2_line)
			} else {
				line.clone()
			}
		})
		.collect::<Vec<String>>();

	print!("\n\n{}\n\n", output.join("\n"));
}

fn main() {
	display_banner("cfonts", Fonts::FontSimple3d, Colors::Green);
}
image

Note that this only works if the first font has equal or more lines than the second font or the second font will get cut off:
image

Hope this helps

@frederic-loui
Copy link
Author

This is perfect ! This was actually what i initially pictured when you first suggested to concatenate the vec out of RenderedString. Generalizing this to other cfonts flavor (nodejs, cli, rust) would be an enhancement. (Granted the constraint related to the number of lines per font)

What if:

  • we test before which fonts has more line
  • and align the concatenated output based on the font that have more lines ?

Anyway, thanks again for your feedback !

@dominikwilkowski
Copy link
Owner

dominikwilkowski commented May 4, 2024

Glad it worked.
Yeah the merging of two fonts isn't a big issue. Which is why I expose the vec in the first place.
The problem is the ergonomics of how you'd do that in either interfaces code and cli.
You wrote out the cli one but how do you know when a new cfonts block starts?
cfonts "my text" -f 3d
That's one block. Adding another is to check the next flag and see if it's any of the allowed options and if not treat it like a new block?
That'll make the cli parser pretty complex.

And ^ that's just the cli interface. What about the code one:

render(Options {
	text: String::from(text),
	font: font,
	spaceless: true,
	colors: vec![color],
	..Options::default()
})

How do I add another font?
You could change it to make it methods on the cfonts struct which would be a re-write if the lib. Not opposed to re-writes just weighing off the tradeoffs here.

@frederic-loui
Copy link
Author

frederic-loui commented May 4, 2024 via email

@dominikwilkowski
Copy link
Owner

I might just keep this issue open for a bit to see if there is more interest.
Otherwise I think it might be too much work.

@dominikwilkowski dominikwilkowski changed the title [cfonts/rust] multiple values with different option style Multiple different fonts on the same line May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants