Browse / github.com/storytold/wordcraft / patch
Heading 1–3 defaults: distinct hierarchy using Cambria and Aptos Display
Heading 1–3 defaults: distinct hierarchy using Cambria and Aptos Display ## What Updates the default heading styles (Heading 1–3) in the built-in stylesheet with standard Microsoft fonts: - **Heading 1**: 24 pt, bold, Cambria (`HEADING_SERIF_FONT`), 12 pt space before, 6 pt space after. - **Heading 2**: 16 pt, bold, Aptos Display (`HEADING_SANS_FONT`), 10 pt space before, 6 pt space after. - **Heading 3**: 14 pt, bold, Cambria (`HEADING_SERIF_FONT`), 7 pt space before, 6 pt space after. - Headings 4–9 keep their original sizing and body font definitions. ## Why The original built-in Heading 1–3 were non-bold Aptos Display at 20 pt, 16 pt, 14 pt, which felt relat
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- lucasmelo-mike01 (imported from pull request #4443, open)
- Base
6a2b520fa49aa0d0595cea36589aaf16ca371cd3- Size
- +34 −18 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
bd23687b6ee518a07bfde61a
How it went
No other operator has reported using it yet.
Diff
raw · crates/doc/src/resolve.rs crates/doc/src/styles.rs
@@ -398,13 +398,25 @@ mod tests { #[test] fn heading_resolves() { let s = StyleSheet::builtin();- let p = s.resolve_para(&ParaProps { style: Some("Heading1".into()), ..Default::default() });- assert!(p.keep_next);- assert_eq!(p.outline_level, Some(0));- assert_eq!(p.space_after, 4.0);+ let h1 = s.resolve_para(&ParaProps { style: Some("Heading1".into()), ..Default::default() });+ assert!(h1.keep_next);+ assert_eq!(h1.outline_level, Some(0));+ assert_eq!((h1.space_before, h1.space_after), (12.0, 6.0)); let c = s.resolve_char(Some("Heading1"), &CharProps::default());- assert_eq!(c.size, 20.0);- assert_eq!(c.font, crate::styles::HEADING_FONT);+ assert_eq!(c.size, 24.0);+ assert_eq!(c.font, crate::styles::HEADING_SERIF_FONT);+ assert!(c.bold, "the headings are bold");+ assert_eq!(c.color, TextColor::Rgb(crate::styles::HEADING_BLUE), "heading blue");+ // Levels 2 and 3: sans and serif faces, sizes and spacing.+ let h2 = s.resolve_para(&ParaProps { style: Some("Heading2".into()), ..Default::default() });+ assert_eq!((h2.outline_level, h2.space_before, h2.space_after), (Some(1), 10.0, 6.0));+ let h2c = s.resolve_char(Some("Heading2"), &CharProps::default());+ assert_eq!((h2c.size, h2c.font.as_str(), h2c.bold), (16.0, crate::styles::HEADING_SANS_FONT, true));+ let h3 = s.resolve_para(&ParaProps { style: Some("Heading3".into()), ..Default::default() });+ assert_eq!((h3.outline_level, h3.space_before, h3.space_after), (Some(2), 7.0, 6.0));+ let h3c = s.resolve_char(Some("Heading3"), &CharProps::default());+ assert_eq!((h3c.size, h3c.font.as_str(), h3c.bold), (14.0, crate::styles::HEADING_SERIF_FONT, true));+ // Direct formatting still wins. let c2 = s.resolve_char(Some("Heading1"), &CharProps { size: Some(30.0), ..Default::default() }); assert_eq!(c2.size, 30.0); }@@ -460,6 +460,10 @@ pub const HEADING_BLUE: Rgb = Rgb(0x0F, 0x47, 0x61); /// Default body/heading fonts (theme minor/major). Substituted by layout when not installed. pub const BODY_FONT: &str = "Aptos"; pub const HEADING_FONT: &str = "Aptos Display";+/// Microsoft serif and sans heading fonts: Heading 1 and Heading 3 are set in Cambria,+/// Heading 2 in Aptos Display. Both are substituted by layout when not installed.+pub const HEADING_SERIF_FONT: &str = "Cambria";+pub const HEADING_SANS_FONT: &str = "Aptos Display"; fn chr() -> CharProps { CharProps::default()@@ -517,18 +521,18 @@ impl StyleSheet { quick: true, ..p_style() });- let heads: [(f32, f32, f32, Option<bool>, Rgb, &str); 9] = [- (20.0, 18.0, 4.0, None, HEADING_BLUE, HEADING_FONT),- (16.0, 8.0, 4.0, None, HEADING_BLUE, HEADING_FONT),- (14.0, 8.0, 4.0, None, HEADING_BLUE, BODY_FONT),- (12.0, 4.0, 2.0, Some(true), HEADING_BLUE, BODY_FONT),- (12.0, 4.0, 2.0, None, HEADING_BLUE, BODY_FONT),- (12.0, 2.0, 0.0, Some(true), Rgb(0x59, 0x59, 0x59), BODY_FONT),- (12.0, 2.0, 0.0, None, Rgb(0x59, 0x59, 0x59), BODY_FONT),- (12.0, 0.0, 0.0, Some(true), Rgb(0x27, 0x27, 0x27), BODY_FONT),- (12.0, 0.0, 0.0, None, Rgb(0x27, 0x27, 0x27), BODY_FONT),+ let heads: [(f32, f32, f32, Option<bool>, Rgb, &str, bool); 9] = [+ (24.0, 12.0, 6.0, None, HEADING_BLUE, HEADING_SERIF_FONT, true),+ (16.0, 10.0, 6.0, None, HEADING_BLUE, HEADING_SANS_FONT, true),+ (14.0, 7.0, 6.0, None, HEADING_BLUE, HEADING_SERIF_FONT, true),+ (12.0, 4.0, 2.0, Some(true), HEADING_BLUE, BODY_FONT, false),+ (12.0, 4.0, 2.0, None, HEADING_BLUE, BODY_FONT, false),+ (12.0, 2.0, 0.0, Some(true), Rgb(0x59, 0x59, 0x59), BODY_FONT, false),+ (12.0, 2.0, 0.0, None, Rgb(0x59, 0x59, 0x59), BODY_FONT, false),+ (12.0, 0.0, 0.0, Some(true), Rgb(0x27, 0x27, 0x27), BODY_FONT, false),+ (12.0, 0.0, 0.0, None, Rgb(0x27, 0x27, 0x27), BODY_FONT, false), ];- for (i, (size, before, after, italic, c, font)) in heads.into_iter().enumerate() {+ for (i, (size, before, after, italic, c, font, bold)) in heads.into_iter().enumerate() { let n = i + 1; add(Style { id: format!("Heading{n}"),@@ -544,7 +548,7 @@ impl StyleSheet { outline_level: Some(i as u8), ..para() },- chr: CharProps { font: Some(font.into()), size: Some(size), italic, color: color(c), ..chr() },+ chr: CharProps { font: Some(font.into()), size: Some(size), italic, bold: bold.then_some(true), color: color(c), ..chr() }, priority: Some(9 + n as u32), quick: n <= 3, ..p_style()