You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
4.8 KiB
250 lines
4.8 KiB
// ------------------------------------------------------------------------
|
|
// Project active2
|
|
// Active Thing (activething.com) git.activething.com/go
|
|
//
|
|
// File n code.go
|
|
// Created by DEV
|
|
// Modified 06/04/2024
|
|
//
|
|
// Copyright 2024 activething.com
|
|
// ------------------------------------------------------------------------
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// ------------------------------------------------------------------------
|
|
|
|
package ansi
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type (
|
|
|
|
Code uint16
|
|
)
|
|
|
|
|
|
func (c Code) Atts () string {
|
|
if c == 0 {
|
|
return ""
|
|
}
|
|
var r []string
|
|
m := c & txMask
|
|
if m != 0 {
|
|
dc := styleAttsStart
|
|
for i:=0; i<6; i++ {
|
|
if m & dc != 0 {
|
|
r = append(r,string(g.itx[i].n))
|
|
}
|
|
dc <<= 1
|
|
}
|
|
}
|
|
r = append(r,strings.Join([]string{c.FgColor().Name(),c.BgColor().Name()},":"))
|
|
return strings.Join(r,";")
|
|
}
|
|
|
|
|
|
|
|
func (c Code) Clear () Code {
|
|
return 0 }
|
|
|
|
func (c Code) ClearColor () Code {
|
|
return c & txMask }
|
|
|
|
func (c Code) ClearText () Code {
|
|
return c & clMask }
|
|
|
|
|
|
func (c Code) FgColor() Color {
|
|
return Color((c & clMask) & bgMask) }
|
|
|
|
func (c Code) SetFgColor(color Color) Code {
|
|
if !color.IsValid() {
|
|
return c
|
|
}
|
|
return (c & fgMask) | Code(color)& bgMask
|
|
}
|
|
|
|
func (c Code) ResetFgColor() Code {
|
|
return (c & fgMask) | Code(colorDefault)& bgMask }
|
|
|
|
|
|
func (c Code) BgColor() Color {
|
|
return Color(((c & clMask) & fgMask) >> bgShift) }
|
|
|
|
func (c Code) SetBgColor(color Color) Code {
|
|
if !color.IsValid() {
|
|
return c
|
|
}
|
|
return (c & bgMask) | (Code(color)<< bgShift) & fgMask
|
|
}
|
|
|
|
func (c Code) ResetBgColor() Code {
|
|
return (c & bgMask) | (Code(colorDefault)<< bgShift) & fgMask }
|
|
|
|
|
|
|
|
func (c Code) Style () Style {
|
|
return Style(c >> 10) }
|
|
|
|
|
|
func (c Code) SetStyle (sty Style) Code {
|
|
if !sty.IsValid() {
|
|
return c
|
|
}
|
|
v := Code(sty) << stShift
|
|
return ((((c & txMask) >>styleNumOps) &^ v) <<styleNumOps | v) | c & clMask
|
|
}
|
|
|
|
func (c Code) DelStyle (sty Style) Code {
|
|
if !sty.IsValid() {
|
|
return c
|
|
}
|
|
v := Code(sty) << (styleNumOps + stShift)
|
|
return ((((c & txMask) <<styleNumOps) &^ v) >>styleNumOps | v) | c & clMask
|
|
}
|
|
|
|
|
|
|
|
func (c Code) scapeStyle () []byte {
|
|
m := c & txMask
|
|
if m == 0 {
|
|
return nil
|
|
}
|
|
var r []byte
|
|
dc := styleAttsStart
|
|
for i:=0; i<6; i++ {
|
|
if m & dc != 0 {
|
|
if r != nil {
|
|
r = append(r,';')
|
|
} else {
|
|
r = append(r,'0',';')
|
|
}
|
|
r = append(r, g.itx[i].s...)
|
|
}
|
|
dc <<= 1
|
|
}
|
|
return r
|
|
}
|
|
|
|
|
|
func (c Code) scapeColor () []byte {
|
|
m := c & clMask
|
|
if m == 0 {
|
|
return nil
|
|
}
|
|
var r []byte
|
|
f := m & bgMask
|
|
b := (m & fgMask) >> bgShift
|
|
if f != 0 {
|
|
r = append(r, g.ics[f].f...)
|
|
}
|
|
if b != 0 {
|
|
if f > 0 {
|
|
r=append(r,';')
|
|
}
|
|
r = append(r, g.ics[b].b...)
|
|
}
|
|
return r
|
|
}
|
|
|
|
|
|
func (c Code) escape () []byte {
|
|
if c == 0 {
|
|
return []byte{'0'}
|
|
}
|
|
st := c.scapeStyle()
|
|
sc := c.scapeColor()
|
|
if len(sc) == 0 {
|
|
return st
|
|
}
|
|
if len(st) == 0 {
|
|
return sc
|
|
}
|
|
return append(st,append([]byte{';'},sc...)...)
|
|
}
|
|
|
|
|
|
func (c Code) stringValues() string {
|
|
return string(c.escape())
|
|
}
|
|
|
|
|
|
func (c Code) String() string {
|
|
if c == 0 {
|
|
return ""
|
|
}
|
|
r := c.escape()
|
|
return string(append(g.beginEscIni, append(r, g.beginEscEnd...)...))
|
|
}
|
|
|
|
func (_ Code) End () string {
|
|
return g.endEscStr }
|
|
|
|
|
|
|
|
|
|
|
|
func (c Code) Errorf (format string, params ...any) error {
|
|
return fmt.Errorf(c.Sprintf(format,params...)) }
|
|
|
|
func (c Code) Fprint (writer io.Writer, format string, params ...any) (n int, e error) {
|
|
return fmt.Fprint(writer,c.Sprintf(format,params...)) }
|
|
|
|
func (c Code) Fprintln (writer io.Writer, format string, params ...any) (n int, e error) {
|
|
return fmt.Fprintln(writer,c.Sprintf(format,params...)) }
|
|
|
|
func (c Code) Print (input ...any) (n int, e error) {
|
|
return fmt.Print(c.wrap(input ...)) }
|
|
|
|
func (c Code) Printf (format string, params ...any) {
|
|
fmt.Printf(c.Sprintf(format,params...)) }
|
|
|
|
|
|
func (c Code) Sprint (format string, params ...any) string {
|
|
return fmt.Sprint(c.Sprintf(format,params...))
|
|
}
|
|
|
|
func (c Code) Sprintf (format string, params ...any) string {
|
|
if len(format) == 0 && len(params) == 0 {
|
|
return ""
|
|
}
|
|
s := fmt.Sprintf(format,params...)
|
|
if c == 0 {
|
|
return s
|
|
}
|
|
return c.wrap(s)
|
|
}
|
|
|
|
func (c Code) Sprintln(format string, params ...any) string {
|
|
return fmt.Sprintln(c.Sprintf(format,params...)) }
|
|
|
|
|
|
|
|
func (c Code) wrap(str ...any) string {
|
|
b := bytes.Buffer{}
|
|
b.WriteString(c.String())
|
|
for _,s := range str {
|
|
b.WriteString(fmt.Sprint(s))
|
|
}
|
|
b.WriteString(g.endEscStr)
|
|
return b.String()
|
|
}
|
|
|