ui: Use parsed markdown contents to determine sizing.

pull/8/head
Blaž Hrastnik 3 years ago
parent f9b9bc04cc
commit 80eca5c32f

@ -21,10 +21,7 @@ impl Markdown {
Self { contents } Self { contents }
} }
} }
impl Component for Markdown { fn parse(contents: &str) -> tui::text::Text {
fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
use tui::widgets::{Paragraph, Widget, Wrap};
use pulldown_cmark::{CodeBlockKind, CowStr, Event, Options, Parser, Tag}; use pulldown_cmark::{CodeBlockKind, CowStr, Event, Options, Parser, Tag};
use tui::text::{Span, Spans, Text}; use tui::text::{Span, Spans, Text};
@ -33,7 +30,7 @@ impl Component for Markdown {
let mut options = Options::empty(); let mut options = Options::empty();
options.insert(Options::ENABLE_STRIKETHROUGH); options.insert(Options::ENABLE_STRIKETHROUGH);
let parser = Parser::new_ext(&self.contents, options); let parser = Parser::new_ext(contents, options);
// TODO: if possible, render links as terminal hyperlinks: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda // TODO: if possible, render links as terminal hyperlinks: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
let mut tags = Vec::new(); let mut tags = Vec::new();
@ -43,7 +40,7 @@ impl Component for Markdown {
fn to_span(text: pulldown_cmark::CowStr) -> Span { fn to_span(text: pulldown_cmark::CowStr) -> Span {
use std::ops::Deref; use std::ops::Deref;
Span::raw::<std::borrow::Cow<_>>(match text { Span::raw::<std::borrow::Cow<_>>(match text {
CowStr::Borrowed(s) => s.into(), CowStr::Borrowed(s) => s.to_string().into(), // could retain borrow
CowStr::Boxed(s) => s.to_string().into(), CowStr::Boxed(s) => s.to_string().into(),
CowStr::Inlined(s) => s.deref().to_owned().into(), CowStr::Inlined(s) => s.deref().to_owned().into(),
}) })
@ -59,12 +56,12 @@ impl Component for Markdown {
Event::End(tag) => { Event::End(tag) => {
tags.pop(); tags.pop();
match tag { match tag {
Tag::Heading(_) Tag::Heading(_) | Tag::Paragraph | Tag::CodeBlock(CodeBlockKind::Fenced(_)) => {
| Tag::Paragraph
| Tag::CodeBlock(CodeBlockKind::Fenced(_)) => {
// whenever code block or paragraph closes, new line // whenever code block or paragraph closes, new line
let spans = std::mem::replace(&mut spans, Vec::new()); let spans = std::mem::replace(&mut spans, Vec::new());
if !spans.is_empty() {
lines.push(Spans::from(spans)); lines.push(Spans::from(spans));
}
lines.push(Spans::default()); lines.push(Spans::default());
} }
_ => (), _ => (),
@ -110,9 +107,15 @@ impl Component for Markdown {
lines.push(Spans::from(spans)); lines.push(Spans::from(spans));
} }
let contents = Text::from(lines); Text::from(lines)
}
impl Component for Markdown {
fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
use tui::widgets::{Paragraph, Widget, Wrap};
let text = parse(&self.contents);
let par = Paragraph::new(contents) let par = Paragraph::new(text)
.wrap(Wrap { trim: false }) .wrap(Wrap { trim: false })
.scroll((cx.scroll.unwrap_or_default() as u16, 0)); .scroll((cx.scroll.unwrap_or_default() as u16, 0));
@ -121,7 +124,7 @@ impl Component for Markdown {
} }
fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> { fn required_size(&mut self, viewport: (u16, u16)) -> Option<(u16, u16)> {
let contents = tui::text::Text::from(self.contents.clone()); let contents = parse(&self.contents);
let padding = 2; let padding = 2;
let width = std::cmp::min(contents.width() as u16 + padding, viewport.0); let width = std::cmp::min(contents.width() as u16 + padding, viewport.0);
let height = std::cmp::min(contents.height() as u16 + padding, viewport.1); let height = std::cmp::min(contents.height() as u16 + padding, viewport.1);

Loading…
Cancel
Save