Fix markdown monospace in headings

This commit is contained in:
2025-08-03 10:08:03 +02:00
parent 0acab0413c
commit 2fb9908329
6 changed files with 65 additions and 42 deletions

View File

@ -11,10 +11,11 @@ use crate::{
file_editor::{FileEditor, SaveStatus},
folder::Folder,
preferences::Preferences,
text_styles::{H1, H1_MONO, H2, H2_MONO, H3, H3_MONO, H4, H4_MONO, H5, H5_MONO, H6, H6_MONO},
util::{GuiSender, file_mtime, log_error},
};
use egui::{
Align, Button, Context, FontData, FontDefinitions, FontId, Image, Key, Modifiers,
Align, Button, Context, FontData, FontDefinitions, FontFamily, FontId, Image, Key, Modifiers,
PointerButton, RichText, ScrollArea, Theme, Widget, include_image,
};
use eyre::eyre;
@ -190,35 +191,35 @@ impl App {
.map(|(name, data)| (name.to_string(), Arc::new(FontData::from_static(data))))
.collect();
fonts.families.insert(
egui::FontFamily::Proportional,
vec!["IosevkaAile-Regular".into()],
);
fonts
.families
.insert(FontFamily::Proportional, vec!["IosevkaAile-Regular".into()]);
fonts
.families
.insert(egui::FontFamily::Monospace, vec!["Iosevka-Thin".into()]);
.insert(FontFamily::Monospace, vec!["Iosevka-Thin".into()]);
cc.egui_ctx.set_fonts(fonts);
// markdown font styles
for theme in [Theme::Dark, Theme::Light] {
cc.egui_ctx.style_mut_of(theme, |style| {
for (name, size) in [
("H1", 28.0),
("H2", 26.0),
("H3", 24.0),
("H4", 22.0),
("H5", 20.0),
("H6", 18.0),
for (name, size, family) in [
(H1, 28.0, FontFamily::Proportional),
(H2, 26.0, FontFamily::Proportional),
(H3, 24.0, FontFamily::Proportional),
(H4, 22.0, FontFamily::Proportional),
(H5, 20.0, FontFamily::Proportional),
(H6, 18.0, FontFamily::Proportional),
(H1_MONO, 28.0, FontFamily::Monospace),
(H2_MONO, 26.0, FontFamily::Monospace),
(H3_MONO, 24.0, FontFamily::Monospace),
(H4_MONO, 22.0, FontFamily::Monospace),
(H5_MONO, 20.0, FontFamily::Monospace),
(H6_MONO, 18.0, FontFamily::Monospace),
] {
style.text_styles.insert(
egui::TextStyle::Name(name.into()),
FontId {
size,
family: egui::FontFamily::Proportional,
},
);
let name = egui::TextStyle::Name(name.into());
style.text_styles.insert(name, FontId { size, family });
}
});
}

View File

@ -82,6 +82,8 @@ struct Ephemeral {
current_stroke: Vec<Pos2>,
/// The lines that have not been blitted to `texture` yet.
///
/// Each pair of [Pos2]s is the start and end of one line.
unblitted_lines: Vec<[Pos2; 2]>,
tessellator: Option<Tessellator>,
@ -425,7 +427,7 @@ impl Handwriting {
last_mesh_ctx,
..
} = &mut self.e;
// TODO: don't tessellate and rasterize on the GUI thread
// TODO: avoid tessellating and rasterizing on the GUI thread
*last_mesh_ctx = Some(mesh_context);
@ -444,10 +446,7 @@ impl Handwriting {
.iter()
.chain([&*current_stroke])
.filter(|stroke| stroke.len() >= 2)
.map(|stroke| {
//let points: Vec<Pos2> = stroke.iter().map(|&p| to_screen * p).collect();
egui::Shape::line(stroke.clone(), style.stroke)
})
.map(|stroke| egui::Shape::line(stroke.clone(), style.stroke))
.for_each(|shape| {
tessellator.tessellate_shape(shape, mesh);
});
@ -480,7 +479,6 @@ impl Handwriting {
ui.vertical_centered_justified(|ui| {
self.ui_control(None, ui, &mut response);
//ui.label("Paint with your mouse/touch!");
Frame::canvas(ui.style())
.corner_radius(20.0)
.stroke(Stroke::new(5.0, Color32::from_black_alpha(40)))

View File

@ -8,6 +8,7 @@ pub mod markdown;
pub mod preferences;
pub mod rasterizer;
pub mod text_editor;
pub mod text_styles;
pub mod util;
pub use app::App;

View File

@ -1,6 +1,9 @@
use egui::text::{CCursorRange, LayoutJob};
use crate::markdown::Heading;
use crate::{
markdown::Heading,
text_styles::{H1, H1_MONO, H2, H2_MONO, H3, H3_MONO, H4, H4_MONO, H5, H5_MONO, H6, H6_MONO},
};
use super::{Item, Style, parse};
@ -36,7 +39,6 @@ pub fn highlight_markdown(
_cursor: Option<CCursorRange>,
) -> LayoutJob {
let mut job = LayoutJob::default();
let code_style = Style {
code: true,
..Default::default()
@ -74,14 +76,23 @@ fn format_from_style(egui_style: &egui::Style, style: &Style) -> egui::text::Tex
};
let text_style = if let Some(heading) = style.heading {
match heading {
Heading::H1 => TextStyle::Name("H1".into()),
Heading::H2 => TextStyle::Name("H2".into()),
Heading::H3 => TextStyle::Name("H3".into()),
Heading::H4 => TextStyle::Name("H4".into()),
Heading::H5 => TextStyle::Name("H5".into()),
Heading::H6 => TextStyle::Name("H6".into()),
}
let text_style = match (heading, style.code) {
(Heading::H1, false) => H1,
(Heading::H2, false) => H2,
(Heading::H3, false) => H3,
(Heading::H4, false) => H4,
(Heading::H5, false) => H5,
(Heading::H6, false) => H6,
(Heading::H1, true) => H1_MONO,
(Heading::H2, true) => H2_MONO,
(Heading::H3, true) => H3_MONO,
(Heading::H4, true) => H4_MONO,
(Heading::H5, true) => H5_MONO,
(Heading::H6, true) => H6_MONO,
};
TextStyle::Name(text_style.into())
} else if style.code {
TextStyle::Monospace
} else if style.small | style.raised {

View File

@ -16,11 +16,6 @@ pub fn parse_tokens<'a>(mut tokens: &[Token<'a>]) -> Vec<Item<'a>> {
let mut style = Style::default();
let mono_style = Style {
code: true,
..Default::default()
};
iter::from_fn(move || {
if tokens.is_empty() {
return None;
@ -73,7 +68,10 @@ pub fn parse_tokens<'a>(mut tokens: &[Token<'a>]) -> Vec<Item<'a>> {
any_of([TokenKind::Mono, TokenKind::CodeBlock, TokenKind::Newline]),
);
return Some(Item::Text { span, style: mono_style});
let mut style = style;
style.code = true;
return Some(Item::Text { span, style });
}
// TODO: different heading strengths

14
src/text_styles.rs Normal file
View File

@ -0,0 +1,14 @@
//! Name of custom [egui::TextStyle]s
pub const H1: &str = "H1";
pub const H2: &str = "H2";
pub const H3: &str = "H3";
pub const H4: &str = "H4";
pub const H5: &str = "H5";
pub const H6: &str = "H6";
pub const H1_MONO: &str = "H1-mono";
pub const H2_MONO: &str = "H2-mono";
pub const H3_MONO: &str = "H3-mono";
pub const H4_MONO: &str = "H4-mono";
pub const H5_MONO: &str = "H5-mono";
pub const H6_MONO: &str = "H6-mono";