more fixes
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 26 Dec 2025 20:09:09 +0000 (12:09 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 26 Dec 2025 20:09:09 +0000 (12:09 -0800)
rust/pspp/src/output/pivot/value.rs
rust/pspp/src/spv/read/legacy_xml.rs
rust/pspp/src/spv/read/tests.rs
rust/pspp/src/spv/testdata/legacy12.expected [new file with mode: 0644]
rust/pspp/src/spv/testdata/legacy12.spv [new file with mode: 0644]

index 8aec1f9f7535298cc2484a15572c5825b0bd97a0..879e0a6e9939930ebe5c6d84c3526f7bbf9a259b 100644 (file)
@@ -290,14 +290,26 @@ impl Value {
         footnotes.sort_by_key(|f| f.index);
     }
 
+    /// Removes all of the footnotes from `value`.
+    pub fn clear_footnotes(&mut self) {
+        if let Some(styling) = &mut self.styling
+            && !styling.footnotes.is_empty()
+        {
+            styling.footnotes.clear();
+            if styling.is_empty() {
+                self.styling = None;
+            }
+        }
+    }
+
     /// Returns this `Value` with the added `subscripts`.
     pub fn with_subscripts<'a>(
         mut self,
         subscripts: impl IntoIterator<Item = impl Into<String>>,
     ) -> Self {
-        for subscript in subscripts {
-            self.add_subscript(subscript);
-        }
+        self.styling_mut()
+            .subscripts
+            .extend(subscripts.into_iter().map(|s| s.into()));
         self
     }
 
index f728acf8e8ddc2a6af7e5b3247c65ff8064be87b..4ca93a0cf4da265a56705e489c441e6c8307b0d3 100644 (file)
@@ -844,6 +844,7 @@ impl Visualization {
                     dims: &mut [Dim],
                     data: &mut HashMap<Vec<usize>, Value>,
                     footnotes: &pivot::Footnotes,
+                    has_cell_footnotes: bool,
                 ) {
                     let mut wheres = Vec::new();
                     let mut alternating = false;
@@ -930,6 +931,7 @@ impl Visualization {
                                             self.frame,
                                             &look.areas[Area::Labels(axis)],
                                             footnotes,
+                                            has_cell_footnotes,
                                         );
                                     }
                                 }
@@ -993,7 +995,8 @@ impl Visualization {
                                         self.major_ticks,
                                         self.frame,
                                         &look.areas[Area::Data(RowParity::Even)],
-                                        footnotes
+                                        footnotes,
+                                        has_cell_footnotes,
                                     );
                                 }
                             }
@@ -1039,7 +1042,8 @@ impl Visualization {
                             &series,
                             dims.as_mut_slice(),
                             &mut data,
-                            &footnotes
+                            &footnotes,
+                            cell_footnotes.is_some(),
                         );
                     }
                 }
@@ -1061,6 +1065,7 @@ impl Visualization {
                                 None,
                                 &look.areas[Area::Data(RowParity::Even)],
                                 &footnotes,
+                                cell_footnotes.is_some(),
                             );
                         }
                     }
@@ -1963,6 +1968,7 @@ impl Style {
         bg: Option<&Style>,
         base_style: &AreaStyle,
         footnotes: &pivot::Footnotes,
+        has_cell_footnotes: bool,
     ) {
         if let Some(sf) = sf {
             if let Some(child) = &sf.child
@@ -1992,7 +1998,10 @@ impl Style {
                     }
                 }
             }
-            if let Some(child) = &sf.child {
+            if let Some(child) = &sf.child
+                && !has_cell_footnotes
+            {
+                value.clear_footnotes();
                 for affix in child.affixes() {
                     if let Some(index) = affix.defines_reference.checked_sub(1)
                         && let Ok(index) = usize::try_from(index)
index 634446b6b7f848fe086fcb58d037399c063819ae..b850bca2268b9fe6cd8440994c170f90f6211020 100644 (file)
@@ -75,6 +75,13 @@ fn legacy11() {
     test_raw_spvfile("legacy11");
 }
 
+/// Checks that footnotes on data cells added via the `cellFootnotes` series
+/// can't be deleted via `setFormat`.
+#[test]
+fn legacy12() {
+    test_raw_spvfile("legacy12");
+}
+
 fn test_raw_spvfile(name: &str) {
     let input_filename = Path::new("src/spv/testdata")
         .join(name)
diff --git a/rust/pspp/src/spv/testdata/legacy12.expected b/rust/pspp/src/spv/testdata/legacy12.expected
new file mode 100644 (file)
index 0000000..ff3c625
--- /dev/null
@@ -0,0 +1,30 @@
+                                           Correlations
+╭──────────────────────────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────╮
+│                              │Variable A│Variable B│Variable C│Variable D│Variable E│Variable F│
+├──────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
+│Variable A Pearson Correlation│         1│      .223│   .245[*]│   .293[*]│  .461[**]│  .687[**]│
+│           Sig. (2-tailed)    │          │      .056│      .035│      .011│      .000│      .000│
+│           N                  │        74│        74│        74│        74│        74│        74│
+├──────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
+│Variable B Pearson Correlation│      .223│         1│  .982[**]│  .635[**]│  .320[**]│  .386[**]│
+│           Sig. (2-tailed)    │      .056│          │      .000│      .000│      .005│      .001│
+│           N                  │        74│        74│        74│        74│        74│        74│
+├──────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
+│Variable C Pearson Correlation│   .245[*]│  .982[**]│         1│  .665[**]│  .342[**]│  .404[**]│
+│           Sig. (2-tailed)    │      .035│      .000│          │      .000│      .003│      .000│
+│           N                  │        74│        74│        74│        74│        74│        74│
+├──────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
+│Variable D Pearson Correlation│   .293[*]│  .635[**]│  .665[**]│         1│  .339[**]│  .513[**]│
+│           Sig. (2-tailed)    │      .011│      .000│      .000│          │      .003│      .000│
+│           N                  │        74│        74│        74│        74│        74│        74│
+├──────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
+│Variable E Pearson Correlation│  .461[**]│  .320[**]│  .342[**]│  .339[**]│         1│  .663[**]│
+│           Sig. (2-tailed)    │      .000│      .005│      .003│      .003│          │      .000│
+│           N                  │        74│        74│        74│        74│        74│        74│
+├──────────────────────────────┼──────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
+│Variable F Pearson Correlation│  .687[**]│  .386[**]│  .404[**]│  .513[**]│  .663[**]│         1│
+│           Sig. (2-tailed)    │      .000│      .001│      .000│      .000│      .000│          │
+│           N                  │        74│        74│        74│        74│        74│        74│
+╰──────────────────────────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────╯
+*. Correlation is significant at the 0.05 level (2-tailed).
+**. Correlation is significant at the 0.01 level (2-tailed).
diff --git a/rust/pspp/src/spv/testdata/legacy12.spv b/rust/pspp/src/spv/testdata/legacy12.spv
new file mode 100644 (file)
index 0000000..9673270
Binary files /dev/null and b/rust/pspp/src/spv/testdata/legacy12.spv differ