Open k86td opened 5 days ago
Hi @k86td
Sorry for late reply.
I am pretty confident that it's possible to do with tabled
.
But to be honest I haven't understood the issue properly :(
Could you example once again?
In mean time, look at my example. I think it's what you want? To be honest I quite dissatisfied how complex it is :disappointed:
It looks like it would great to add some type of iterator callback to modify cells.
use std::convert::TryFrom;
use owo_colors::OwoColorize;
use tabled::{
settings::{object::Rows, style::BorderColor, themes::Colorization, Color, Style},
Table,
};
fn main() {
let expenses = vec![
("1", "11.11.11", "11.11.11", "11.11.11"),
("2", "11.22.11", "11.11.11", "11.11.11"),
("3", "11.33.11", "11.11.11", "11.11.11"),
("4", "11.44.11", "11.11.11", "11.11.11"),
];
let underline_color = Color::try_from(".".underline().to_string()).unwrap();
let mut table = Table::new(expenses);
table
.with(Style::blank())
.with(Colorization::rows([Color::BG_BLACK, Color::BG_WHITE]))
.with(Colorization::exact([underline_color], Rows::first()));
for row in (1..table.count_rows()).step_by(2) {
table.modify(Rows::single(row), BorderColor::new().left(Color::BG_WHITE));
}
for row in (2..table.count_rows()).step_by(2) {
table.modify(Rows::single(row), BorderColor::new().left(Color::BG_BLACK));
}
println!("{}", table);
}
And @k86td if you want to you can contribute some of the things like italic
, underline
etc into Color
.
So it could be used as Color::Black | Color::Underline | Color::Bold
.
It's a fairly simple trick. You can open a PR if you wish. See
Hey, thanks for your quick reply! It's exactly what I was looking for.
I agree with the extra complexity, I'm not familiar with exposing internal iterators to the outside, would it be like Table::new().rows_iter()
?
I would gladly try to help you with this. As for the colors, I was using an enum to support ANSI escape codes, not just colors. In my testing project I've made this little enum, maybe it would be something interesting to add inside Color
?
pub enum AsciiStyling<'a> {
Reset,
Bold,
Underline,
BackgroundColor8Bit(&'a str),
// ...
}
impl From<AsciiStyling<'_>> for String {
// ...
}
Let me know what you think, otherwise I'll add the constants.
I agree with the extra complexity,
I am thinking about adding Iterator like step()
function for modify
arguments.
Something like this.
What do you think.
The hardest question is how to call it step
or step_by
:thinking:
// instead of this
for row in (1..table.count_rows()).step_by(2) {
table.modify(Rows::single(row), BorderColor::new().left(Color::BG_WHITE));
}
// this
table.modify(Rows::new(1..).step(2), BorderColor::new().left(Color::BG_WHITE));
I'm not familiar with exposing internal iterators to the outside, would it be like Table::new().rows_iter() ?
There's a few methods to do that. I am not sure why you need it but something like
for row in table.get_records().iter_rows() {
for cell in row {
println!("{cell}")
}
}
If you need access to cells you could use Format
instead, which uses a function/closure.
table.modify(
Rows::new(1..),
Format::content(|text| text.on_red().to_string()),
);
I was using an enum
These constants are supposed to look like enum :sweat_smile:
That's how we approach it. I think that's better then original enum
in this case.
Actually implemented already it on master.
table.modify(Rows::new(1..).step_by(2), BorderColor::new().left(Color::BG_WHITE));
That looks very clean.
There's a few methods to do that. I am not sure why you need it but something like
I was asking how you thought of approaching this, not a request:)
These constants are supposed to look like enum 😅
Yeah, you want to use static everywhere to avoid dynamic allocation? It would be great to have better support for more colour, but since it's not that hard to create Color
it might not be useful here, but I'm still asking.
let color_white = Color::BG_8BIT::255;
let color_white = Color::8Bit::BG::255;
// or
let color_white = Color::BG_RGB(255, 255, 255);
Keep me posted, thanks for your very quick reply:)
Yeah, you want to use static everywhere to avoid dynamic allocation?
Exactly.
But more importantly is because of this it could be used in const
context.
While general enum
has some downsides, in particular cause of custom color creation.
It would be great to have better support for more colour, but since it's not that hard to create Color it might not be useful here, but I'm still asking.
No I think it's pretty valuable, as it reduces boilerplate code.
Your idea about RGB is actually very good, I never thought about it.
The only think I would probably make it a function?
Yes it could be const
.
let color_white = Color::rgb_bg(255, 255, 255);
So a simple method in Color
would probably do the trick, but having it const causes problems from what I've tested.
impl Color {
// ...
// tried also with `&'static str` type
const fn rgb_bg(r: u8, g: u8, b: u8) -> Self {
let color = StaticColor::new(&format!("\u{1b}[38;{};{};{}m", r, g, b), "\u{1b}[49m");
// or
// let color = StaticColor::new(formatcp!("\u{1b}[38;{};{};{}m", r, g, b), "\u{1b}[49m");
let inner = ColorInner::Static(color);
Self { inner }
}
// ...
}
I checked using generics parameters, I don't think it'll be possible either:
const fn rgb_bg<const R: u8, const G: u8, const B: u8>() -> Self {
// ...
}
I found const_format, but I don't think it'll help since the arguments aren't const. Would you need to wrap it around something else?
Does the output of rgb_bg
really needs to be constant?
So a simple method in Color would probably do the trick, but having it const causes problems from what I've tested.
Ahhhh yesss I did missed it. You're right.
Though your original comment about enum
would work in const
in case of RGB.
See there's downsides/upsides to some approaches :smile:
Does the output of rgb_bg really needs to be constant?
It shouldn't. I think it'll be all right to be generic.
So I've made the two functions that can create colors from rgb. I also added an example & some tests.
Hello there. I'm asking because I'm not sure if it's possible with this crate, and I'm still new to Rust. I'm trying to create alternating BorderColor to follow alternating Rows colour. The reason is, I want to create a colourized table with the header underlined. To avoid having a single line underlined going through the header, I'm setting a border of
' '
in the first row, the problem is when I try to colourize, borders are added on all rows which are not colourized using the current rowColorization
. I've tried setting BorderColor, but I was setting it globally for all rows except the first. The result is half the rows would look okay, but the rows with the alternate colours do not display correctly.Here's a sample of the code I'm using to display my table:
Is it possible? I've checked the examples and tried different combination and this is the closest to the actual result I'm looking for. I haven't touched really the iterators yet, maybe it's just about extending
Colorize
to acceptBorderColor
? I will update this issue if I make progress on this. Thanks!