Skip to content

Commit db994db

Browse files
authored
Merge pull request #300 from olekukonko/pie
Implement MergeCells ByColumn
2 parents 34c1ba2 + 89dc7b4 commit db994db

20 files changed

Lines changed: 531 additions & 162 deletions

MIGRATION.md

Lines changed: 48 additions & 48 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ func main() {
520520
tablewriter.WithConfig(tablewriter.Config{
521521
Header: tw.CellConfig{Alignment: tw.CellAlignment{Global: tw.AlignCenter}},
522522
Row: tw.CellConfig{
523-
Formatting: tw.CellFormatting{MergeMode: tw.MergeHierarchical},
523+
Merging: tw.CellMerging{Mode: tw.MergeHierarchical},
524524
Alignment: tw.CellAlignment{Global: tw.AlignLeft},
525525
},
526526
}),
@@ -579,8 +579,8 @@ func main() {
579579
})),
580580
tablewriter.WithConfig(tablewriter.Config{
581581
Row: tw.CellConfig{
582-
Formatting: tw.CellFormatting{MergeMode: tw.MergeBoth},
583-
Alignment: tw.CellAlignment{PerColumn: []tw.Align{tw.Skip, tw.Skip, tw.AlignRight, tw.AlignLeft}},
582+
Merging: tw.CellMerging{Mode: tw.MergeBoth},
583+
Alignment: tw.CellAlignment{PerColumn: []tw.Align{tw.Skip, tw.Skip, tw.AlignRight, tw.AlignLeft}},
584584
},
585585

586586
Footer: tw.CellConfig{
@@ -806,12 +806,12 @@ func main() {
806806
tablewriter.WithRenderer(renderer.NewHTML(htmlCfg)),
807807
tablewriter.WithConfig(tablewriter.Config{
808808
Header: tw.CellConfig{
809-
Formatting: tw.CellFormatting{MergeMode: tw.MergeHorizontal}, // Merge identical header cells
810-
Alignment: tw.CellAlignment{Global: tw.AlignCenter},
809+
Merging: tw.CellMerging{Mode: tw.MergeHorizontal}, // Merge identical header cells
810+
Alignment: tw.CellAlignment{Global: tw.AlignCenter},
811811
},
812812
Row: tw.CellConfig{
813-
Formatting: tw.CellFormatting{MergeMode: tw.MergeHorizontal}, // Merge identical row cells
814-
Alignment: tw.CellAlignment{Global: tw.AlignLeft},
813+
Merging: tw.CellMerging{Mode: tw.MergeHorizontal}, // Merge identical row cells
814+
Alignment: tw.CellAlignment{Global: tw.AlignLeft},
815815
},
816816
Footer: tw.CellConfig{Alignment: tw.CellAlignment{Global: tw.AlignRight}},
817817
}),

_example/symbols/main.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ func main() {
2121

2222
cnf := tablewriter.Config{
2323
Header: tw.CellConfig{
24-
Formatting: tw.CellFormatting{Alignment: tw.AlignCenter},
24+
Alignment: tw.CellAlignment{Global: tw.AlignCenter},
2525
},
2626
Row: tw.CellConfig{
27-
Formatting: tw.CellFormatting{
28-
MergeMode: tw.MergeHierarchical,
29-
Alignment: tw.AlignLeft,
30-
},
27+
Merging: tw.CellMerging{Mode: tw.MergeHierarchical},
28+
Alignment: tw.CellAlignment{Global: tw.AlignLeft},
3129
},
3230
Debug: false,
3331
}

config.go

Lines changed: 138 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,12 @@ func (b *ConfigBuilder) WithFooterMaxWidth(maxWidth int) *ConfigBuilder {
135135
return b
136136
}
137137

138-
// WithFooterMergeMode sets the merge behavior for footer cells (e.g., horizontal, hierarchical).
139-
// Invalid merge modes are ignored.
138+
// Deprecated: Use .Footer().CellMerging().WithMode(...) instead. This method will be removed in a future version.
140139
func (b *ConfigBuilder) WithFooterMergeMode(mergeMode int) *ConfigBuilder {
141140
if mergeMode < tw.MergeNone || mergeMode > tw.MergeHierarchical {
142141
return b
143142
}
143+
b.config.Footer.Merging.Mode = mergeMode
144144
b.config.Footer.Formatting.MergeMode = mergeMode
145145
return b
146146
}
@@ -187,12 +187,12 @@ func (b *ConfigBuilder) WithHeaderMaxWidth(maxWidth int) *ConfigBuilder {
187187
return b
188188
}
189189

190-
// WithHeaderMergeMode sets the merge behavior for header cells (e.g., horizontal, vertical).
191-
// Invalid merge modes are ignored.
190+
// Deprecated: Use .Header().CellMerging().WithMode(...) instead. This method will be removed in a future version.
192191
func (b *ConfigBuilder) WithHeaderMergeMode(mergeMode int) *ConfigBuilder {
193192
if mergeMode < tw.MergeNone || mergeMode > tw.MergeHierarchical {
194193
return b
195194
}
195+
b.config.Header.Merging.Mode = mergeMode
196196
b.config.Header.Formatting.MergeMode = mergeMode
197197
return b
198198
}
@@ -246,12 +246,12 @@ func (b *ConfigBuilder) WithRowMaxWidth(maxWidth int) *ConfigBuilder {
246246
return b
247247
}
248248

249-
// WithRowMergeMode sets the merge behavior for row cells (e.g., horizontal, hierarchical).
250-
// Invalid merge modes are ignored.
249+
// Deprecated: Use .Row().CellMerging().WithMode(...) instead. This method will be removed in a future version.
251250
func (b *ConfigBuilder) WithRowMergeMode(mergeMode int) *ConfigBuilder {
252251
if mergeMode < tw.MergeNone || mergeMode > tw.MergeHierarchical {
253252
return b
254253
}
254+
b.config.Row.Merging.Mode = mergeMode
255255
b.config.Row.Formatting.MergeMode = mergeMode
256256
return b
257257
}
@@ -285,6 +285,14 @@ func (h *HeaderConfigBuilder) Formatting() *HeaderFormattingBuilder {
285285
}
286286
}
287287

288+
// Merging returns a HeaderMergingBuilder for configuring cell merging.
289+
func (h *HeaderConfigBuilder) Merging() *HeaderMergingBuilder {
290+
return &HeaderMergingBuilder{
291+
parent: h,
292+
config: &h.config.Merging,
293+
}
294+
}
295+
288296
// Padding returns a HeaderPaddingBuilder for header padding
289297
func (h *HeaderConfigBuilder) Padding() *HeaderPaddingBuilder {
290298
return &HeaderPaddingBuilder{
@@ -341,6 +349,14 @@ func (r *RowConfigBuilder) Formatting() *RowFormattingBuilder {
341349
}
342350
}
343351

352+
// Merging returns a RowMergingBuilder for configuring cell merging.
353+
func (r *RowConfigBuilder) Merging() *RowMergingBuilder {
354+
return &RowMergingBuilder{
355+
parent: r,
356+
config: &r.config.Merging,
357+
}
358+
}
359+
344360
// Padding returns a RowPaddingBuilder for row padding
345361
func (r *RowConfigBuilder) Padding() *RowPaddingBuilder {
346362
return &RowPaddingBuilder{
@@ -397,6 +413,14 @@ func (f *FooterConfigBuilder) Formatting() *FooterFormattingBuilder {
397413
}
398414
}
399415

416+
// Merging returns a FooterMergingBuilder for configuring cell merging.
417+
func (f *FooterConfigBuilder) Merging() *FooterMergingBuilder {
418+
return &FooterMergingBuilder{
419+
parent: f,
420+
config: &f.config.Merging,
421+
}
422+
}
423+
400424
// Padding returns a FooterPaddingBuilder for footer padding
401425
func (f *FooterConfigBuilder) Padding() *FooterPaddingBuilder {
402426
return &FooterPaddingBuilder{
@@ -478,9 +502,10 @@ func (hf *HeaderFormattingBuilder) WithAutoWrap(autoWrap int) *HeaderFormattingB
478502
return hf
479503
}
480504

481-
// WithMergeMode sets merge mode
505+
// Deprecated: Use .CellMerging().WithMode(...) instead. This method will be removed in a future version.
482506
func (hf *HeaderFormattingBuilder) WithMergeMode(mergeMode int) *HeaderFormattingBuilder {
483507
if mergeMode >= tw.MergeNone && mergeMode <= tw.MergeHierarchical {
508+
hf.parent.config.Merging.Mode = mergeMode
484509
hf.config.MergeMode = mergeMode
485510
}
486511
return hf
@@ -512,9 +537,10 @@ func (rf *RowFormattingBuilder) WithAutoWrap(autoWrap int) *RowFormattingBuilder
512537
return rf
513538
}
514539

515-
// WithMergeMode sets merge mode
540+
// Deprecated: Use .CellMerging().WithMode(...) instead. This method will be removed in a future version.
516541
func (rf *RowFormattingBuilder) WithMergeMode(mergeMode int) *RowFormattingBuilder {
517542
if mergeMode >= tw.MergeNone && mergeMode <= tw.MergeHierarchical {
543+
rf.parent.config.Merging.Mode = mergeMode
518544
rf.config.MergeMode = mergeMode
519545
}
520546
return rf
@@ -546,14 +572,117 @@ func (ff *FooterFormattingBuilder) WithAutoWrap(autoWrap int) *FooterFormattingB
546572
return ff
547573
}
548574

549-
// WithMergeMode sets merge mode
575+
// Deprecated: Use .CellMerging().WithMode(...) instead. This method will be removed in a future version.
550576
func (ff *FooterFormattingBuilder) WithMergeMode(mergeMode int) *FooterFormattingBuilder {
551577
if mergeMode >= tw.MergeNone && mergeMode <= tw.MergeHierarchical {
578+
ff.parent.config.Merging.Mode = mergeMode
552579
ff.config.MergeMode = mergeMode
553580
}
554581
return ff
555582
}
556583

584+
// HeaderMergingBuilder configures header cell merging
585+
type HeaderMergingBuilder struct {
586+
parent *HeaderConfigBuilder
587+
config *tw.CellMerging
588+
}
589+
590+
// Build returns the parent HeaderConfigBuilder.
591+
func (hm *HeaderMergingBuilder) Build() *HeaderConfigBuilder {
592+
return hm.parent
593+
}
594+
595+
// WithMode sets the merge mode (e.g., tw.MergeHorizontal).
596+
func (hm *HeaderMergingBuilder) WithMode(mode int) *HeaderMergingBuilder {
597+
hm.config.Mode = mode
598+
// Also set the deprecated field for backward compatibility
599+
hm.parent.config.Formatting.MergeMode = mode
600+
return hm
601+
}
602+
603+
// ByColumnIndex sets specific columns to be merged by their index.
604+
// If not called, merging applies to all columns.
605+
func (hm *HeaderMergingBuilder) ByColumnIndex(indices []int) *HeaderMergingBuilder {
606+
if len(indices) == 0 {
607+
hm.config.ByColumnIndex = nil // nil means apply to all
608+
} else {
609+
mapper := tw.NewMapper[int, bool]()
610+
for _, idx := range indices {
611+
mapper.Set(idx, true)
612+
}
613+
hm.config.ByColumnIndex = mapper
614+
}
615+
return hm
616+
}
617+
618+
// RowMergingBuilder configures row cell merging
619+
type RowMergingBuilder struct {
620+
parent *RowConfigBuilder
621+
config *tw.CellMerging
622+
}
623+
624+
// Build returns the parent RowConfigBuilder.
625+
func (rm *RowMergingBuilder) Build() *RowConfigBuilder {
626+
return rm.parent
627+
}
628+
629+
// WithMode sets the merge mode (e.g., tw.MergeVertical, tw.MergeHierarchical).
630+
func (rm *RowMergingBuilder) WithMode(mode int) *RowMergingBuilder {
631+
rm.config.Mode = mode
632+
// Also set the deprecated field for backward compatibility
633+
rm.parent.config.Formatting.MergeMode = mode
634+
return rm
635+
}
636+
637+
// ByColumnIndex sets specific columns to be merged by their index.
638+
// If not called, merging applies to all columns.
639+
func (rm *RowMergingBuilder) ByColumnIndex(indices []int) *RowMergingBuilder {
640+
if len(indices) == 0 {
641+
rm.config.ByColumnIndex = nil // nil means apply to all
642+
} else {
643+
mapper := tw.NewMapper[int, bool]()
644+
for _, idx := range indices {
645+
mapper.Set(idx, true)
646+
}
647+
rm.config.ByColumnIndex = mapper
648+
}
649+
return rm
650+
}
651+
652+
// FooterMergingBuilder configures footer cell merging
653+
type FooterMergingBuilder struct {
654+
parent *FooterConfigBuilder
655+
config *tw.CellMerging
656+
}
657+
658+
// Build returns the parent FooterConfigBuilder.
659+
func (fm *FooterMergingBuilder) Build() *FooterConfigBuilder {
660+
return fm.parent
661+
}
662+
663+
// WithMode sets the merge mode (e.g., tw.MergeHorizontal).
664+
func (fm *FooterMergingBuilder) WithMode(mode int) *FooterMergingBuilder {
665+
fm.config.Mode = mode
666+
// Also set the deprecated field for backward compatibility
667+
fm.parent.config.Formatting.MergeMode = mode
668+
return fm
669+
}
670+
671+
// ByColumnIndex sets specific columns to be merged by their index.
672+
// If not called, merging applies to all columns.
673+
func (fm *FooterMergingBuilder) ByColumnIndex(indices []int) *FooterMergingBuilder {
674+
if len(indices) == 0 {
675+
fm.config.ByColumnIndex = nil // nil means apply to all
676+
} else {
677+
mapper := tw.NewMapper[int, bool]()
678+
for _, idx := range indices {
679+
mapper.Set(idx, true)
680+
}
681+
fm.config.ByColumnIndex = mapper
682+
}
683+
return fm
684+
}
685+
557686
// HeaderPaddingBuilder configures header padding
558687
type HeaderPaddingBuilder struct {
559688
parent *HeaderConfigBuilder

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/fatih/color v1.15.0
88
github.com/mattn/go-runewidth v0.0.19
99
github.com/olekukonko/errors v1.1.0
10-
github.com/olekukonko/ll v0.1.1
10+
github.com/olekukonko/ll v0.1.2
1111
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0
1212
)
1313

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5
1515
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
1616
github.com/olekukonko/ll v0.1.1 h1:9Dfeed5/Mgaxb9lHRAftLK9pVfYETvHn+If6lywVhJc=
1717
github.com/olekukonko/ll v0.1.1/go.mod h1:2dJo+hYZcJMLMbKwHEWvxCUbAOLc/CXWS9noET22Mdo=
18+
github.com/olekukonko/ll v0.1.2 h1:lkg/k/9mlsy0SxO5aC+WEpbdT5K83ddnNhAepz7TQc0=
19+
github.com/olekukonko/ll v0.1.2/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
1820
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0 h1:LiZB1h0GIcudcDci2bxbqI6DXV8bF8POAnArqvRrIyw=
1921
github.com/olekukonko/ts v0.0.0-20171002115256-78ecb04241c0/go.mod h1:F/7q8/HZz+TXjlsoZQQKVYvXTZaFH4QRa3y+j1p7MS0=
2022
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

0 commit comments

Comments
 (0)