diff --git a/README.md b/README.md index 9d7ce5a..e1b0417 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,28 @@ let line = line!["hello", format!("{name}")]; let line = line!["bye"; 2]; ``` +## Text + +The `text!` macro creates a `Text` that contains a sequence of lines. It is similar to the `vec!` macro. + +```rust +use ratatui::prelude::*; +use ratatui_macros::{span, line, text}; + +let name = "world!"; +let text = text!["hello", format!("{name}")]; +let text = text!["bye"; 2]; +``` + +It is even possible to use `span!` and `line!` in the `text!` macro: + +```rust +use ratatui::prelude::*; +use ratatui_macros::{span, line, text}; +let name = "Bye!!!"; +let text = text![line!["hello", "world".bold()], span!(Modifier::BOLD; "{name}")]; +``` + ## Contributing Contributions to `ratatui-macros` are welcome! Whether it's submitting a bug report, a feature diff --git a/src/layout.rs b/src/layout.rs index a7df25c..14aa4d4 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -17,22 +17,22 @@ /// ``` #[macro_export] macro_rules! constraint { - ( == $token:tt % ) => { + (== $token:tt %) => { ratatui::layout::Constraint::Percentage($token) }; - ( >= $expr:expr ) => { + (>= $expr:expr) => { ratatui::layout::Constraint::Min($expr) }; - ( <= $expr:expr ) => { + (<= $expr:expr) => { ratatui::layout::Constraint::Max($expr) }; - ( == $num:tt / $denom:tt ) => { + (== $num:tt / $denom:tt) => { ratatui::layout::Constraint::Ratio($num as u32, $denom as u32) }; - ( == $expr:expr ) => { + (== $expr:expr) => { ratatui::layout::Constraint::Length($expr) }; - ( =* $expr:expr ) => { + (=* $expr:expr) => { ratatui::layout::Constraint::Fill($expr) }; } diff --git a/src/lib.rs b/src/lib.rs index 7d5cad6..e440161 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,4 @@ mod layout; mod line; mod span; +mod text; diff --git a/src/text.rs b/src/text.rs new file mode 100644 index 0000000..cd30efe --- /dev/null +++ b/src/text.rs @@ -0,0 +1,73 @@ +/// A macro for creating a [`Text`] using vec! syntax. +/// +/// `text!` is similar to the [`vec!`] macro, but it returns a [`Text`] instead of a `Vec`. +/// +/// # Examples +/// +/// * Create a [`Text`] containing a vector of [`Line`]s: +/// +/// ```rust +/// # use ratatui::prelude::*; +/// use ratatui_macros::text; +/// +/// let text = text!["hello", "world"]; +/// let text = text!["hello".red(), "world".red().bold()]; +/// ``` +/// +/// * Create a [`text`] from a given [`Line`] repeated some amount of times: +/// +/// ```rust +/// # use ratatui::prelude::*; +/// use ratatui_macros::text; +/// +/// let text = text!["hello"; 2]; +/// ``` +/// +/// * Use [`line!`] or [`span!`] macro inside [`text!`] macro. +/// +/// ```rust +/// # use ratatui::prelude::*; +/// use ratatui_macros::{line, text, span}; +/// +/// let text = text![line!["hello", "world"], span!(Modifier::BOLD; "goodbye {}", "world")]; +/// ``` +/// +/// [`Text`]: crate::text::Text +/// [`Line`]: crate::text::Line +/// [`Span`]: crate::text::Span +#[macro_export] +macro_rules! text { + () => { + ratatui::text::Text::default() + }; + ($line:expr; $n:expr) => { + ratatui::text::Text::from(vec![$line.into(); $n]) + }; + ($($line:expr),+ $(,)?) => {{ + ratatui::text::Text::from(vec![ + $( + $line.into(), + )+ + ]) + }}; +} + +#[cfg(test)] +mod tests { + use ratatui::prelude::*; + + #[test] + fn text() { + // literal + let text = text!["hello", "world"]; + assert_eq!(text, Text::from(vec!["hello".into(), "world".into()])); + + // explicit use of span and line + let text = text![crate::line!("hello"), crate::span!["world"]]; + assert_eq!(text, Text::from(vec!["hello".into(), "world".into()])); + + // vec count syntax + let text = text!["hello"; 2]; + assert_eq!(text, Text::from(vec!["hello".into(), "hello".into()])); + } +} diff --git a/tests/ui/fails.stderr b/tests/ui/fails.stderr index f982aa3..a7db09f 100644 --- a/tests/ui/fails.stderr +++ b/tests/ui/fails.stderr @@ -19,8 +19,8 @@ error: unexpected end of macro invocation note: while trying to match `==` --> src/layout.rs | - | ( == $token:tt % ) => { - | ^^ + | (== $token:tt %) => { + | ^^ = note: this error originates in the macro `$crate::constraints` which comes from the expansion of the macro `constraints` (in Nightly builds, run with -Z macro-backtrace for more info) error: no rules expected the token `;` @@ -32,8 +32,8 @@ error: no rules expected the token `;` note: while trying to match `%` --> src/layout.rs | - | ( == $token:tt % ) => { - | ^ + | (== $token:tt %) => { + | ^ error[E0527]: pattern requires 2 elements but array has 3 --> tests/ui/fails.rs:8:9