@@ -40,6 +40,27 @@ export type TableData = {
4040 W : number [ ] ;
4141} ;
4242
43+ /*
44+ * Sum the elements of an array
45+ */
46+ function SUM ( A : number [ ] ) {
47+ return A . reduce ( ( a , b ) => a + b , 0 ) ;
48+ }
49+
50+ /*
51+ * Get the maximum value from an array
52+ */
53+ function MAX ( A : number [ ] ) {
54+ return A . reduce ( ( a , b ) => Math . max ( a , b ) , 0 ) ;
55+ }
56+
57+ /*
58+ * Test if a value is a percentage
59+ */
60+ function isPercent ( x : string ) {
61+ return x . match ( / % \s * $ / ) ;
62+ }
63+
4364/*****************************************************************/
4465/*
4566 * The CHTMLmtable wrapper for the MmlMtable object
@@ -99,8 +120,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
99120 //
100121 // Determine the number of columns and rows
101122 //
102- this . numCols = this . childNodes . map ( row => ( row as CHTMLmtr < N , T , D > ) . numCells )
103- . reduce ( ( a , b ) => Math . max ( a , b ) , 0 ) ;
123+ this . numCols = MAX ( this . childNodes . map ( row => ( row as CHTMLmtr < N , T , D > ) . numCells ) ) ;
104124 this . numRows = this . childNodes . length ;
105125 //
106126 // Get the frame, row, and column parameters
@@ -243,10 +263,9 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
243263 //
244264 if ( this . node . attributes . get ( 'equalrows' ) ) {
245265 const HD = this . getEqualRowHeight ( ) ;
246- height = [ ] . concat ( this . rLines , this . rSpace ) . reduce ( ( a , b ) => a + b , 0 )
247- + HD * this . numRows ;
266+ height = SUM ( [ ] . concat ( this . rLines , this . rSpace ) ) + HD * this . numRows ;
248267 } else {
249- height = H . concat ( D , this . rLines , this . rSpace ) . reduce ( ( a , b ) => a + b , 0 ) ;
268+ height = SUM ( H . concat ( D , this . rLines , this . rSpace ) ) ;
250269 }
251270 height += ( this . frame ? .14 + 2 * this . fSpace [ 1 ] : 0 ) ;
252271 //
@@ -258,8 +277,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
258277 //
259278 // Get the expected width of the table
260279 //
261- width = CW . concat ( this . cLines , this . cSpace ) . reduce ( ( a , b ) => a + b , 0 )
262- + ( this . frame ? .14 + 2 * this . fSpace [ 0 ] : 0 ) ;
280+ width = SUM ( CW . concat ( this . cLines , this . cSpace ) ) + ( this . frame ? .14 + 2 * this . fSpace [ 0 ] : 0 ) ;
263281 //
264282 // If the table width is not 'auto', determine the specified width
265283 // and pick the larger of the specified and computed widths.
@@ -486,7 +504,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
486504 protected handleWidth ( ) {
487505 let w = this . node . attributes . get ( 'width' ) as string ;
488506 if ( w === 'auto' ) return ;
489- if ( w . match ( / % $ / ) ) {
507+ if ( isPercent ( w ) ) {
490508 this . bbox . pwidth = w ;
491509 } else {
492510 w = this . em ( this . length2em ( w ) + ( this . frame ? .14 : 0 ) ) ;
@@ -518,16 +536,39 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
518536 */
519537 protected getColumnWidths ( ) {
520538 const width = this . node . attributes . get ( 'width' ) as string ;
539+ if ( this . node . attributes . get ( 'equalcolumns' ) ) {
540+ return this . getEqualColumns ( width ) ;
541+ }
521542 const swidths = this . getColumnAttributes ( 'columnwidth' , 0 ) ;
522543 if ( width === 'auto' ) {
523544 return this . getColumnWidthsAuto ( swidths ) ;
524545 }
525- if ( width . match ( / % $ / ) ) {
546+ if ( isPercent ( width ) ) {
526547 return this . getColumnWidthsPercent ( swidths , width ) ;
527548 }
528549 return this . getColumnWidthsFixed ( swidths , this . length2em ( width ) ) ;
529550 }
530551
552+ /*
553+ * For tables with equal columns, get the proper amount per row.
554+ *
555+ * @return {(string|number|null)[] } The array of widths
556+ */
557+ protected getEqualColumns ( width : string ) {
558+ const n = Math . max ( 1 , this . numCols ) ;
559+ let cwidth ;
560+ if ( width === 'auto' ) {
561+ const { W} = this . getTableData ( ) ;
562+ cwidth = MAX ( W ) ;
563+ } else if ( isPercent ( width ) ) {
564+ cwidth = this . percent ( 1 / n ) ;
565+ } else {
566+ const w = SUM ( [ ] . concat ( this . cLines , this . cSpace ) ) + 2 * this . fSpace [ 0 ] ;
567+ cwidth = Math . max ( 0 , this . length2em ( width ) - w ) / n ;
568+ }
569+ return Array ( this . numCols ) . fill ( cwidth ) ;
570+ }
571+
531572 /*
532573 * For tables with width="auto", auto and fit columns
533574 * will end up being natural width, so don't need to
@@ -538,7 +579,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
538579 protected getColumnWidthsAuto ( swidths : string [ ] ) {
539580 return swidths . map ( x => {
540581 if ( x === 'auto' || x === 'fit' ) return null ;
541- if ( x . match ( / % $ / ) ) return x ;
582+ if ( isPercent ( x ) ) return x ;
542583 return this . length2em ( x ) ;
543584 } ) ;
544585 }
@@ -558,7 +599,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
558599 const x = swidths [ i ] ;
559600 if ( x === 'fit' ) return null ;
560601 if ( x === 'auto' ) return ( hasFit ? W [ i ] : null ) ;
561- if ( x . match ( / % $ / ) ) return x ;
602+ if ( isPercent ( x ) ) return x ;
562603 return this . length2em ( x ) ;
563604 } ) ;
564605 }
@@ -583,7 +624,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
583624 // separation and lines have been removed (cwidth), and
584625 // after the width of the columns have been removed (dw).
585626 //
586- const cwidth = width - [ ] . concat ( this . cLines , this . cSpace ) . reduce ( ( a , b ) => a + b , 0 ) - 2 * this . fSpace [ 0 ] ;
627+ const cwidth = width - SUM ( [ ] . concat ( this . cLines , this . cSpace ) ) - 2 * this . fSpace [ 0 ] ;
587628 let dw = cwidth ;
588629 indices . forEach ( i => {
589630 const x = swidths [ i ] ;
0 commit comments