From aae2c2fefd865cbfc59af80aa27926fae765a802 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 26 Dec 2025 12:09:09 -0800 Subject: [PATCH] more fixes --- rust/pspp/src/output/pivot/value.rs | 18 +++++++++-- rust/pspp/src/spv/read/legacy_xml.rs | 15 ++++++++-- rust/pspp/src/spv/read/tests.rs | 7 +++++ rust/pspp/src/spv/testdata/legacy12.expected | 30 +++++++++++++++++++ rust/pspp/src/spv/testdata/legacy12.spv | Bin 0 -> 5853 bytes 5 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 rust/pspp/src/spv/testdata/legacy12.expected create mode 100644 rust/pspp/src/spv/testdata/legacy12.spv diff --git a/rust/pspp/src/output/pivot/value.rs b/rust/pspp/src/output/pivot/value.rs index 8aec1f9f75..879e0a6e99 100644 --- a/rust/pspp/src/output/pivot/value.rs +++ b/rust/pspp/src/output/pivot/value.rs @@ -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>, ) -> Self { - for subscript in subscripts { - self.add_subscript(subscript); - } + self.styling_mut() + .subscripts + .extend(subscripts.into_iter().map(|s| s.into())); self } diff --git a/rust/pspp/src/spv/read/legacy_xml.rs b/rust/pspp/src/spv/read/legacy_xml.rs index f728acf8e8..4ca93a0cf4 100644 --- a/rust/pspp/src/spv/read/legacy_xml.rs +++ b/rust/pspp/src/spv/read/legacy_xml.rs @@ -844,6 +844,7 @@ impl Visualization { dims: &mut [Dim], data: &mut HashMap, 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) diff --git a/rust/pspp/src/spv/read/tests.rs b/rust/pspp/src/spv/read/tests.rs index 634446b6b7..b850bca226 100644 --- a/rust/pspp/src/spv/read/tests.rs +++ b/rust/pspp/src/spv/read/tests.rs @@ -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 index 0000000000..ff3c6259b6 --- /dev/null +++ b/rust/pspp/src/spv/testdata/legacy12.expected @@ -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 index 0000000000000000000000000000000000000000..9673270cc7d735c8c584baa1656dfb87f73a1bc6 GIT binary patch literal 5853 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