From 68560ea8622e31ee720193440144976cda78bec3 Mon Sep 17 00:00:00 2001 From: tjp Date: Mon, 8 Jan 2024 11:54:00 -0700 Subject: gopher and gemtext colors/styles --- handlers.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- main.go | 2 +- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/handlers.go b/handlers.go index 3c37086..d918fd0 100644 --- a/handlers.go +++ b/handlers.go @@ -96,7 +96,7 @@ func parseGophermapDoc(body []byte, softWrap int) (string, []Link, error) { } } width := numberWidth(links - 1) - infopad := string(bytes.Repeat([]byte{' '}, width + 3)) + infopad := string(bytes.Repeat([]byte{' '}, width+3)) i := 0 for _, item := range mapdoc { @@ -112,7 +112,7 @@ func parseGophermapDoc(body []byte, softWrap int) (string, []Link, error) { Text: item.Display, Target: fmtGopherURL(item.Type, item.Selector, item.Hostname, item.Port), }) - if _, err := b.WriteString(fmt.Sprintf("[%d]%s %s\n", i, padding(i, width), item.Display)); err != nil { + if _, err := b.WriteString(fmt.Sprintf("[%d]%s %s%s%s\n", i, padding(i, width), linkStyle, item.Display, ansiClear)); err != nil { return "", nil, err } i += 1 @@ -122,6 +122,18 @@ func parseGophermapDoc(body []byte, softWrap int) (string, []Link, error) { return b.String(), l, nil } +const ( + ansiClear = "\x1b[0m" + linkStyle = "\x1b[38;5;33m" + promptStyle = "\x1b[38;5;39m" + quoteStyle = "\x1b[38;5;208m\x1b[3m" + rawStyle = "\x1b[38;5;249m" + h1Style = "\x1b[38;5;154m\x1b[1m\x1b[4m" + h2Style = "\x1b[38;5;50m\x1b[4m" + h3Style = "\x1b[38;5;6m\x1b[4m" + listStyle = "\x1b[38;5;3m" +) + func parseGemtextDoc(body []byte, softWrap int) (string, []Link, error) { var b strings.Builder var l []Link @@ -137,11 +149,12 @@ func parseGemtextDoc(body []byte, softWrap int) (string, []Link, error) { } } width := numberWidth(links - 1) - textpad := string(bytes.Repeat([]byte{' '}, width + 3)) + textpad := string(bytes.Repeat([]byte{' '}, width+3)) i := 0 for _, item := range gemdoc { isPrompt := false + hLevel := 0 switch item.Type() { case gemtext.LineTypePrompt: isPrompt = true @@ -161,10 +174,59 @@ func parseGemtextDoc(body []byte, softWrap int) (string, []Link, error) { if len(label) == 0 { label = ll.URL() } - if _, err := b.WriteString(fmt.Sprintf("[%d]%s %s\n", i, padding(i, width), label)); err != nil { + if _, err := b.WriteString(fmt.Sprintf("[%d]%s %s%s%s\n", i, padding(i, width), linkStyle, label, ansiClear)); err != nil { return "", nil, err } i += 1 + case gemtext.LineTypeQuote: + q := item.(gemtext.QuoteLine) + for _, line := range fold(q.Body(), softWrap - 1) { + line = strings.TrimSpace(line) + if _, err := b.WriteString(textpad + "> " + quoteStyle + line + ansiClear + "\n"); err != nil { + return "", nil, err + } + } + case gemtext.LineTypePreformatToggle: + case gemtext.LineTypePreformattedText: + for _, line := range fold(item.String(), softWrap) { + if _, err := b.WriteString(textpad + rawStyle + line + ansiClear + "\n"); err != nil { + return "", nil, err + } + } + case gemtext.LineTypeHeading3: + hLevel += 1 + fallthrough + case gemtext.LineTypeHeading2: + hLevel += 1 + fallthrough + case gemtext.LineTypeHeading1: + hLevel += 1 + var color string + switch hLevel { + case 1: + color = h1Style + case 2: + color = h2Style + case 3: + color = h3Style + } + + for _, line := range fold(item.String(), softWrap) { + if _, err := b.WriteString(textpad + color + line + ansiClear + "\n"); err != nil { + return "", nil, err + } + } + case gemtext.LineTypeListItem: + li := item.(gemtext.ListItemLine) + for i, line := range fold(li.Body(), softWrap - 2) { + lpad := " " + if i == 0 { + lpad = "* " + } + if _, err := b.WriteString(textpad + listStyle + lpad + line + ansiClear + "\n"); err != nil { + return "", nil, err + } + } default: for _, line := range fold(item.String(), softWrap) { if _, err := b.WriteString(textpad + line + "\n"); err != nil { @@ -235,5 +297,5 @@ func numberWidth(i int) int { } func padding(num int, width int) string { - return string(bytes.Repeat([]byte{' '}, width - numberWidth(num))) + return string(bytes.Repeat([]byte{' '}, width-numberWidth(num))) } diff --git a/main.go b/main.go index fd3803e..0c1e7da 100644 --- a/main.go +++ b/main.go @@ -71,7 +71,7 @@ func main() { } } -const Prompt = "\x1b[38;5;39mX-1\x1b[0m> " +const Prompt = promptStyle + "X-1" + ansiClear + "> " func writeError(msg string) { fmt.Fprintf(os.Stdout, "\x1b[31m%s\x1b[0m\n", msg) -- cgit v1.2.3