fixes
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 6 Jan 2026 20:14:54 +0000 (12:14 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 6 Jan 2026 20:14:54 +0000 (12:14 -0800)
rust/pspp/src/output/drivers/html.rs
rust/pspp/src/output/drivers/text/text_line.rs
rust/pspp/src/output/pivot/output.rs
rust/pspp/src/output/render.rs
rust/pspp/src/output/table.rs
rust/pspp/src/spv/testdata/legacy17.expected

index eaa623f6b064fc29b7867e7ff090bf2566e44903..a057364a4ed89c063eb962a9c9db537c3cae3fce 100644 (file)
@@ -322,8 +322,10 @@ where
         writeln!(&mut self.writer, "</{tag}>")
     }
 
-    fn put_border(dst: &mut String, style: BorderStyle, border_name: &str) {
-        if let Some(css_style) = style.stroke.as_css() {
+    fn put_border(dst: &mut String, style: Option<BorderStyle>, border_name: &str) {
+        if let Some(style) = style
+            && let Some(css_style) = style.stroke.as_css()
+        {
             write!(dst, "border-{border_name}: {css_style}").unwrap();
             if style.color != Color::BLACK {
                 write!(dst, " {}", style.color.display_css()).unwrap();
index 9d1019c465bc39c2d71a7f9ce9ce2dec3ad3dc07..f93dda5d8ed5e6dac0befc5feedca826678e4aeb 100644 (file)
@@ -322,7 +322,7 @@ impl TextLine {
 
 impl Display for TextLine {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.write_str(&self.string)
+        f.write_str(self.string.trim_end())
     }
 }
 
index e918401cef8b6258a7415b38746210018ac9f68d..b4d1db288520221b9bd1c18ab44037517106cd2b 100644 (file)
@@ -302,9 +302,9 @@ impl PivotTable {
             .rev()
             .filter(|(dimension, _)| !dimension.is_empty())
             .map(|(dimension, &layer_index)| {
-                // Append `:` to the name of the dimension, preserving all the styling.
+                // Append `: ` to the name of the dimension, preserving all the styling.
                 let name = dimension.root.name();
-                let text = format!("{}:", name.display(self).without_suffixes());
+                let text = format!("{}: ", name.display(self).without_suffixes());
                 let name = Value::new_user_text(text).with_styling(name.styling.clone());
 
                 self.create_aux_table(
index 301eb0186acce5ad65aa4d514af5dd14bb29bab3..69676343b24787dae674c6dbe65a4a5793348d1a 100644 (file)
@@ -671,24 +671,23 @@ impl Page {
         bb: Rect2,
         bg: Color,
     ) {
-        const NO_BORDER: BorderStyle = BorderStyle::none();
         let styles = EnumMap::from_fn(|a: Axis2| {
             let b = !a;
             if !is_rule(coord[a]) {
-                [NO_BORDER, NO_BORDER]
+                [None, None]
             } else if is_rule(coord[b]) {
                 let first = if coord[b] > 0 {
                     let mut e = coord;
                     e[b] -= 1;
                     self.get_rule(a, e)
                 } else {
-                    NO_BORDER
+                    None
                 };
 
                 let second = if coord[b] / 2 < self.table.n()[b] {
                     self.get_rule(a, coord)
                 } else {
-                    NO_BORDER
+                    None
                 };
 
                 [first, second]
@@ -698,10 +697,14 @@ impl Page {
             }
         });
 
-        device.draw_line(bb.translate(ofs), styles, bg);
+        if styles.values().any(|[a, b]| a.is_some() || b.is_some()) {
+            const NO_BORDER: BorderStyle = BorderStyle::none();
+            let styles = styles.map(|_, [a, b]| [a.unwrap_or(NO_BORDER), b.unwrap_or(NO_BORDER)]);
+            device.draw_line(bb.translate(ofs), styles, bg);
+        }
     }
 
-    fn get_rule(&self, a: Axis2, coord: CellPos) -> BorderStyle {
+    fn get_rule(&self, a: Axis2, coord: CellPos) -> Option<BorderStyle> {
         let coord = CellPos::from_fn(|a| coord[a] / 2);
         self.table.table.get_rule(a, coord)
     }
@@ -893,8 +896,9 @@ fn measure_rule(device: &dyn Device, table: &Table, a: Axis2, z: usize) -> isize
     // Determine the types of rules that are present.
     let mut rules = EnumMap::default();
     for w in 0..table.n[b] {
-        let stroke = table.get_rule(a, CellPos::for_axis((a, z), w)).stroke;
-        rules[stroke] = true;
+        if let Some(border) = table.get_rule(a, CellPos::for_axis((a, z), w)) {
+            rules[border.stroke] = true;
+        }
     }
 
     // Turn off [Stroke::None] because it has width 0 and we needn't bother.
index c9bd0ee2ebbeeaef94f2151ab5843b1506ed3e2d..228c76d9a77ba2935410dff5823f84dd6d8c91f4 100644 (file)
@@ -368,8 +368,8 @@ impl Table {
         }
     }
 
-    pub fn get_rule(&self, axis: Axis2, pos: CellPos) -> BorderStyle {
-        self.rules[axis][[pos.x, pos.y]].map_or(BorderStyle::none(), |b| self.borders[b])
+    pub fn get_rule(&self, axis: Axis2, pos: CellPos) -> Option<BorderStyle> {
+        self.rules[axis][[pos.x, pos.y]].map(|b| self.borders[b])
     }
 
     pub fn put(&mut self, region: CellRect, inner: CellInner) {
index 721c6b55a29d4a0225d9973c1b3e1f1063fada60..fcc6c531dd30952ffb1e9272868997c293cd9ab0 100644 (file)
@@ -1,10 +1,10 @@
-\e[38;2;0;0;0;48;2;255;255;255m                                   \e[0m\e[38;2;0;0;0;48;2;255;255;255;1mCoefficients[a]\e[0m\e[38;2;0;0;0;48;2;255;255;255m                                  \e[0m
+\e[38;2;0;0;0;48;2;255;255;255;1m                                   Coefficients[a]                                  \e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
 \e[38;2;0;0;0;48;2;255;255;255m╭───────────────┬────────────────────────────┬─────────────────────────┬──────┬────╮\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
-\e[38;2;0;0;0;48;2;255;255;255m│               │ \e[0m\e[38;2;0;0;0;48;2;255;255;255mUnstandardized Coefficients\e[0m\e[38;2;0;0;0;48;2;255;255;255m│\e[0m\e[38;2;0;0;0;48;2;255;255;255mStandardized Coefficients\e[0m\e[38;2;0;0;0;48;2;255;255;255m│      │    │\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
-\e[38;2;0;0;0;48;2;255;255;255m│               ├────────────┬───────────────┼─────────────────────────┤      │    │\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
-\e[38;2;0;0;0;48;2;255;255;255m│\e[0m\e[38;2;0;0;0;48;2;255;255;255mModel\e[0m\e[38;2;0;0;0;48;2;255;255;255m          │      \e[0m\e[38;2;0;0;0;48;2;255;255;255mB\e[0m\e[38;2;0;0;0;48;2;255;255;255m     │   \e[0m\e[38;2;0;0;0;48;2;255;255;255mStd. Error\e[0m\e[38;2;0;0;0;48;2;255;255;255m  │           \e[0m\e[38;2;0;0;0;48;2;255;255;255mBeta\e[0m\e[38;2;0;0;0;48;2;255;255;255m          │   \e[0m\e[38;2;0;0;0;48;2;46;184;72;1;3mt\e[0m\e[38;2;0;0;0;48;2;255;255;255m  │\e[0m\e[38;2;0;0;0;48;2;255;255;255mSig.\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
+\e[38;2;0;0;0;48;2;255;255;255m│               │ Unstandardized Coefficients│Standardized Coefficients│\e[0m\e[38;2;0;0;0;48;2;46;184;72;1;3m      \e[0m\e[38;2;0;0;0;48;2;255;255;255m│    │\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
+\e[38;2;0;0;0;48;2;255;255;255m│               ├────────────┬───────────────┼─────────────────────────┤\e[0m\e[38;2;0;0;0;48;2;46;184;72;1;3m      \e[0m\e[38;2;0;0;0;48;2;255;255;255m│    │\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
+\e[38;2;0;0;0;48;2;255;255;255m│Model          │      B     │   Std. Error  │           Beta          │\e[0m\e[38;2;0;0;0;48;2;46;184;72;1;3m   t  \e[0m\e[38;2;0;0;0;48;2;255;255;255m│Sig.\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
 \e[38;2;0;0;0;48;2;255;255;255m├───────────────┼────────────┼───────────────┼─────────────────────────┼──────┼────┤\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
-\e[38;2;0;0;0;48;2;255;255;255m│\e[0m\e[38;2;0;0;0;48;2;255;255;255m1.00\e[0m\e[38;2;0;0;0;48;2;255;255;255m \e[0m\e[38;2;0;0;0;48;2;255;255;255m(Constant)\e[0m\e[38;2;0;0;0;48;2;255;255;255m│      \e[0m\e[38;2;0;0;0;48;2;255;255;255m59.146\e[0m\e[38;2;0;0;0;48;2;255;255;255m│         \e[0m\e[38;2;0;0;0;48;2;255;255;255m18.854\e[0m\e[38;2;0;0;0;48;2;255;255;255m│                         │ \e[0m\e[38;2;0;0;0;48;2;239;51;56;1;3m3.137\e[0m\e[38;2;0;0;0;48;2;255;255;255m│\e[0m\e[38;2;0;0;0;48;2;255;255;255m.016\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
-\e[38;2;0;0;0;48;2;255;255;255m│     \e[0m\e[38;2;0;0;0;48;2;255;255;255mVariable A\e[0m\e[38;2;0;0;0;48;2;255;255;255m│       \e[0m\e[38;2;0;0;0;48;2;255;255;255m-.664\e[0m\e[38;2;0;0;0;48;2;255;255;255m│           \e[0m\e[38;2;0;0;0;48;2;255;255;255m.585\e[0m\e[38;2;0;0;0;48;2;255;255;255m│                    \e[0m\e[38;2;0;0;0;48;2;255;255;255m-.395\e[0m\e[38;2;0;0;0;48;2;255;255;255m│\e[0m\e[38;2;0;0;0;48;2;255;255;255m-1.136\e[0m\e[38;2;0;0;0;48;2;255;255;255m│\e[0m\e[38;2;0;0;0;48;2;255;255;255m.293\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
+\e[38;2;0;0;0;48;2;255;255;255m│1.00 (Constant)│      59.146│         18.854│                         │\e[0m\e[38;2;0;0;0;48;2;239;51;56;1;3m 3.137\e[0m\e[38;2;0;0;0;48;2;255;255;255m│.016\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
+\e[38;2;0;0;0;48;2;255;255;255m│     Variable A│       -.664│           .585│                    -.395│-1.136│.293\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
 \e[38;2;0;0;0;48;2;255;255;255m╰───────────────┴────────────┴───────────────┴─────────────────────────┴──────┴────╯\e[0m\e[38;2;0;0;0;48;2;255;255;255m\e[0m
 \e[38;2;0;0;0;48;2;255;255;255ma. Dependent Variable: A\e[0m\e[38;2;0;0;0;48;2;255;255;255m                                                            \e[0m