diff options
author | 2024-07-17 22:04:11 +0200 | |
---|---|---|
committer | 2024-07-17 22:04:11 +0200 | |
commit | 910eb72a0620b34e5b3d7793bbd5ab7290e08dd6 (patch) | |
tree | 0a0940d56a9bc4147b7ef06fe9fb5099c761090a /examples/markdown | |
parent | ffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f (diff) | |
download | iced-910eb72a0620b34e5b3d7793bbd5ab7290e08dd6.tar.gz iced-910eb72a0620b34e5b3d7793bbd5ab7290e08dd6.tar.bz2 iced-910eb72a0620b34e5b3d7793bbd5ab7290e08dd6.zip |
Implement `rich_text` widget and `markdown` example
Diffstat (limited to 'examples/markdown')
-rw-r--r-- | examples/markdown/Cargo.toml | 12 | ||||
-rw-r--r-- | examples/markdown/src/main.rs | 172 |
2 files changed, 184 insertions, 0 deletions
diff --git a/examples/markdown/Cargo.toml b/examples/markdown/Cargo.toml new file mode 100644 index 00000000..f9bf4042 --- /dev/null +++ b/examples/markdown/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "markdown" +version = "0.1.0" +authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] +edition = "2021" +publish = false + +[dependencies] +iced.workspace = true +iced.features = ["debug"] + +pulldown-cmark = "0.11" diff --git a/examples/markdown/src/main.rs b/examples/markdown/src/main.rs new file mode 100644 index 00000000..43adaf72 --- /dev/null +++ b/examples/markdown/src/main.rs @@ -0,0 +1,172 @@ +use iced::font; +use iced::padding; +use iced::widget::{ + self, column, container, rich_text, row, span, text_editor, +}; +use iced::{Element, Fill, Font, Task, Theme}; + +pub fn main() -> iced::Result { + iced::application("Markdown - Iced", Markdown::update, Markdown::view) + .theme(Markdown::theme) + .run_with(Markdown::new) +} + +struct Markdown { + content: text_editor::Content, +} + +#[derive(Debug, Clone)] +enum Message { + Edit(text_editor::Action), +} + +impl Markdown { + fn new() -> (Self, Task<Message>) { + ( + Self { + content: text_editor::Content::with_text( + "# Markdown Editor\nType your Markdown here...", + ), + }, + widget::focus_next(), + ) + } + fn update(&mut self, message: Message) { + match message { + Message::Edit(action) => { + self.content.perform(action); + } + } + } + + fn view(&self) -> Element<Message> { + let editor = text_editor(&self.content) + .on_action(Message::Edit) + .height(Fill) + .padding(10) + .font(Font::MONOSPACE); + + let preview = { + let markdown = self.content.text(); + let parser = pulldown_cmark::Parser::new(&markdown); + + let mut strong = false; + let mut emphasis = false; + let mut heading = None; + let mut spans = Vec::new(); + + let items = parser.filter_map(|event| match event { + pulldown_cmark::Event::Start(tag) => match tag { + pulldown_cmark::Tag::Strong => { + strong = true; + None + } + pulldown_cmark::Tag::Emphasis => { + emphasis = true; + None + } + pulldown_cmark::Tag::Heading { level, .. } => { + heading = Some(level); + None + } + _ => None, + }, + pulldown_cmark::Event::End(tag) => match tag { + pulldown_cmark::TagEnd::Emphasis => { + emphasis = false; + None + } + pulldown_cmark::TagEnd::Strong => { + strong = false; + None + } + pulldown_cmark::TagEnd::Heading(_) => { + heading = None; + Some( + container(rich_text(spans.drain(..))) + .padding(padding::bottom(5)) + .into(), + ) + } + pulldown_cmark::TagEnd::Paragraph => Some( + container(rich_text(spans.drain(..))) + .padding(padding::bottom(15)) + .into(), + ), + pulldown_cmark::TagEnd::CodeBlock => Some( + container( + container( + rich_text(spans.drain(..)) + .font(Font::MONOSPACE), + ) + .width(Fill) + .padding(10) + .style(container::rounded_box), + ) + .padding(padding::bottom(15)) + .into(), + ), + _ => None, + }, + pulldown_cmark::Event::Text(text) => { + let span = span(text.into_string()); + + let span = match heading { + None => span, + Some(heading) => span.size(match heading { + pulldown_cmark::HeadingLevel::H1 => 32, + pulldown_cmark::HeadingLevel::H2 => 28, + pulldown_cmark::HeadingLevel::H3 => 24, + pulldown_cmark::HeadingLevel::H4 => 20, + pulldown_cmark::HeadingLevel::H5 => 16, + pulldown_cmark::HeadingLevel::H6 => 16, + }), + }; + + let span = if strong || emphasis { + span.font(Font { + weight: if strong { + font::Weight::Bold + } else { + font::Weight::Normal + }, + style: if emphasis { + font::Style::Italic + } else { + font::Style::Normal + }, + ..Font::default() + }) + } else { + span + }; + + spans.push(span); + + None + } + pulldown_cmark::Event::Code(code) => { + spans.push(span(code.into_string()).font(Font::MONOSPACE)); + None + } + pulldown_cmark::Event::SoftBreak => { + spans.push(span(" ")); + None + } + pulldown_cmark::Event::HardBreak => { + spans.push(span("\n")); + None + } + _ => None, + }); + + column(items).width(Fill) + }; + + row![editor, preview].spacing(10).padding(10).into() + } + + fn theme(&self) -> Theme { + Theme::TokyoNight + } +} |