package door import ( "log" "strings" "unicode" ) /* door.Line - Display a line of text Example: var basicLine door.Line = {Text: "Welcome", DefaultColor: door.Color("BRIGHT YELLOW"), } d.Write(basicLine.Output() + door.Reset + door.CRNL) This outputs Welcome in Bright/Bold Yellow. Example Render: var renderAlphaDigit func(string) string = func(text string) string { var r door.Render{Text: text} var alpha string = door.ColorText("BOLD YELLOW") var digit string = door.ColorText("BOLD GREEN") var other string = door.Reset for _, letter := range text { if unicode.IsAlpha(letter) { r.Append(alpha, 1) } else { if unicode.IsDigit(letter) { r.Append(digit, 1) } else { r.Append(other, 1) } } } return r.Result } var renderLine door.Line = {Text: "Render - 12345", RenderF: renderAlphaDigit, } d.Write(renderLine.Output() + door.Reset + door.CRNL) This outputs "Render" in Yellow, "12345" in Green, and " - " in White. Example Update: var updateTime() string { var now time.Time = time.Now() var result string = now.Format("3:04:05 PM") return result } var timeLine door.Line = {Text: updateTime(), UpdateF: updateTime, } d.Write(timeLine.Output() + door.CRNL) time.Sleep(time.Second) // Check timeLine for update if timeLine.Update() { // Yes, there's an update to the time, output it. d.Write(timeLine.Output() + door.CRNL) } if timeLine.Update() { // This isn't called. There were no changes. d.Write(timeLine.Output() + door.CRNL) } This outputs the Current time in 12 hour format. It pauses for a second, and outputs the new time. */ /* Line of text to display. */ type Line struct { Text string // Text to be displayed DefaultColor string // Default Color to use RenderF func(string) string // Render function (displays string with colors) UpdateF func() string // Update function updates the text Width int // Line length } /* Line Update - This calls the UpdateF if present. Returns true if the line has been updated, and there's an Update function. */ func (l *Line) Update() bool { if l.UpdateF == nil { return false } var NewText string = l.UpdateF() l.LineLength(&NewText) if NewText != l.Text { l.Text = NewText return true } return false } // If a line Width has been set, make sure we match it. func (l *Line) LineLength(text *string) { if l.Width == 0 { return } var length int = StringLen(*text) /* if Unicode { length = len([]rune(*text)) } else { length = len([]byte(*text)) } */ if length > l.Width { log.Printf("ERROR: Line Width %d: Have %d\n", l.Width, length) } else { *text += strings.Repeat(" ", l.Width-length) } } /* Line Output - returns a string with ANSI Color codes. If there is no RenderF, we use the DefaultColor. Otherwise we pass the text to RenderF and return what it returns. */ func (l *Line) Output() string { l.LineLength(&l.Text) if l.RenderF == nil { return l.DefaultColor + l.Text } else { return l.RenderF(l.Text) } } /* door.Render - Helper for Line RenderF (Render Function) Example: // RenderStatus - KEY_COLOR[key] COLON_COLOR[:] VALUE_COLOR[value] func RenderStatus(text string) string { var r door.Render = Render{Line: text} var bool inValue = false var key string = door.ColorText("BLUE") var colon string = door.ColorText("BRIGHT WHITE") var value string = door.ColorText("MAGENTA") for _, letter := range text { if letter == ':' { r.Append(colon, 1) inValue = true } else { if inValue { r.Append(value, 1) } else { r.Append(key, 1) } } } return r.Result } */ type Render struct { Line string // Original Text Result string // Output Result Pos int // Current Position LastColor string // LastColor code sent } /* Render.Append - Output len number of characters in the color. This uses Render.LastColor to tell if we've already sent that color before. */ func (r *Render) Append(color string, len int) { if color != r.LastColor { r.LastColor = color r.Result += color } if Unicode { // Treat unicode as []rune. r.Result += string([]rune(r.Line)[r.Pos : r.Pos+len]) } else { r.Result += r.Line[r.Pos : r.Pos+len] } r.Pos += len } // RenderBlueYellow - Uppercase is Bold Blue, everything else is Yellow. // This is an example of using the door.Render routines. func RenderBlueYellow(text string) string { var r Render = Render{Line: text} var blue string = ColorText("BOLD BLUE") var yellow string = ColorText("BOLD YELLOW") for _, letter := range text { if unicode.IsUpper(letter) { r.Append(blue, 1) } else { r.Append(yellow, 1) } } return r.Result }