Skip to content

Commit b36e9fd

Browse files
committed
Tables without headers.
1 parent 38c474a commit b36e9fd

7 files changed

+208
-66
lines changed

data.go

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2020 Markku Rossi
2+
// Copyright (c) 2020-2021 Markku Rossi
33
//
44
// All rights reserved.
55
//
@@ -14,7 +14,7 @@ import (
1414
var (
1515
_ = Data((&Value{}))
1616
_ = Data((&Lines{}))
17-
_ = Data((&Array{}))
17+
_ = Data((&Slice{}))
1818
)
1919

2020
// Data contains table cell data.
@@ -117,27 +117,27 @@ func (lines *Lines) String() string {
117117
return strings.Join(lines.Lines, "\n")
118118
}
119119

120-
// NewArray creates a new Array Data type with the specified maximum
120+
// NewSlice creates a new Slice Data type with the specified maximum
121121
// rendering width.
122-
func NewArray(maxWidth int) *Array {
123-
return &Array{
122+
func NewSlice(maxWidth int) *Slice {
123+
return &Slice{
124124
maxWidth: maxWidth,
125125
}
126126
}
127127

128-
// Array implements the Data interface for an array of Data elements.
129-
type Array struct {
128+
// Slice implements the Data interface for an array of Data elements.
129+
type Slice struct {
130130
maxWidth int
131131
height int
132132
content []Data
133133
lines []string
134134
}
135135

136-
func (arr *Array) addLine(line string) {
136+
func (arr *Slice) addLine(line string) {
137137
arr.lines = append(arr.lines, line)
138138
}
139139

140-
func (arr *Array) layout() {
140+
func (arr *Slice) layout() {
141141
if len(arr.lines) > 0 {
142142
return
143143
}
@@ -174,12 +174,12 @@ func (arr *Array) layout() {
174174
}
175175

176176
// Append adds data to the array.
177-
func (arr *Array) Append(data Data) {
177+
func (arr *Slice) Append(data Data) {
178178
arr.content = append(arr.content, data)
179179
}
180180

181181
// Width implements the Data.Width().
182-
func (arr *Array) Width(m Measure) int {
182+
func (arr *Slice) Width(m Measure) int {
183183
arr.layout()
184184

185185
var max int
@@ -193,20 +193,20 @@ func (arr *Array) Width(m Measure) int {
193193
}
194194

195195
// Height implements the Data.Height().
196-
func (arr *Array) Height() int {
196+
func (arr *Slice) Height() int {
197197
arr.layout()
198198
return len(arr.lines)
199199
}
200200

201201
// Content implements the Data.Content().
202-
func (arr *Array) Content(row int) string {
202+
func (arr *Slice) Content(row int) string {
203203
if row < len(arr.lines) {
204204
return arr.lines[row]
205205
}
206206
return ""
207207
}
208208

209-
func (arr *Array) String() string {
209+
func (arr *Slice) String() string {
210210
result := "["
211211
for idx, c := range arr.content {
212212
if idx > 0 {

example_test.go

+43-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2020 Markku Rossi
2+
// Copyright (c) 2020-2021 Markku Rossi
33
//
44
// All rights reserved.
55
//
@@ -122,7 +122,7 @@ func ExampleReflect() {
122122
tab := New(ASCII)
123123
tab.Header("Key").SetAlign(ML)
124124
tab.Header("Value")
125-
err := Reflect(tab, 0, nil, &Book{
125+
err := Reflect(tab, InheritHeaders, nil, &Book{
126126
Title: "Structure and Interpretation of Computer Programs",
127127
Author: []Person{
128128
{
@@ -166,6 +166,47 @@ func ExampleReflect() {
166166
// +-----------+---------------------------------------------------+
167167
}
168168

169+
func ExampleArray() {
170+
tab, err := Array(New(ASCII), [][]interface{}{
171+
{"a", "b", "c"},
172+
{"1", "2", "3"},
173+
})
174+
if err != nil {
175+
log.Fatal(err)
176+
}
177+
tab.Print(os.Stdout)
178+
// Output: +---+---+---+
179+
// | a | b | c |
180+
// +---+---+---+
181+
// | 1 | 2 | 3 |
182+
// +---+---+---+
183+
}
184+
185+
func ExampleArray_second() {
186+
tab, err := Array(New(Unicode), [][]interface{}{
187+
{"int", "float", "struct"},
188+
{42, 3.14, struct {
189+
ival int
190+
strval string
191+
}{
192+
ival: 42,
193+
strval: "Hello, world!",
194+
}},
195+
})
196+
if err != nil {
197+
log.Fatal(err)
198+
}
199+
tab.Print(os.Stdout)
200+
// Output: ┏━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
201+
// ┃ int ┃ float ┃ struct ┃
202+
// ┡━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
203+
// │ 42 │ 3.14 │ ┌────────┬───────────────┐ │
204+
// │ │ │ │ ival │ 42 │ │
205+
// │ │ │ │ strval │ Hello, world! │ │
206+
// │ │ │ └────────┴───────────────┘ │
207+
// └─────┴───────┴────────────────────────────┘
208+
}
209+
169210
func ExampleTabulate_MarshalJSON() {
170211
tab := New(Unicode)
171212
tab.Header("Key").SetAlign(MR)

json.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2020 Markku Rossi
2+
// Copyright (c) 2020-2021 Markku Rossi
33
//
44
// All rights reserved.
55
//
@@ -60,7 +60,7 @@ func (v *Value) marshalJSON() (interface{}, error) {
6060
return v.value, nil
6161
}
6262

63-
func (arr *Array) marshalJSON() (interface{}, error) {
63+
func (arr *Slice) marshalJSON() (interface{}, error) {
6464
var content []interface{}
6565

6666
for _, data := range arr.content {

reflect.go

+45-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2020 Markku Rossi
2+
// Copyright (c) 2020-2021 Markku Rossi
33
//
44
// All rights reserved.
55
//
@@ -21,6 +21,7 @@ type Flags int
2121
// Flag values for reflection tabulation.
2222
const (
2323
OmitEmpty Flags = 1 << iota
24+
InheritHeaders
2425
)
2526

2627
const nilLabel = "<nil>"
@@ -63,6 +64,39 @@ func Reflect(tab *Tabulate, flags Flags, tags []string, v interface{}) error {
6364
return nil
6465
}
6566

67+
// Array tabulates the argument v into rows and columns. If the tab
68+
// defines header columns, those will be used. Otherwise the first row
69+
// of v defines the header columns.
70+
func Array(tab *Tabulate, v [][]interface{}) (*Tabulate, error) {
71+
flags := OmitEmpty
72+
tags := make(map[string]bool)
73+
74+
if len(tab.Headers) == 0 {
75+
if len(v) == 0 {
76+
return tab, nil
77+
}
78+
for _, c := range v[0] {
79+
data, err := reflectValue(tab, flags, tags, reflect.ValueOf(c))
80+
if err != nil {
81+
return nil, err
82+
}
83+
tab.HeaderData(data)
84+
}
85+
v = v[1:]
86+
}
87+
for _, r := range v {
88+
row := tab.Row()
89+
for _, c := range r {
90+
data, err := reflectValue(tab, flags, tags, reflect.ValueOf(c))
91+
if err != nil {
92+
return nil, err
93+
}
94+
row.ColumnData(data)
95+
}
96+
}
97+
return tab, nil
98+
}
99+
66100
func reflectValue(tab *Tabulate, flags Flags, tags map[string]bool,
67101
value reflect.Value) (Data, error) {
68102

@@ -115,6 +149,9 @@ func reflectValue(tab *Tabulate, flags Flags, tags map[string]bool,
115149
case reflect.Map:
116150
if value.Len() > 0 || flags&OmitEmpty == 0 {
117151
sub := tab.Clone()
152+
if flags&InheritHeaders == 0 {
153+
sub.Headers = nil
154+
}
118155
err := reflectMap(sub, flags, tags, value)
119156
if err != nil {
120157
return nil, err
@@ -143,6 +180,9 @@ func reflectValue(tab *Tabulate, flags Flags, tags map[string]bool,
143180

144181
case reflect.Struct:
145182
sub := tab.Clone()
183+
if flags&InheritHeaders == 0 {
184+
sub.Headers = nil
185+
}
146186
err := reflectStruct(sub, flags, tags, value)
147187
if err != nil {
148188
return nil, err
@@ -182,7 +222,7 @@ func reflectByteSliceValue(tab *Tabulate, flags Flags, tags map[string]bool,
182222
func reflectSliceValue(tab *Tabulate, flags Flags, tags map[string]bool,
183223
width int, value reflect.Value) (Data, error) {
184224

185-
data := NewArray(width)
225+
data := NewSlice(width)
186226
loop:
187227
for i := 0; i < value.Len(); i++ {
188228
v := value.Index(i)
@@ -199,6 +239,9 @@ loop:
199239
switch v.Type().Kind() {
200240
case reflect.Struct:
201241
sub := tab.Clone()
242+
if flags&InheritHeaders == 0 {
243+
sub.Headers = nil
244+
}
202245
err := reflectStruct(sub, flags, tags, v)
203246
if err != nil {
204247
return nil, err

reflect_test.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2020 Markku Rossi
2+
// Copyright (c) 2020-2021 Markku Rossi
33
//
44
// All rights reserved.
55
//
@@ -185,3 +185,15 @@ func TestReflectTextMarshaler(t *testing.T) {
185185
t.Fatalf("Reflect failed: %s", err)
186186
}
187187
}
188+
189+
func TestReflectArray(t *testing.T) {
190+
fmt.Printf("TestReflectArray\n")
191+
tab, err := Array(New(ASCII), [][]interface{}{
192+
{"a", "b", "c"},
193+
{"1", "2", "3"},
194+
})
195+
if err != nil {
196+
t.Fatalf("Array failed: %s", err)
197+
}
198+
tab.Print(os.Stdout)
199+
}

0 commit comments

Comments
 (0)