Skip to content

Commit

Permalink
Add html callback function
Browse files Browse the repository at this point in the history
Closes #73
  • Loading branch information
lampsitter committed Jan 28, 2025
1 parent 73ac543 commit 081af9f
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

- Callback function `render_math_fn` for custom math rendering
- Callback function `render_html_fn` for custom html rendering

### Fixed

Expand Down
81 changes: 81 additions & 0 deletions egui_commonmark/examples/html.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! Add `light` or `dark` to the end of the command to specify theme. Default
//! is light. `cargo r --example html -- dark`
use eframe::egui;
use egui_commonmark::*;
use std::cell::RefCell;
use std::rc::Rc;

struct App {
cache: CommonMarkCache,
/// To avoid id collisions
counter: Rc<RefCell<usize>>,
}

impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
*self.counter.as_ref().borrow_mut() = 0;

egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::vertical().show(ui, |ui| {
CommonMarkViewer::new()
.render_html_fn({
let counter = Rc::clone(&self.counter);
Some(&move |ui, html| {
// For simplicity lets just hide the content regardless of what kind of
// node it is.
ui.collapsing(
format!("Collapsed {}", counter.as_ref().borrow()),
|ui| {
ui.label(html);
},
);

*counter.as_ref().borrow_mut() += 1;
})
})
.show(ui, &mut self.cache, EXAMPLE_TEXT);
});
});
}
}

fn main() -> eframe::Result {
let mut args = std::env::args();
args.next();

eframe::run_native(
"Markdown viewer",
eframe::NativeOptions::default(),
Box::new(move |cc| {
if let Some(theme) = args.next() {
if theme == "light" {
cc.egui_ctx.set_theme(egui::Theme::Light);
} else if theme == "dark" {
cc.egui_ctx.set_theme(egui::Theme::Dark);
}
}

cc.egui_ctx.style_mut(|style| {
// Show the url of a hyperlink on hover
style.url_in_tooltip = true;
});

Ok(Box::new(App {
cache: CommonMarkCache::default(),
counter: Rc::new(RefCell::new(0)),
}))
}),
)
}

const EXAMPLE_TEXT: &str = r#"
# Customized rendering using html
<p>
some text
</p>
<p>
some text 2
</p>
"#;
11 changes: 9 additions & 2 deletions egui_commonmark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,15 @@ impl<'f> CommonMarkViewer<'f> {
/// );
/// }));
/// ```
pub fn render_math_fn(mut self, math_fn: Option<&'f RenderMathFn>) -> Self {
self.options.math_fn = math_fn;
pub fn render_math_fn(mut self, func: Option<&'f RenderMathFn>) -> Self {
self.options.math_fn = func;
self
}

/// Allows custom handling of html. Enabling this will disable plain text rendering
/// of html blocks. Nodes are included in the provided text
pub fn render_html_fn(mut self, func: Option<&'f RenderHtmlFn>) -> Self {
self.options.html_fn = func;
self
}

Expand Down
21 changes: 18 additions & 3 deletions egui_commonmark/src/parsers/pulldown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ pub struct CommonMarkViewerInternal {
image: Option<Image>,
line: Newline,
code_block: Option<CodeBlock>,

/// Only populated if the html_fn option has been set
html_block: String,
is_list_item: bool,
def_list: DefinitionList,
is_table: bool,
Expand All @@ -96,6 +99,7 @@ impl CommonMarkViewerInternal {
is_list_item: false,
def_list: Default::default(),
code_block: None,
html_block: String::new(),
is_table: false,
is_blockquote: false,
checkbox_events: Vec::new(),
Expand Down Expand Up @@ -520,8 +524,13 @@ impl CommonMarkViewerInternal {
pulldown_cmark::Event::InlineHtml(text) => {
self.event_text(text, ui);
}
pulldown_cmark::Event::Html(node) => {
self.event_text(node, ui);

pulldown_cmark::Event::Html(text) => {
if options.html_fn.is_some() {
self.html_block.push_str(&text);
} else {
self.event_text(text, ui);
}
}
pulldown_cmark::Event::FootnoteReference(footnote) => {
footnote_start(ui, &footnote);
Expand Down Expand Up @@ -755,7 +764,13 @@ impl CommonMarkViewerInternal {
image.end(ui, options);
}
}
pulldown_cmark::TagEnd::HtmlBlock => {}
pulldown_cmark::TagEnd::HtmlBlock => {
if let Some(html_fn) = options.html_fn {
html_fn(ui, &self.html_block);
self.html_block.clear();
}
}

pulldown_cmark::TagEnd::MetadataBlock(_) => {}

pulldown_cmark::TagEnd::DefinitionList => self.line.try_insert_end(ui),
Expand Down
2 changes: 2 additions & 0 deletions egui_commonmark_backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ pub use misc::CommonMarkCache;

/// Takes [`egui::Ui`], the math text to be rendered and whether it is inline
pub type RenderMathFn = dyn Fn(&mut egui::Ui, &str, bool);
/// Takes [`egui::Ui`] and the html text to be rendered/used
pub type RenderHtmlFn = dyn Fn(&mut egui::Ui, &str);
2 changes: 2 additions & 0 deletions egui_commonmark_backend/src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct CommonMarkOptions<'f> {
/// Whether to present a mutable ui for things like checkboxes
pub mutable: bool,
pub math_fn: Option<&'f crate::RenderMathFn>,
pub html_fn: Option<&'f crate::RenderHtmlFn>,
}

impl<'f> std::fmt::Debug for CommonMarkOptions<'f> {
Expand Down Expand Up @@ -74,6 +75,7 @@ impl Default for CommonMarkOptions<'_> {
alerts: AlertBundle::gfm(),
mutable: false,
math_fn: None,
html_fn: None,
}
}
}
Expand Down

0 comments on commit 081af9f

Please sign in to comment.