#[macro_export]
macro_rules! md {
($($arg:tt)*) => {{
let text = format!($($arg)*);
$crate::util::md_render::render_md(&text);
}};
}
#[macro_export]
macro_rules! md_inline {
($($arg:tt)*) => {{
let text = format!($($arg)*);
termimad::print_inline(&text);
}};
}
fn print_lines_to_terminal(lines: &[ratatui::text::Line]) {
use crossterm::ExecutableCommand;
use crossterm::style::{Attribute, ContentStyle, Print, ResetColor, SetStyle};
use ratatui::style::Modifier;
use std::io::{Write, stdout};
let mut out = stdout();
for line in lines {
for span in &line.spans {
let style = span.style;
let mut ct_style = ContentStyle::new();
if let Some(fg) = style.fg {
ct_style.foreground_color = Some(map_color(fg));
}
if let Some(bg) = style.bg {
ct_style.background_color = Some(map_color(bg));
}
let mods = style.add_modifier;
if mods.contains(Modifier::BOLD) {
ct_style.attributes.set(Attribute::Bold);
}
if mods.contains(Modifier::ITALIC) {
ct_style.attributes.set(Attribute::Italic);
}
if mods.contains(Modifier::UNDERLINED) {
ct_style.attributes.set(Attribute::Underlined);
}
if mods.contains(Modifier::CROSSED_OUT) {
ct_style.attributes.set(Attribute::CrossedOut);
}
if mods.contains(Modifier::DIM) {
ct_style.attributes.set(Attribute::Dim);
}
let _ = out.execute(SetStyle(ct_style));
let _ = out.execute(Print(&span.content));
let _ = out.execute(ResetColor);
}
let _ = writeln!(out);
}
let _ = out.flush();
}
fn map_color(color: ratatui::style::Color) -> crossterm::style::Color {
use crossterm::style::Color as CtColor;
use ratatui::style::Color as RColor;
match color {
RColor::Rgb(r, g, b) => CtColor::Rgb { r, g, b },
RColor::Indexed(i) => CtColor::AnsiValue(i),
RColor::Black => CtColor::Black,
RColor::Red => CtColor::DarkRed,
RColor::Green => CtColor::DarkGreen,
RColor::Yellow => CtColor::DarkYellow,
RColor::Blue => CtColor::DarkBlue,
RColor::Magenta => CtColor::DarkMagenta,
RColor::Cyan => CtColor::DarkCyan,
RColor::Gray => CtColor::Grey,
RColor::DarkGray => CtColor::DarkGrey,
RColor::LightRed => CtColor::Red,
RColor::LightGreen => CtColor::Green,
RColor::LightYellow => CtColor::Yellow,
RColor::LightBlue => CtColor::Blue,
RColor::LightMagenta => CtColor::Magenta,
RColor::LightCyan => CtColor::Cyan,
RColor::White => CtColor::White,
_ => CtColor::Reset,
}
}
pub fn render_md(text: &str) {
use crate::command::chat::markdown::markdown_to_lines;
use crate::command::chat::theme::Theme;
let width = crossterm::terminal::size()
.map(|(w, _)| w as usize)
.unwrap_or(80);
let theme = Theme::terminal();
let lines = markdown_to_lines(text, width, &theme);
print_lines_to_terminal(&lines);
}