Skip to content

Commit

Permalink
Automatically set UUID in hyperlinks. Disallow setting/getting other …
Browse files Browse the repository at this point in the history
…params.
  • Loading branch information
meowgorithm committed May 30, 2024
1 parent 172cdc2 commit 3229905
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 37 deletions.
27 changes: 11 additions & 16 deletions get.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,9 @@ func (s Style) GetTransform() func(string) string {
return s.getAsTransform(transformKey)
}

func (s Style) GetHyperlink() (url string, params map[string]string) {
// GetHyperlink returns the hyperlink set on the style. If no hyperlink is set
// the empty string and nil is returned.
func (s Style) GetHyperlink() string {
return s.getAsHyperlink(hyperlinkKey)
}

Expand Down Expand Up @@ -530,25 +532,18 @@ func (s Style) getAsTransform(k propKey) func(string) string {
return s.transform
}

func (s Style) getAsHyperlink(k propKey) (string, map[string]string) {
if !s.isSet(k) || len(s.hyperlink) == 0 {
return "", nil
// getAsHyperlink returns the hyperlink URL set on the style. No other
// parameters will be returned.
func (s Style) getAsHyperlink(k propKey) string {
if !s.isSet(k) {
return ""
}

var (
url = s.hyperlink[0]
params = s.hyperlink[1:]
m map[string]string
)

if len(params) >= 2 {
m = make(map[string]string)
for i := 0; i < len(params); i += 2 {
m[params[i]] = params[i+1]
}
if len(s.hyperlink) == 0 {
return ""
}

return url, m
return s.hyperlink[0]
}

// Split a string into lines, additionally returning the size of the widest
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ go 1.18
require (
github.com/aymanbagabas/go-udiff v0.2.0
github.com/charmbracelet/x/ansi v0.1.1
github.com/hashicorp/uuid v0.0.0-20230117211644-212010c9d616
github.com/muesli/termenv v0.15.2
github.com/rivo/uniseg v0.4.7
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWp
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/x/ansi v0.1.1 h1:CGAduulr6egay/YVbGc8Hsu8deMg1xZ/bkaXTPi1JDk=
github.com/charmbracelet/x/ansi v0.1.1/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/hashicorp/uuid v0.0.0-20230117211644-212010c9d616 h1:XVHNaBfj9Dp+skr2rRHK3GdgF0m/tsCc/ClnBKrlN0k=
github.com/hashicorp/uuid v0.0.0-20230117211644-212010c9d616/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
Expand Down
46 changes: 28 additions & 18 deletions hyperlink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,42 @@ import "testing"

func TestHyperlinkGetter(t *testing.T) {
for i, tt := range []struct {
style Style
expectedURL string
expectedParams map[string]string
style Style
url string
}{
{
style: NewStyle().Hyperlink("https://charm.sh"),
expectedURL: "https://charm.sh",
expectedParams: nil,
style: NewStyle(),
url: "https://charm.sh",
},
{
style: NewStyle().Hyperlink("https://charm.sh", "id", "IDK"),
expectedURL: "https://charm.sh",
expectedParams: map[string]string{"id": "IDK"},
style: NewStyle().Bold(true),
url: "https://charm.sh/blog/",
},
} {
url, params := tt.style.GetHyperlink()
if url != tt.expectedURL {
t.Errorf("Test %d: expected URL %q, got %q", i, tt.expectedURL, url)
// Check that URL is set correctly.
s := tt.style.Hyperlink(tt.url)
url := s.GetHyperlink()
if url != tt.url {
t.Errorf("Test %d: expected URL %q, got %q", i, tt.url, url)
}
if len(params) != len(tt.expectedParams) {
t.Errorf("Test %d: expected %d params, got %d", i, len(tt.expectedParams), len(params))

if len(s.hyperlink) < 3 {
t.Errorf("Test %d: hyperlink parameters missing (we're looking for an ID)", i)
}

// slice to map
params := make(map[string]string)
for n := 1; n < len(s.hyperlink); n += 2 {
params[s.hyperlink[n]] = s.hyperlink[n+1]
}

// Check that ID is set.
id, ok := params["id"]
if !ok {
t.Errorf("Test %d: ID key missing in hyperlink data", i)
}
for k, v := range tt.expectedParams {
if params[k] != v {
t.Errorf("Test %d: expected param %q to be %q, got %q", i, k, v, params[k])
}
if id == "" {
t.Errorf("Test %d: value missing in hyperlink data", i)
}
}
}
20 changes: 17 additions & 3 deletions set.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package lipgloss

import "github.com/hashicorp/uuid"

// Set a value on the underlying rules map.
func (s *Style) set(key propKey, value interface{}) {
// We don't allow negative integers on any of our other values, so just keep
Expand Down Expand Up @@ -687,12 +689,24 @@ func (s Style) Transform(fn func(string) string) Style {
return s
}

func (s Style) Hyperlink(url string, params ...string) Style {
// Hyperlink sets a hyperlink on the style. You're responsible for setting
// a style on the on the text so that it visually identifiable as a hyperlink
// (or not).
//
// Note that hyperlinks are not available in all terminal emulators and there's
// a no way to detect if hyperlinks are supported. If hyperlinks are not
// the text will still render as normal.
//
// Hyperlinks in terminal emulators can contain an ID. This is important for
// ensuring that when long URLs are wrapped and broken apart they are still
// understood as a single hyperlink. In Lip Gloss, this ID is set
// automatically.
func (s Style) Hyperlink(url string) Style {
if url == "" {
return s
}
params = append([]string{url}, params...)
s.set(hyperlinkKey, params)

s.set(hyperlinkKey, []string{url, "id", uuid.GenerateUUID()})
return s
}

Expand Down

0 comments on commit 3229905

Please sign in to comment.