Skip to content

Commit 4ba84dc

Browse files
authored
Absorb stray Input-styled widget-dump cells when opening Manipulate notebooks (#450)
Wolfram Demonstrations Project source notebooks (the authoring copy downloaded from demonstrations.wolfram.com) sometimes store an extra Input-styled cell between the real Manipulate[...] source and its cached Output — a leftover evaluation snapshot whose content is itself a raw FrontEnd widget dump (DynamicModuleBox[...]), never meaningful as code. editors_from_notebook only recognized Output/Print cells as part of an Input cell's evaluation result, so this stray cell broke the pairing: the real source lost its cached output (no live widget), and the stray cell rendered as its own empty, broken "code" cell. Treat an Input-styled cell whose content is itself a dynamic-box dump the same as a stored Output when scanning forward from a source cell, so it is absorbed into the widget instantiation instead of shown as its own broken cell.
1 parent 69f61ba commit 4ba84dc

1 file changed

Lines changed: 47 additions & 4 deletions

File tree

woxi-studio/src/main.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,18 +568,27 @@ impl WoxiStudio {
568568
while i < cells.len() {
569569
let cell = &cells[i];
570570
if matches!(cell.style, CellStyle::Input | CellStyle::Code) {
571-
// Collect following Output/Print cells
571+
// Collect following Output/Print cells. Source notebooks
572+
// downloaded from the Wolfram Demonstrations Project
573+
// sometimes carry a stray *Input*-styled cell between the
574+
// real source and its cached Output — a leftover evaluation
575+
// snapshot whose content is itself a raw FrontEnd widget
576+
// dump (`DynamicModuleBox[…]`), never meaningful as code.
577+
// Treat such a cell the same as a stored Output so it is
578+
// absorbed here instead of rendered as a broken, empty
579+
// "code" cell of its own.
572580
let mut output = None;
573581
let mut stdout = None;
574582
let mut j = i + 1;
575583
while j < cells.len()
576-
&& matches!(
584+
&& (matches!(
577585
cells[j].style,
578586
CellStyle::Output | CellStyle::Print
579-
)
587+
) || (cells[j].style == CellStyle::Input
588+
&& is_dynamic_box_dump(&cells[j].content)))
580589
{
581590
match cells[j].style {
582-
CellStyle::Output => {
591+
CellStyle::Output | CellStyle::Input => {
583592
output = Some(cells[j].content.clone());
584593
}
585594
CellStyle::Print => {
@@ -7264,6 +7273,40 @@ Cell[BoxData["DynamicModuleBox[{$CellContext`a$$ = 1}, \"…\"]"], "Output"]
72647273
);
72657274
}
72667275

7276+
/// Wolfram Demonstrations Project "source" notebooks (the authoring
7277+
/// copy downloaded from demonstrations.wolfram.com, as opposed to the
7278+
/// deployed cloud embed) sometimes carry a stray *Input*-styled cell
7279+
/// between the real `Manipulate[…]` source and its cached Output — a
7280+
/// leftover evaluation snapshot whose content is itself a raw
7281+
/// FrontEnd widget dump (`DynamicModuleBox[…]`), never meaningful as
7282+
/// code. That extra cell must be absorbed rather than rendered as its
7283+
/// own broken, empty "code" cell, and must not be mistaken for the
7284+
/// real source when the live widget is instantiated.
7285+
#[test]
7286+
fn stray_input_styled_widget_dump_between_source_and_output_is_absorbed() {
7287+
let nb_src = r#"Notebook[{
7288+
Cell[CellGroupData[{
7289+
Cell[BoxData["Manipulate[x^2, {x, 1, 10}]"], "Input"],
7290+
Cell[BoxData["DynamicModuleBox[{$CellContext`x$$ = 5}, \"…\"]"], "Input"],
7291+
Cell[BoxData["DynamicModuleBox[{$CellContext`x$$ = 1}, \"…\"]"], "Output"]
7292+
}, Open]]
7293+
}]"#;
7294+
let nb = woxi::notebook::parse_notebook(nb_src).unwrap();
7295+
let editors = WoxiStudio::editors_from_notebook(&nb);
7296+
// The stray widget-dump Input cell is absorbed into the real source
7297+
// cell's editor, not rendered as its own (broken, empty) entry.
7298+
assert_eq!(editors.len(), 1);
7299+
let widget = editors[0]
7300+
.manipulate_state
7301+
.as_ref()
7302+
.expect("the stored Manipulate must instantiate on load");
7303+
assert!(
7304+
widget.error.is_none(),
7305+
"body must evaluate cleanly: {:?}",
7306+
widget.error
7307+
);
7308+
}
7309+
72677310
/// A stored Manipulate whose body composes `Tooltip`-wrapped series
72687311
/// (one built with `Table`, one with `NestList`/`Partition`) into a
72697312
/// `ListLinePlot` with a `PlotLabel` assembled from `ToString`/

0 commit comments

Comments
 (0)