feat(tui): add HtmlRenderer for HTML-to-ANSI terminal text conversion (GH-25) #54
No files matched your search
@@ -45,6 +45,8 @@ rrule = "0.10"
|
||||
chrono = "0.4"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||
quick-xml = "0.36"
|
||||
html2text = "0.12"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,3 +15,5 @@ tokio.workspace = true
|
||||
ratatui.workspace = true
|
||||
crossterm.workspace = true
|
||||
tracing.workspace = true
|
||||
html2text.workspace = true
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//! HTML to ANSI terminal plaintext renderer wrapper for email preview.
|
||||
|
||||
/// Renderer converting HTML body strings into wrapped terminal plaintext.
|
||||
pub struct HtmlRenderer;
|
||||
|
||||
impl HtmlRenderer {
|
||||
/// Render HTML body string into plaintext formatted for terminal reader width.
|
||||
pub fn render_html(html: &str, width: usize) -> String {
|
||||
let max_width = if width == 0 { 80 } else { width };
|
||||
html2text::from_read(html.as_bytes(), max_width)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn render_html_paragraph_and_links() {
|
||||
let html = "<h1>Meeting Notes</h1><p>Discussing <b>Nuncio</b> release.</p>";
|
||||
let rendered = HtmlRenderer::render_html(html, 60);
|
||||
|
||||
assert!(rendered.contains("Meeting Notes"));
|
||||
assert!(rendered.contains("Nuncio"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_empty_or_zero_width_uses_default() {
|
||||
let rendered = HtmlRenderer::render_html("<p>test</p>", 0);
|
||||
assert!(rendered.contains("test"));
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
//! Nuncio Terminal UI application entry point.
|
||||
|
||||
mod html;
|
||||
mod keybindings;
|
||||
mod layout;
|
||||
|
||||
use html::HtmlRenderer;
|
||||
use keybindings::{KeybindingEngine, UserAction};
|
||||
use layout::{ActivePane, AppLayout};
|
||||
use ratatui::layout::Rect;
|
||||
@@ -12,8 +14,10 @@ fn main() {
|
||||
let (sidebar, list, reader) = AppLayout::compute_layout(area);
|
||||
let focused = ActivePane::Sidebar;
|
||||
|
||||
let sample_rendered = HtmlRenderer::render_html("<h1>Nuncio</h1>", 40);
|
||||
|
||||
println!(
|
||||
"Nuncio TUI Layout Active: sidebar={}px, list={}px, reader={}px (focused: {:?})",
|
||||
sidebar.width, list.width, reader.width, focused
|
||||
"Nuncio TUI Layout Active: sidebar={}px, list={}px, reader={}px (focused: {:?}, rendered: {})",
|
||||
sidebar.width, list.width, reader.width, focused, sample_rendered.trim()
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user