1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//! ANSI escape code rendering for the web
//!
//! # Yew
//!
//! ```
//! # use yew::html;
//! # use yew_ansi::AnsiStatic;
//! html! {
//! <AnsiStatic text="Hello \u{001b}[32mWorld\u{001b}[39;1m!" />
//! }
//! # ;
//! ```
//!
//! This will generate the following output (whitespace added for clarity):
//!
//! ```html
//! <pre style="font-family: monospace">
//! <span>Hello </span>
//! <span style="color:#00ff00;">World</span>
//! <span style="font-weight:bold;">!</span>
//! </pre>
//! ```
//!
//! Refer to [`AnsiRenderer`] and [`AnsiProps`] for more details.
//!
//! # Parsing
//!
//! If you want to parse text containing ANSI escape codes you can use [`get_sgr_segments`]
//! to iterate over text segments along with their [`SgrEffect`].
//!
//! If you need more control, use [`get_markers`] to iterate over the raw [`Escape`] codes in the text.
pub use cursor::CharCursor;
pub use graphic_rendition::*;
pub use sequences::*;
pub use style::*;
#[cfg(feature = "yew")]
pub use yew_component::*;
mod cursor;
mod graphic_rendition;
mod sequences;
mod style;
#[cfg(feature = "yew")]
mod yew_component;
/// Iterator over the SGR segments in a string slice.
///
/// Each item is a tuple containing the [`SgrEffect`] and the [`&str`][str] it applies to.
///
/// Returned by [`get_sgr_segments`].
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone, Debug)]
pub struct SgrSegmentIter<'a> {
markers: MarkerIter<'a>,
effect: SgrEffect,
}
impl<'a> SgrSegmentIter<'a> {
fn new(s: &'a str) -> Self {
Self {
markers: get_markers(s),
effect: SgrEffect::default(),
}
}
}
impl<'a> Iterator for SgrSegmentIter<'a> {
type Item = (SgrEffect, &'a str);
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.markers.next()? {
Marker::Text(text) => {
return Some((self.effect.clone(), text));
}
Marker::Sequence(Escape::Csi(Csi::Sgr(sgrs))) => {
self.effect.apply_sgrs(sgrs);
}
}
}
}
}
/// Create an iterator which iterates over SGR segments in a string slice.
/// Each item consists of a [`SgrEffect`] and the corresponding text slice it applies to.
///
/// ```
/// # use yew_ansi::*;
/// let mut segments = yew_ansi::get_sgr_segments("Hello \u{001b}[32mWorld\u{001b}[39;1m!");
/// assert_eq!(segments.next(), Some((SgrEffect::default(), "Hello ")));
/// assert_eq!(
/// segments.next(),
/// Some((
/// SgrEffect {
/// fg: ColorEffect::Name(ColorName::Green),
/// ..Default::default()
/// },
/// "World"
/// ))
/// );
/// assert_eq!(
/// segments.next(),
/// Some((
/// SgrEffect {
/// bold: true,
/// ..Default::default()
/// },
/// "!"
/// ))
/// );
/// ```
pub fn get_sgr_segments(s: &str) -> SgrSegmentIter {
SgrSegmentIter::new(s)
}