@@ -627,6 +627,10 @@ pub const ConsoleRenderer = struct {
627627 const ncol = table .content .Table .ncol ;
628628 const col_w = @divFloor (self .opts .width - (2 * self .opts .indent ) - (ncol + 1 ), ncol );
629629
630+ // The total width of all text to be rendered (removing inter-column spacing)
631+ const render_width = self .opts .width - (2 * self .opts .indent ) - (ncol + 1 );
632+ const render_width_f : f32 = @floatFromInt (render_width );
633+
630634 // Create a new renderer to render into a buffer for each cell
631635 // Use an arena to simplify memory management here
632636 var arena = std .heap .ArenaAllocator .init (self .alloc );
@@ -639,11 +643,33 @@ pub const ConsoleRenderer = struct {
639643 };
640644 var cells = ArrayList (Cell ).init (alloc );
641645
642- for (table .children .items ) | item | {
646+ const relative_widths = table .content .Table .relative_width .items ;
647+ const total_width : usize = blk : {
648+ var sum : usize = 0 ;
649+ for (relative_widths ) | w | {
650+ sum += w ;
651+ }
652+ break :blk sum ;
653+ };
654+ const total_width_f : f32 = @floatFromInt (total_width );
655+
656+ // Compute & store the (integer) width of each column
657+ var col_widths = try ArrayList (u32 ).initCapacity (alloc , ncol );
658+ for (relative_widths ) | w | {
659+ const rel_width : f32 = @floatFromInt (w );
660+ const width_frac : f32 = rel_width / total_width_f ;
661+ col_widths .appendAssumeCapacity (@intFromFloat (@round (width_frac * render_width_f )));
662+ }
663+
664+ for (table .children .items , 0.. ) | item , i | {
665+ // Compute the width of this cell based on which column it is in
666+ const col_idx : usize = @mod (i , ncol );
667+ const width : usize = col_widths .items [col_idx ];
668+
643669 // Render the table cell into a new buffer
644670 var alloc_writer = std .Io .Writer .Allocating .init (alloc );
645671 const sub_opts = Config {
646- .width = col_w - 1 ,
672+ .width = width - 1 , // col_w - 1,
647673 .indent = 1 ,
648674 .max_image_rows = self .opts .max_image_rows ,
649675 .max_image_cols = col_w - 2 * self .opts .indent ,
@@ -664,7 +690,7 @@ pub const ConsoleRenderer = struct {
664690 const nrow : usize = @divFloor (cells .items .len , ncol );
665691 std .debug .assert (cells .items .len == ncol * nrow );
666692
667- self .writeTableBorderTop (ncol , col_w );
693+ self .writeTableBorderTop (ncol , col_widths . items );
668694
669695 for (0.. nrow ) | i | {
670696 // Get the max number of rows of text for any cell in the table row
@@ -683,14 +709,20 @@ pub const ConsoleRenderer = struct {
683709 // Loop over the # of rows of text in this single row of the table
684710 for (0.. max_rows ) | _ | {
685711 self .writeLeaders ();
712+ var left_col_idx : usize = self .opts .indent + 2 ;
686713 for (0.. ncol ) | j | {
687714 const cell_idx : usize = i * ncol + j ;
688715 const cell : * Cell = & cells .items [cell_idx ];
689716
717+ const rel_width : f32 = @floatFromInt (relative_widths [j ]);
718+ const width_f : f32 = (rel_width / total_width_f ) * render_width_f ;
719+ const width : usize = @intFromFloat (@round (width_f ));
720+
690721 // For each cell in the row...
691722 self .write (self .opts .box_style .vb );
692723 self .write (" " );
693724
725+ // --- TODO --- left/center/right alignment should be handled here
694726 if (cell .idx < cell .text .len ) {
695727 // Write the next line of text from that cell,
696728 // then increment the write head index of that cell.
@@ -706,11 +738,14 @@ pub const ConsoleRenderer = struct {
706738 cell .idx += text .len + 1 ;
707739
708740 // Move the cursor to the start of the next cell
709- const new_col : usize = self .opts .indent + (j + 2 ) + (j + 1 ) * col_w ;
741+ // const new_col: usize = self.opts.indent + (j + 2) + (j + 1) * col_w;
742+ left_col_idx += width + 1 ;
743+ const new_col = left_col_idx ;
710744 self .printno (cons .set_col , .{new_col });
711745 self .column = new_col ;
712746 } else {
713- self .writeNTimes (" " , col_w - 1 );
747+ // self.writeNTimes(" ", col_w - 1);
748+ self .writeNTimes (" " , width - 1 );
714749 }
715750 }
716751 self .write (self .opts .box_style .vb );
@@ -721,16 +756,17 @@ pub const ConsoleRenderer = struct {
721756 self .writeLeaders ();
722757
723758 if (i == nrow - 1 ) {
724- self .writeTableBorderBottom (ncol , col_w );
759+ self .writeTableBorderBottom (ncol , col_widths . items );
725760 } else {
726- self .writeTableBorderMiddle (ncol , col_w );
761+ self .writeTableBorderMiddle (ncol , col_widths . items );
727762 }
728763 }
729764 }
730765
731- fn writeTableBorderTop (self : * Self , ncol : usize , col_w : usize ) void {
766+ fn writeTableBorderTop (self : * Self , ncol : usize , col_widths : [] const u32 ) void {
732767 self .write (self .opts .box_style .tl );
733768 for (0.. ncol ) | i | {
769+ const col_w : usize = col_widths [i ];
734770 for (0.. col_w ) | _ | {
735771 self .write (self .opts .box_style .hb );
736772 }
@@ -744,9 +780,10 @@ pub const ConsoleRenderer = struct {
744780 self .writeLeaders ();
745781 }
746782
747- fn writeTableBorderMiddle (self : * Self , ncol : usize , col_w : usize ) void {
783+ fn writeTableBorderMiddle (self : * Self , ncol : usize , col_widths : [] const u32 ) void {
748784 self .write (self .opts .box_style .lj );
749785 for (0.. ncol ) | i | {
786+ const col_w : usize = col_widths [i ];
750787 for (0.. col_w ) | _ | {
751788 self .write (self .opts .box_style .hb );
752789 }
@@ -760,9 +797,10 @@ pub const ConsoleRenderer = struct {
760797 self .writeLeaders ();
761798 }
762799
763- fn writeTableBorderBottom (self : * Self , ncol : usize , col_w : usize ) void {
800+ fn writeTableBorderBottom (self : * Self , ncol : usize , col_widths : [] const u32 ) void {
764801 self .write (self .opts .box_style .bl );
765802 for (0.. ncol ) | i | {
803+ const col_w : usize = col_widths [i ];
766804 for (0.. col_w ) | _ | {
767805 self .write (self .opts .box_style .hb );
768806 }
0 commit comments