Skip to content

Commit

Permalink
docs: improve godoc for trees and lists (#296)
Browse files Browse the repository at this point in the history
* docs(godoc): add overview

* docs(godoc): include examples in godoc

* docs(godoc): fix roman numerals example

* docs(godoc): fix tree examples

* docs(godoc): attempt to fix list Enumerator examples
  • Loading branch information
bashbunni committed May 17, 2024
1 parent e3d9cca commit 52b5089
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 43 deletions.
48 changes: 24 additions & 24 deletions list/enumerations.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const abcLen = 26

// Alphabet is the enumeration for alphabetical listing.
//
// a. Foo
// b. Bar
// c. Baz
// d. Qux.
// a. Foo
// b. Bar
// c. Baz
// d. Qux.
func Alphabet(_ Data, i int) string {
if i >= abcLen*abcLen+abcLen {
return fmt.Sprintf("%c%c%c.", 'A'+i/abcLen/abcLen-1, 'A'+(i/abcLen)%abcLen-1, 'A'+i%abcLen)
Expand All @@ -25,20 +25,20 @@ func Alphabet(_ Data, i int) string {

// Arabic is the enumeration for arabic numerals listing.
//
// 1. Foo
// 2. Bar
// 3. Baz
// 4. Qux.
// 1. Foo
// 2. Bar
// 3. Baz
// 4. Qux.
func Arabic(_ Data, i int) string {
return fmt.Sprintf("%d.", i+1)
}

// Roman is the enumeration for roman numerals listing.
//
// / I. Foo
// / II. Bar
// / III. Baz
// / IV. Qux.
// I. Foo
// II. Bar
// III. Baz
// IV. Qux.
func Roman(_ Data, i int) string {
var (
roman = []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
Expand All @@ -57,30 +57,30 @@ func Roman(_ Data, i int) string {

// Bullet is the enumeration for bullet listing.
//
// • Foo
// • Bar
// • Baz
// • Qux.
// • Foo

Check failure on line 60 in list/enumerations.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
// • Bar
// • Baz
// • Qux.
func Bullet(Data, int) string {
return "•"
}

// Asterisk is an enumeration using asterisks.
//
// * Foo
// * Bar
// * Baz
// * Qux.
// \* Foo
// \* Bar
// \* Baz
// \* Qux.
func Asterisk(Data, int) string {
return "*"
}

// Dash is an enumeration using dashes.
//
// - Foo
// - Bar
// - Baz
// - Qux.
// \- Foo
// \- Bar
// \- Baz
// \- Qux.
func Dash(Data, int) string {
return "-"
}
69 changes: 60 additions & 9 deletions list/list.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
// Package list provides an API to create printable list structures that can be
// included in any command line application. This package includes full support
// for nested lists. Here's how you do it:
//
// l := list.New(
// "A",
// "B",
// "C",
// list.New(
// "D",
// "E",
// "F",
// ).Enumerator(list.Roman),
// )
// fmt.Println(l)
//
// The list package provides built-in enumerator styles to help glamourize your
// lists. This package wraps the tree package with list-specific styling. Lists
// are fully customizable, so let your creativity flow.
package list

import (
Expand Down Expand Up @@ -28,7 +47,7 @@ func (n *List) Hidden() bool {
}

// Hide sets whether or not to hide the tree.
// This is useful for collapsing / hiding sub-tree.
// This is useful for collapsing or hiding sub-lists.
func (n *List) Hide(hide bool) *List {
n.inner.Hide(hide)
return n
Expand All @@ -53,33 +72,60 @@ func (n *List) String() string {
return n.inner.String()
}

// EnumeratorStyle implements Renderer.
// Margins and paddings should usually be set only in ItemStyle/ItemStyleFunc.
// EnumeratorStyle sets the enumeration style.
// Margins and paddings should usually be set only in ItemStyle or ItemStyleFunc.
func (n *List) EnumeratorStyle(style lipgloss.Style) *List {
n.inner.EnumeratorStyle(style)
return n
}

// EnumeratorStyleFunc implements Renderer.
// EnumeratorStyleFunc sets the enumeration style function. Use this function
// for conditional styling.
//
// Margins and paddings should usually be set only in ItemStyle/ItemStyleFunc.
//
// l := list.New().
// EnumeratorStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
// if i == 1 {
// return lipgloss.NewStyle().Foreground(hightlightColor)
// }
// return lipgloss.NewStyle().Foreground(dimColor)
// })
func (n *List) EnumeratorStyleFunc(fn StyleFunc) *List {
n.inner.EnumeratorStyleFunc(tree.StyleFunc(fn))
return n
}

// ItemStyle implements Renderer.
// ItemStyle sets the item style.
//
// l := tree.New("Duck", "Duck", "Duck", "Goose", "Duck").
// ItemStyle(lipgloss.NewStyle().Foreground(lipgloss.Color(255)))
func (n *List) ItemStyle(style lipgloss.Style) *List {
n.inner.ItemStyle(style)
return n
}

// ItemStyleFunc implements Renderer.
// ItemStyleFunc sets the item style function. Use this for conditional styling.
// For example:
//
// l := list.New().
// ItemStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
// st := baseStyle.Copy()
// if selectedIndex == i {
// return st.Foreground(hightlightColor)
// }
// return st.Foreground(dimColor)
// })
func (n *List) ItemStyleFunc(fn StyleFunc) *List {
n.inner.ItemStyleFunc(tree.StyleFunc(fn))
return n
}

// Item appends an item to a list.
// Item appends an item to a list. Lists support nesting.
//
// l := list.New().
// Item("Item 1").
// Item(list.New("Item 1.1", "Item 1.2"))
func (n *List) Item(item any) *List {
switch item := item.(type) {
case *List:
Expand All @@ -98,15 +144,20 @@ func (n *List) Items(items ...any) *List {
return n
}

// Enumerator implements Renderer.
// Enumerator sets the enumerator implementation. Lipgloss includes
// predefined enumerators including bullets, roman numerals, and more. For
// example, you can have a numbered list:
//
// list.New().
// Enumerator(Arabic)
func (n *List) Enumerator(enum Enumerator) *List {
n.inner.Enumerator(func(data tree.Data, i int) (string, string) {
return " ", enum(data, i)
})
return n
}

// New returns a new list.
// New returns a new list with a bullet enumerator.
func New(items ...any) *List {
l := &List{
inner: tree.New().Items(items...),
Expand Down
8 changes: 8 additions & 0 deletions tree/enumerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ package tree
type Enumerator func(data Data, i int) (indent string, prefix string)

// DefaultEnumerator enumerates items.
//
// root
// ├── foo
// └── bar
func DefaultEnumerator(data Data, i int) (indent, prefix string) {
if data.Length()-1 == i {
return " ", "└──"
Expand All @@ -13,6 +17,10 @@ func DefaultEnumerator(data Data, i int) (indent, prefix string) {
}

// RoundedEnumerator enumerates items.
//
// root
// ├── foo
// ╰── bar
func RoundedEnumerator(data Data, i int) (indent, prefix string) {
if data.Length()-1 == i {
return " ", "╰──"
Expand Down
77 changes: 67 additions & 10 deletions tree/tree.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
// Package tree provides an API to create printable tree-like structures that
// can be included in any command line application. It goes something like:
//
// t := tree.New().
// Root(".").
// Item("Item 1").
// Item(
// tree.New().Root("Item 2").
// Item("Item 2.1").
// Item("Item 2.2").
// Item("Item 2.3"),
// ).
// Item(
// tree.New().
// Root("Item 3").
// Item("Item 3.1").
// Item("Item 3.2"),
// )
//
// fmt.Println(t)
//
// If you're looking to create a list, you can use the list package which wraps
// the tree package with bulleted enumerations. Trees are fully customizable, so
// don't be shy, give 'em the 'ol razzle dazzle.
package tree

import (
Expand Down Expand Up @@ -53,7 +77,7 @@ func (n *Tree) Hidden() bool {
}

// Hide sets whether or not to hide the tree.
// This is useful for collapsing / hiding sub-tree.
// This is useful for collapsing or hiding sub-trees.
func (n *Tree) Hide(hide bool) *Tree {
n.hide = hide
return n
Expand Down Expand Up @@ -93,10 +117,10 @@ func (n *Tree) String() string {
//
// The resulting tree would be:
//
// ├── foo
// ├── bar
// │ └── zaz
// └── qux
// ├── foo
// ├── bar
// │ └── zaz
// └── qux
//
// You may also change the tree style using Enumerator.
func (n *Tree) Item(item any) *Tree {
Expand Down Expand Up @@ -140,6 +164,10 @@ func (n *Tree) Item(item any) *Tree {
}

// Items add multiple items to the tree.
//
// t := tree.New().
// Root("Nyx").
// Items("Qux", "Quux").
func (n *Tree) Items(items ...any) *Tree {
for _, item := range items {
n.Item(item)
Expand Down Expand Up @@ -184,14 +212,27 @@ func (n *Tree) ensureRenderer() *renderer {
}

// EnumeratorStyle sets the enumeration style.
// Margins and paddings should usually be set only in ItemStyle/ItemStyleFunc.
// Margins and paddings should usually be set only in ItemStyle or ItemStyleFunc.
//
// t := tree.New("Duck", "Duck", "Duck", "Goose", "Duck").
// EnumeratorStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("#00d787")))
func (n *Tree) EnumeratorStyle(style lipgloss.Style) *Tree {
n.ensureRenderer().style.enumeratorFunc = func(Data, int) lipgloss.Style { return style }
return n
}

// EnumeratorStyleFunc sets the enumeration style function.
// EnumeratorStyleFunc sets the enumeration style function. Use this function
// for conditional styling.
//
// Margins and paddings should usually be set only in ItemStyle/ItemStyleFunc.
//
// t := tree.New().
// EnumeratorStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
// if i == 1 {
// return lipgloss.NewStyle().Foreground(hightlightColor)
// }
// return lipgloss.NewStyle().Foreground(dimColor)
// })
func (n *Tree) EnumeratorStyleFunc(fn StyleFunc) *Tree {
if fn == nil {
fn = func(Data, int) lipgloss.Style { return lipgloss.NewStyle() }
Expand All @@ -201,12 +242,25 @@ func (n *Tree) EnumeratorStyleFunc(fn StyleFunc) *Tree {
}

// ItemStyle sets the item style.
//
// t := tree.New("Duck", "Duck", "Duck", "Goose", "Duck").
// ItemStyle(lipgloss.NewStyle().Foreground(lipgloss.Color(255)))
func (n *Tree) ItemStyle(style lipgloss.Style) *Tree {
n.ensureRenderer().style.itemFunc = func(Data, int) lipgloss.Style { return style }
return n
}

// ItemStyleFunc sets the item style function.
// ItemStyleFunc sets the item style function. Use this for conditional styling.
// For example:
//
// t := tree.New().
// ItemStyleFunc(func(_ tree.Data, i int) lipgloss.Style {
// st := baseStyle.Copy()
// if selectedIndex == i {
// return st.Foreground(hightlightColor)
// }
// return st.Foreground(dimColor)
// })
func (n *Tree) ItemStyleFunc(fn StyleFunc) *Tree {
if fn == nil {
fn = func(Data, int) lipgloss.Style { return lipgloss.NewStyle() }
Expand All @@ -215,9 +269,12 @@ func (n *Tree) ItemStyleFunc(fn StyleFunc) *Tree {
return n
}

// Enumerator sets the enumerator implementation.
// Enumerator sets the enumerator implementation. This can be used to change the way the branches indicators look.
// Lipgloss includes predefined enumerators including bullets, roman numerals, and more. For
// example, you can have a numbered list:
//
// This can be used to change the way the branches indicators look.
// tree.New().
// Enumerator(Arabic)
func (n *Tree) Enumerator(enum Enumerator) *Tree {
n.ensureRenderer().enumerator = enum
return n
Expand Down

0 comments on commit 52b5089

Please sign in to comment.