Documents: headings step up from the body, all bold
CI / platforms (ubuntu-24.04) (push) Waiting to run
CI / platforms (windows-latest) (push) Failing after 10s
CI / site (push) Successful in 23s
CI / crate (push) Failing after 10m33s

Sizes follow Typora's steps over the body (2.25, 1.75, 1.5, 1.25, 1, 1)
so levels 3 and 4 stand out; level 6 is muted; line height fits the size.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-15 12:25:50 -04:00
1 parent 9fb607beb4
commit 5954132e76
2 files changed
+51 -15

No files matched your search

+24 -15
View File
@@ -109,6 +109,8 @@ struct Draw<'a> {
sections: &'a Option<Entity<Sections>>,
headings: std::cell::Cell<usize>,
code: &'a Option<DrawCode>,
/// The body's size; headings step up from it.
body: TextSize,
/// Text size against the theme's.
scale: f32,
/// Lists open around the node drawn.
@@ -227,24 +229,29 @@ impl Draw<'_> {
.child(self.inline(inline, cx))
.into_any_element(),
Node::Heading(level, inline) => {
let size = match level {
1 => TextSize::Xxl,
2 => TextSize::Xl,
3 => TextSize::Lg,
_ => TextSize::Md,
// Typora's steps over the body; every level bold.
let step = match level {
1 => 2.25,
2 => 1.75,
3 => 1.5,
4 => 1.25,
_ => 1.0,
};
let heading = div()
.pt_2()
.text_size(theme.text_size(size) * self.scale)
.font_weight(if *level <= 2 {
FontWeight::SEMIBOLD
} else {
FontWeight::MEDIUM
})
.text_color(colors.fg)
.child(self.inline(inline, cx));
let size = theme.text_size(self.body) * step * self.scale;
let ordinal = self.headings.get();
self.headings.set(ordinal + 1);
let heading = div()
.debug_selector(move || format!("markdown-heading-{ordinal}"))
.pt_2()
.text_size(size)
.line_height(size * 1.3)
.font_weight(FontWeight::BOLD)
.text_color(if *level == 6 {
colors.fg_muted
} else {
colors.fg
})
.child(self.inline(inline, cx));
match self.sections {
Some(sections) => Anchor::new(sections, anchor(ordinal))
.child(heading)
@@ -392,6 +399,7 @@ pub(crate) fn draw_nodes(
sections: &None,
headings: std::cell::Cell::new(0),
code: &None,
body: TextSize::Base,
scale,
lists: std::cell::Cell::new(0),
table: std::cell::Cell::new(false),
@@ -417,6 +425,7 @@ impl RenderOnce for MarkdownRenderer {
sections: &self.sections,
headings: std::cell::Cell::new(0),
code: &self.code,
body: self.size,
scale: 1.0,
lists: std::cell::Cell::new(0),
table: std::cell::Cell::new(false),
+27
View File
@@ -51,3 +51,30 @@ fn alerts_lists_of_headings_and_front_matter_draw(cx: &mut TestAppContext) {
);
assert!(two.top() > one.top(), "{one:?} {two:?}");
}
#[gpui::test]
fn each_heading_level_stands_above_the_next(cx: &mut TestAppContext) {
cx.update(Theme::init);
let source = "# a
## a
### a
#### a
##### a
";
let (_, cx) = cx.add_window_view(|_, _| Page(source));
cx.run_until_parked();
let high = |ordinal: usize| {
let selector = Box::leak(format!("markdown-heading-{ordinal}").into_boxed_str());
cx.debug_bounds(selector).expect("drawn").size.height
};
let heights: Vec<_> = (0..5).map(high).collect();
// Level 5 is the body's size; each above it is taller.
assert!(
heights.windows(2).all(|pair| pair[0] > pair[1]),
"{heights:?}"
);
}