Skip to content

Commit

Permalink
Update math to latest main
Browse files Browse the repository at this point in the history
Code manually copied from #45 as that was the easiest way to get it up
to date.

Co-Authored-By: zeozeozeo <[email protected]>
  • Loading branch information
lampsitter and zeozeozeo committed Jan 13, 2025
1 parent 9f2418f commit fef0f6d
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 11 deletions.
36 changes: 36 additions & 0 deletions egui_commonmark/examples/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
//! Shows a simple way to use the crate to implement a book like view.
use eframe::egui;
use egui::ImageSource;
use egui_commonmark::*;
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};

struct Page {
name: String,
Expand All @@ -18,6 +20,19 @@ struct App {
cache: CommonMarkCache,
curr_tab: Option<usize>,
pages: Vec<Page>,
math_to_svg: Rc<RefCell<HashMap<String, Arc<[u8]>>>>,
}

fn render_math(math: &str, inline: bool) -> Arc<[u8]> {
println!("rendering math: {math}");
// TODO
if inline {
// mathjax_svg::convert_to_svg_inline(math).unwrap()
} else {
// mathjax_svg::convert_to_svg(math).unwrap()
}
.into_bytes()
.into()
}

impl App {
Expand Down Expand Up @@ -47,12 +62,28 @@ impl App {
fn content_panel(&mut self, ui: &mut egui::Ui) {
egui::ScrollArea::vertical().show(ui, |ui| {
// Add a frame with margin to prevent the content from hugging the sidepanel
let math_to_svg = self.math_to_svg.clone();
egui::Frame::none()
.inner_margin(egui::Margin::symmetric(5.0, 0.0))
.show(ui, |ui| {
CommonMarkViewer::new()
.default_width(Some(200))
.max_image_width(Some(512))
.render_math_fn(Some(&move |ui, math, inline| {
let mut map = math_to_svg.borrow_mut();
let svg = map
.entry(math.to_string())
.or_insert_with(|| render_math(math, inline));

let uri = format!("{}.svg", egui::Id::from(math.to_string()).value());
ui.add(
egui::Image::new(ImageSource::Bytes {
uri: uri.into(),
bytes: egui::load::Bytes::Shared(svg.clone()),
})
.fit_to_original_size(1.0),
);
}))
.show(
ui,
&mut self.cache,
Expand Down Expand Up @@ -128,7 +159,12 @@ fn main() -> eframe::Result {
name: "Embedded Image".to_owned(),
content: include_str!("markdown/embedded_image.md").to_owned(),
},
Page {
name: "Math".to_owned(),
content: include_str!("markdown/math.md").to_owned(),
},
],
math_to_svg: Rc::new(RefCell::new(HashMap::new())),
}))
}),
)
Expand Down
57 changes: 57 additions & 0 deletions egui_commonmark/examples/markdown/math.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$

- Block equations:

$$ \frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} $$

- Stokes' theorem:

$$ \begin{equation}
\int_{\partial\Omega} \omega = \int_{\Omega} \mathrm{d}\omega \,.
\label{eq:stokes}
\end{equation} $$

- Maxwell's equations:

$$
\begin{align}
\nabla \cdot \vec{E} & = \rho \nonumber \\
\nabla \cdot \vec{B} & = 0 \nonumber \\
\nabla \times \vec{E} & = - \frac{\partial \vec{B}}{\partial t} \label{eq:maxwell} \\
\nabla \times \vec{B} & = \vec{j} + \frac{\partial \vec{E}}{\partial t} \nonumber \,.
\end{align}
$$

- L'Hôpital's rule

$$
\begin{align}
\lim_{x\to 0}{\frac{e^x-1}{2x}}
\overset{\left[\frac{0}{0}\right]}{\underset{\mathrm{H}}{=}}
\lim_{x\to 0}{\frac{e^x}{2}}={\frac{1}{2}}
\end{align}
$$

- More stuff

$$
\begin{align}
z = \overbrace{
\underbrace{x}_\text{real} + i
\underbrace{y}_\text{imaginary}
}^\text{complex number}
\end{align}
$$

- Multiline subscripts: $$
\begin{align}
\prod_{\substack{
1\le i \le n \\
1\le j \le m}}
M_{i,j}
\end{align}
$$
---
## Edge cases
Cheese is $10.40 + $0.20 tax
16 changes: 12 additions & 4 deletions egui_commonmark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ mod parsers;

pub use egui_commonmark_backend::alerts::{Alert, AlertBundle};
pub use egui_commonmark_backend::misc::CommonMarkCache;
pub use egui_commonmark_backend::RenderMathFn;

#[cfg(feature = "macros")]
pub use egui_commonmark_macros::*;
Expand All @@ -89,16 +90,23 @@ pub use egui_commonmark_backend;

use egui_commonmark_backend::*;

#[derive(Debug, Default)]
pub struct CommonMarkViewer {
options: CommonMarkOptions,
// FIXME: Manual Debug impl
// #[derive(Debug, Default)]
#[derive(Default)]
pub struct CommonMarkViewer<'a> {
options: CommonMarkOptions<'a>,
}

impl CommonMarkViewer {
impl<'a> CommonMarkViewer<'a> {
pub fn new() -> Self {
Self::default()
}

pub fn render_math_fn(mut self, math_fn: Option<&'a RenderMathFn>) -> Self {
self.options.math_fn = math_fn;
self
}

/// The amount of spaces a bullet point is indented. By default this is 4
/// spaces.
pub fn indentation_spaces(mut self, spaces: usize) -> Self {
Expand Down
14 changes: 11 additions & 3 deletions egui_commonmark/src/parsers/pulldown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl CommonMarkViewerInternal {

impl CommonMarkViewerInternal {
/// Be aware that this acquires egui::Context internally.
/// If Id is provided split then split points will be populated
/// If split Id is provided then split points will be populated
pub(crate) fn show(
&mut self,
ui: &mut egui::Ui,
Expand Down Expand Up @@ -533,8 +533,16 @@ impl CommonMarkViewerInternal {
ui.add(ImmutableCheckbox::without_text(&mut checkbox));
}
}

pulldown_cmark::Event::InlineMath(_) | pulldown_cmark::Event::DisplayMath(_) => {}
pulldown_cmark::Event::InlineMath(tex) => {
if let Some(math_fn) = options.math_fn {
math_fn(ui, &tex, true);
}
}
pulldown_cmark::Event::DisplayMath(tex) => {
if let Some(math_fn) = options.math_fn {
math_fn(ui, &tex, false);
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions egui_commonmark_backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ syntect = { version = "5.0.0", optional = true, default-features = false, featur
[features]
better_syntax_highlighting = ["dep:syntect"]
embedded_image = ["dep:data-url"]

math = ["egui_extras/svg"]
3 changes: 3 additions & 0 deletions egui_commonmark_backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ pub use {

// The only struct that is allowed to use directly. (If one does not need egui_commonmark)
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);
11 changes: 7 additions & 4 deletions egui_commonmark_backend/src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ const DEFAULT_THEME_LIGHT: &str = "base16-ocean.light";
#[cfg(feature = "better_syntax_highlighting")]
const DEFAULT_THEME_DARK: &str = "base16-ocean.dark";

#[derive(Debug)]
pub struct CommonMarkOptions {
// FIXME: Debug
// #[derive(Debug)]
pub struct CommonMarkOptions<'f> {
pub indentation_spaces: usize,
pub max_image_width: Option<usize>,
pub show_alt_text_on_hover: bool,
Expand All @@ -32,9 +33,10 @@ pub struct CommonMarkOptions {
pub alerts: AlertBundle,
/// Whether to present a mutable ui for things like checkboxes
pub mutable: bool,
pub math_fn: Option<&'f crate::RenderMathFn>,
}

impl Default for CommonMarkOptions {
impl Default for CommonMarkOptions<'_> {
fn default() -> Self {
Self {
indentation_spaces: 4,
Expand All @@ -49,11 +51,12 @@ impl Default for CommonMarkOptions {
default_implicit_uri_scheme: "file://".to_owned(),
alerts: AlertBundle::gfm(),
mutable: false,
math_fn: None,
}
}
}

impl CommonMarkOptions {
impl CommonMarkOptions<'_> {
#[cfg(feature = "better_syntax_highlighting")]
pub fn curr_theme(&self, ui: &Ui) -> &str {
if ui.style().visuals.dark_mode {
Expand Down
15 changes: 15 additions & 0 deletions egui_commonmark_backend/src/pulldown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@ pub fn parse_alerts<'a>(
}

/// Supported pulldown_cmark options
#[inline]
#[cfg(feature = "math")]
pub fn parser_options() -> Options {
Options::ENABLE_TABLES
| Options::ENABLE_TASKLISTS
| Options::ENABLE_STRIKETHROUGH
| Options::ENABLE_FOOTNOTES
| Options::ENABLE_DEFINITION_LIST
| Options::ENABLE_MATH
}

/// Supported pulldown_cmark options
#[inline]
#[cfg(not(feature = "math"))]
pub fn parser_options() -> Options {
Options::ENABLE_TABLES
| Options::ENABLE_TASKLISTS
Expand Down

0 comments on commit fef0f6d

Please sign in to comment.