From 77df0dee8e84b242c994fe5f5e3a8fb4590d5b81 Mon Sep 17 00:00:00 2001 From: Bortlesboat Date: Tue, 12 May 2026 22:37:50 -0400 Subject: [PATCH] fix: preserve table width remainders --- src/cortex-core/src/markdown/table/tests.rs | 23 +++++++++++++++++ src/cortex-core/src/markdown/table/types.rs | 28 +++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/cortex-core/src/markdown/table/tests.rs b/src/cortex-core/src/markdown/table/tests.rs index b483a0203..2b2fa09a9 100644 --- a/src/cortex-core/src/markdown/table/tests.rs +++ b/src/cortex-core/src/markdown/table/tests.rs @@ -151,6 +151,29 @@ mod tests { assert!(table.column_widths[1] >= 20); } + #[test] + fn test_column_width_distribution_preserves_available_space() { + let mut builder = TableBuilder::new(); + builder.start_header(); + builder.add_cell("A A A".to_string()); + builder.add_cell("B B B".to_string()); + builder.add_cell("C C C".to_string()); + builder.end_header(); + + builder.start_row(); + builder.add_cell("aa bb cc".to_string()); + builder.add_cell("dd ee ff".to_string()); + builder.add_cell("gg hh ii".to_string()); + builder.end_row(); + + let mut table = builder.build(); + let max_width = 21; + table.calculate_column_widths(max_width); + + // Three columns have 4 border chars and 6 padding chars, leaving 11 content chars. + assert_eq!(table.column_widths.iter().sum::(), 11); + } + #[test] fn test_missing_cells_in_rows() { let mut builder = TableBuilder::new(); diff --git a/src/cortex-core/src/markdown/table/types.rs b/src/cortex-core/src/markdown/table/types.rs index 52bd6839c..f5223e171 100644 --- a/src/cortex-core/src/markdown/table/types.rs +++ b/src/cortex-core/src/markdown/table/types.rs @@ -209,11 +209,35 @@ impl Table { self.column_widths = min_widths.clone(); if pref_extra > 0 { + let mut allocated_total = 0; + let mut remainders = Vec::with_capacity(num_cols); + for i in 0..num_cols { let col_extra = pref_widths[i].saturating_sub(min_widths[i]); - let allocated = - (col_extra as f64 / pref_extra as f64 * extra_space as f64) as usize; + let weighted_extra = col_extra * extra_space; + let allocated = weighted_extra / pref_extra; + let remainder = weighted_extra % pref_extra; + self.column_widths[i] += allocated; + allocated_total += allocated; + + if allocated < col_extra { + remainders.push((i, remainder)); + } + } + + let mut remaining = extra_space.saturating_sub(allocated_total); + remainders.sort_by(|a, b| b.1.cmp(&a.1).then_with(|| a.0.cmp(&b.0))); + + for (i, _) in remainders { + if remaining == 0 { + break; + } + + if self.column_widths[i] < pref_widths[i] { + self.column_widths[i] += 1; + remaining -= 1; + } } } } else {