mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-26 03:27:03 -06:00
format.languageAll: also mark each text body's own list style
A layout placeholder's a:lstStyle can carry lang/noProof, and ed::format_all only touched runs and end marks, so such a placeholder kept its old language. Existing list style levels of shape, table cell and notes bodies now get the edit too; bodies without one get none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
507fdc3767
commit
291725c78e
@@ -434,16 +434,21 @@ fn language(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
/// Every run in the deck, and the text styles new text inherits from, in one language.
|
||||
fn language_all(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let f = language_edit("format.languageAll", p)?;
|
||||
// Runs, end marks and the body's own list style levels (never creating one).
|
||||
fn body(t: &mut deckcraft_model::text::TextBody, f: &dyn Fn(&mut RunProps)) {
|
||||
ed::format_all(t, f);
|
||||
t.list_style.levels.iter_mut().flatten().for_each(|lv| f(&mut lv.run));
|
||||
}
|
||||
fn shapes(list: &mut [Shape], f: &dyn Fn(&mut RunProps), depth: usize) {
|
||||
if depth > 64 {
|
||||
return;
|
||||
}
|
||||
for sh in list {
|
||||
if let Some(t) = &mut sh.text {
|
||||
ed::format_all(t, f);
|
||||
body(t, f);
|
||||
}
|
||||
match &mut sh.kind {
|
||||
deckcraft_model::ShapeKind::Table(t) => t.rows.iter_mut().flat_map(|r| &mut r.cells).for_each(|c| ed::format_all(&mut c.text, f)),
|
||||
deckcraft_model::ShapeKind::Table(t) => t.rows.iter_mut().flat_map(|r| &mut r.cells).for_each(|c| body(&mut c.text, f)),
|
||||
deckcraft_model::ShapeKind::Group { children, .. } => shapes(children, f, depth + 1),
|
||||
_ => {}
|
||||
}
|
||||
@@ -460,7 +465,7 @@ fn language_all(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
for sl in &mut doc.slides {
|
||||
let sl = Arc::make_mut(sl);
|
||||
shapes(&mut sl.shapes, &f, 0);
|
||||
ed::format_all(&mut sl.notes, &f);
|
||||
body(&mut sl.notes, &f);
|
||||
}
|
||||
let extra = [doc.notes_master.as_mut(), doc.handout_master.as_mut()];
|
||||
for m in doc.masters.iter_mut().chain(extra.into_iter().flatten()) {
|
||||
|
||||
@@ -3767,8 +3767,26 @@ fn language_all_marks_every_text_in_the_deck_with_nothing_selected() {
|
||||
s.execute("slide.new", &json!({"title": "world hellow"})).unwrap();
|
||||
s.execute("insert.table", &json!({"rows": 1, "cols": 1})).unwrap();
|
||||
s.execute("edit.select", &json!({"ids": []})).unwrap();
|
||||
// A layout placeholder with its own list style (a:lstStyle) in another language.
|
||||
let placeholder = s
|
||||
.edit(|doc, _| {
|
||||
let m = std::sync::Arc::make_mut(doc.masters.first_mut().unwrap());
|
||||
let sh = m.layouts[0].shapes.iter_mut().find(|sh| sh.text.is_some()).unwrap();
|
||||
let lv = deckcraft_model::text::LevelStyle {
|
||||
run: deckcraft_model::RunProps { lang: Some("de-DE".into()), ..Default::default() },
|
||||
..Default::default()
|
||||
};
|
||||
sh.text.as_mut().unwrap().list_style.set(0, lv);
|
||||
Ok(sh.id)
|
||||
})
|
||||
.unwrap();
|
||||
s.execute("format.languageAll", &json!({"lang": "xx-AL"})).unwrap();
|
||||
let st = s.doc().unwrap();
|
||||
let ph = deckcraft_model::find_shape(&st.doc.masters[0].layouts[0].shapes, placeholder).unwrap();
|
||||
assert_eq!(ph.text.as_ref().unwrap().list_style.level(0).unwrap().run.lang.as_deref(), Some("xx-AL"));
|
||||
// A body without a list style doesn't get one.
|
||||
let boxed = st.doc.slides.iter().find_map(|sl| deckcraft_model::find_shape(&sl.shapes, deckcraft_model::ShapeId(a as u32))).unwrap();
|
||||
assert!(boxed.text.as_ref().unwrap().list_style.is_empty());
|
||||
let mut langs = vec![];
|
||||
for sl in &st.doc.slides {
|
||||
deckcraft_model::walk(&sl.shapes, &mut |sh, _| {
|
||||
|
||||
Reference in New Issue
Block a user