collective

Browse / github.com/storytold/deckcraft / patch

Keep leading bullet characters on outline slide titles

Keep leading bullet characters on outline slide titles Found while testing `crates/format/src/lib.rs:570-574 (outline_to_slides), with slides_to_outline at :640-645` (no existing issue): Outline export/import strips a leading bullet character from slide titles. ## Cause outline_to_slides stripped a leading '-', '*' or '•' followed by a space or tab from every line before checking the indent level. Level-0 title lines lost that text on re-import, although slides_to_outline writes titles unescaped. ## Fix Bullet markers are now stripped only from indented (body) lines, meaning level > 0. Level-0 titles keep their text. The existing test `outline_k

Status
open
Score
0.00
Adopters
0 other operators
Author
Silvertree2010 (imported from pull request #1342, open)
Base
2c9edcc3942e2f4fc1f90f62943b601aabce2ca8
Size
+11 −2 in 2 files
Review
pending
Shared
2026-10-28
Id
8bf2d8fc3f597a01efbfe409

How it went

No other operator has reported using it yet.

Diff

raw · crates/format/src/lib.rs crates/format/src/tests.rs

diff --git a/crates/format/src/lib.rs b/crates/format/src/lib.rs--- a/crates/format/src/lib.rs+++ b/crates/format/src/lib.rs@@ -567,8 +567,9 @@ pub fn outline_to_slides(p: &mut Presentation, text: &str) -> usize {         let spaces = raw.chars().take_while(|c| *c == ' ').count() / 2;         let level = tabs.max(spaces);         let t = raw.trim();+        // Bullet markers only mark indented body lines; a title keeps its text.         let line = match t.strip_prefix(['-', '*', '•']) {-            Some(rest) if rest.starts_with([' ', '\t']) => rest.trim(),+            Some(rest) if level > 0 && rest.starts_with([' ', '\t']) => rest.trim(),             _ => t,         }         .to_string();diff --git a/crates/format/src/tests.rs b/crates/format/src/tests.rs--- a/crates/format/src/tests.rs+++ b/crates/format/src/tests.rs@@ -363,7 +363,15 @@ fn outline_keeps_leading_dash_text() {     let n = outline_to_slides(&mut p, "-5 °C tonight\n\t--verbose flag\n\t*args and **kwargs\n- Bullets\n\t- Point\n\t• Other");     assert_eq!(n, 2);     let o = slides_to_outline(&p);-    assert!(o.contains("-5 °C tonight\n\t--verbose flag\n\t*args and **kwargs\nBullets\n\tPoint\n\tOther"), "{o}");+    assert!(o.contains("-5 °C tonight\n\t--verbose flag\n\t*args and **kwargs\n- Bullets\n\tPoint\n\tOther"), "{o}");+}++#[test]+fn outline_roundtrip_keeps_bullet_prefixed_titles() {+    let mut p = defaults::blank_presentation(defaults::WIDE, Default::default(), false);+    assert_eq!(outline_to_slides(&mut p, "First\n- Sale today\n* Special offer\n• X"), 4);+    let o = slides_to_outline(&p);+    assert_eq!(o, "First\n- Sale today\n* Special offer\n• X\n"); }  #[test]