master
dev 1 year ago
parent ea49ab09da
commit 5cb73a99a9

@ -57,7 +57,7 @@ import (
// ReduceColor1 toma un color RGB y lo reduce a la mejor representación disponible
// según el soporte del terminal.
func ReduceColor(r, g, b uint8, hasTrueColor, has256Colors bool) string {
// 1. Soporte TrueColor (24 bits)
// 1. Soporte TrueFgColor (24 bits)
if hasTrueColor {
return fmt.Sprintf("\x1b[38;2;%d;%d;%dm", r, g, b)
}
@ -115,7 +115,7 @@ func ReduceColor(r, g, b uint8, hasTrueColor, has256Colors bool) string {
// ReduceColor toma un color RGB y lo reduce a la mejor representación disponible
// según el soporte del terminal.
func ReduceColor2(r, g, b uint8, hasTrueColor, has256Colors bool) string {
// 1. Soporte TrueColor (24 bits)
// 1. Soporte TrueFgColor (24 bits)
if hasTrueColor {
return fmt.Sprintf("\x1b[38;2;%d;%d;%dm", r, g, b)
}
@ -196,9 +196,9 @@ func weightedDistance(r1, g1, b1, r2, g2, b2 uint8) float64 {
func main() {
r, g, b := uint8(25), uint8(128), uint8(200)
// Caso 1: Soporte TrueColor
fmt.Printf("1- Soporte TrueColor: %sTexto de ejemplo\x1b[0m\n", ReduceColor(r, g, b, true, true))
fmt.Printf("2- Soporte TrueColor: %sTexto de ejemplo\x1b[0m\n", ReduceColor2(r, g, b, true, true))
// Caso 1: Soporte TrueFgColor
fmt.Printf("1- Soporte TrueFgColor: %sTexto de ejemplo\x1b[0m\n", ReduceColor(r, g, b, true, true))
fmt.Printf("2- Soporte TrueFgColor: %sTexto de ejemplo\x1b[0m\n", ReduceColor2(r, g, b, true, true))
// Caso 2: Soporte 256 colores
fmt.Printf("1- Soporte 256 colores: %sTexto de ejemplo\x1b[0m\n", ReduceColor(r, g, b, false, true))

@ -89,8 +89,8 @@ var (
"Fraktur",
"Proportional",
"BasicColor",
"IndexColor",
"TrueColor ",
"IndexFgColor",
"TrueFgColor ",
}

@ -64,7 +64,7 @@ const (
BColorWhite
// 8 colores brillantes
BColorBrightBlack // También conocido como GrayColor
BColorBrightBlack // También conocido como GrayFgColor
BColorBrightRed
BColorBrightGreen
BColorBrightYellow

@ -81,24 +81,43 @@ var (
{'5','3'}, // (sobrerayado)
}
digitTable = [10]byte{ '0', '1', '2', '3', '4', '5', '6', '7','8','9'}
capNames = [maxCapabilities]string {
"Bold",
"Dim",
"Italic",
"Underline",
"Blink",
"Inverse",
"Hidden",
"Strike",
"DoubleUnderline",
"Overline",
"Fraktur",
"Proportional",
"BasicColor",
"IndexFgColor",
"TrueFgColor ",
}
)
// AppendItoa convierte un uint8 a bytes usando la tabla de dígitos
func AppendItoa(buffer []byte, num uint8) []byte {
if num < 10 {
return append(buffer, digitTable[num])
return append(buffer, '0' + num)
}
if num < 100 {
return append(buffer, digitTable[num / 10],digitTable[num % 10])
return append(buffer, '0' + (num / 10), '0' + (num % 10))
}
// Números de 100 a 255
num = num % 100
return append(buffer, digitTable[num / 100],digitTable[num / 10],digitTable[num % 10])
cn := num % 100
return append(buffer, '0' + (num / 100), '0' + (cn / 10), '0' + (cn % 10))
}
/*
@ -126,19 +145,4 @@ func AppendItoa(buffer []byte, num uint8) []byte {
*/
func appendItoaOld(buffer []byte, num byte) []byte {
var (
a [3]byte
j = 2
)
for i := 0; i < 3; i, j = i+1, j-1 {
a[j] = '0' + num%10
num /= 10
if num == 0 {
break
}
}
return append(buffer, a[j:]...)
}

@ -0,0 +1,148 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto WIAWAIW
—————————————————————————————————————————————————————————————————————————————
Fichero capabilities.go
Package ansi2
Autor Juan V. Navarro juanvnl@activething.com
Creado 28/08/2025
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/wiawiaw/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | wiawiaw.com
git : g.activething.com | github.com/activething
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2025 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package ansi2
import "strings"
const (
maxCapabilities = 15
)
const (
CapStyleBold Capabilities = 1 << iota // Soporte para texto en negrita.
CapStyleDim
CapStyleItalic // Soporte para texto en cursiva.
CapStyleUnderline // Soporte para texto subrayado.
CapStyleBlink
CapStyleInverse
CapStyleHidden
CapStyleStrike
CapDoubleUnderline
CapOverline
CapFraktur
CapProportional
CapBasicColor //Capabilities = 1 << 12
Cap256Color //Capabilities = 1 << 13
CapTrueColor //Capabilities = 1 << 14
CapNone Capabilities = 0 // El terminal no soporta nada.
CapAllColor = CapBasicColor | Cap256Color | CapTrueColor
CapAllStyle = CapStyleBold | CapStyleDim | CapStyleItalic |
CapStyleUnderline | CapStyleBlink | CapStyleInverse
CapAllExtended = CapStyleHidden | CapStyleStrike| CapDoubleUnderline|
CapOverline | CapFraktur | CapProportional
CapAll = CapAllColor | CapAllStyle | CapAllExtended
)
type (
Capabilities uint16
)
// Métodos para verificar capacidades de color
func (c Capabilities) HasBasicColor () bool { return c&CapBasicColor!= 0 }
func (c Capabilities) Has256Color () bool { return c&Cap256Color != 0 }
func (c Capabilities) HasTrueColor () bool { return c&CapTrueColor != 0 }
func (c Capabilities) HasAnyColor () bool { return c&CapAllColor != 0 }
// Métodos para verificar capacidades de estilo
func (c Capabilities) HasBold () bool { return c&CapStyleBold != 0 }
func (c Capabilities) HasDim () bool { return c&CapStyleDim != 0 }
func (c Capabilities) HasItalic () bool { return c&CapStyleItalic != 0 }
func (c Capabilities) HasUnderline () bool { return c&CapStyleUnderline!= 0 }
func (c Capabilities) HasBlink () bool { return c&CapStyleBlink != 0 }
func (c Capabilities) HasInverse () bool { return c&CapStyleInverse != 0 }
func (c Capabilities) HasHidden () bool { return c&CapStyleHidden != 0 }
func (c Capabilities) HasStrike () bool { return c&CapStyleStrike != 0 }
// Métodos para capacidades extendidas
func (c Capabilities) HasDoubleUnderline() bool { return c&CapDoubleUnderline != 0 }
func (c Capabilities) HasOverline () bool { return c&CapOverline != 0 }
func (c Capabilities) HasFraktur () bool { return c&CapFraktur != 0 }
func (c Capabilities) HasProportional () bool { return c&CapProportional != 0 }
func (c Capabilities) String () string {
if c == 0 {
return ""
}
cs := make([]string, 0, maxCapabilities)
for i := 0; i < maxCapabilities; i++ {
if c&1<<i != 0 {
cs = append(cs, capNames[i])
}
}
return strings.Join(cs, "|")
}

@ -138,7 +138,7 @@ func MakeGrayColor(c uint8) Color {
return MakeIndexColor(grayScaleStartIndex + c)
}
// MakeTrueColor TrueColor RGB
// MakeTrueColor TrueFgColor RGB
func MakeTrueColor(r, g, b uint8) Color {
return (Color(r) << shiftR) | (Color(g) << shiftG) | (Color(b) << shiftB) | (Color(ColorTypeTrue) << shiftType)
}

@ -287,25 +287,25 @@ func (s Style) NoOverlined () Style { return s &^ StyleFormatOverlined }
// Métodos de conveniencia para Style (colores básicos FG)
// =========================================================
func (s Style) Black () Style { return s.Fg(BasicBlack ()) }
func (s Style) Red () Style { return s.Fg(BasicRed ()) }
func (s Style) Green () Style { return s.Fg(BasicGreen ()) }
func (s Style) Yellow () Style { return s.Fg(BasicYellow ()) }
func (s Style) Blue () Style { return s.Fg(BasicBlue ()) }
func (s Style) Magenta () Style { return s.Fg(BasicMagenta ()) }
func (s Style) Cyan () Style { return s.Fg(BasicCyan ()) }
func (s Style) White () Style { return s.Fg(BasicWhite ()) }
func (s Style) FgBlack () Style { return s.Fg(BasicBlack ()) }
func (s Style) FgRed () Style { return s.Fg(BasicRed ()) }
func (s Style) FgGreen () Style { return s.Fg(BasicGreen ()) }
func (s Style) FgYellow () Style { return s.Fg(BasicYellow ()) }
func (s Style) FgBlue () Style { return s.Fg(BasicBlue ()) }
func (s Style) FgMagenta () Style { return s.Fg(BasicMagenta ()) }
func (s Style) FgCyan () Style { return s.Fg(BasicCyan ()) }
func (s Style) FgWhite () Style { return s.Fg(BasicWhite ()) }
// Colores brillantes FG
func (s Style) BrightBlack () Style { return s.Fg(BasicBrightBlack ()) }
func (s Style) BrightRed () Style { return s.Fg(BasicBrightRed ()) }
func (s Style) BrightGreen () Style { return s.Fg(BasicBrightGreen ()) }
func (s Style) BrightYellow () Style { return s.Fg(BasicBrightYellow()) }
func (s Style) BrightBlue () Style { return s.Fg(BasicBrightBlue ()) }
func (s Style) BrightMagenta() Style { return s.Fg(BasicBrightMagenta()) }
func (s Style) BrightCyan () Style { return s.Fg(BasicBrightCyan ()) }
func (s Style) BrightWhite () Style { return s.Fg(BasicBrightWhite ()) }
func (s Style) FgBrightBlack () Style { return s.Fg(BasicBrightBlack ()) }
func (s Style) FgBrightRed () Style { return s.Fg(BasicBrightRed ()) }
func (s Style) FgBrightGreen () Style { return s.Fg(BasicBrightGreen ()) }
func (s Style) FgBrightYellow () Style { return s.Fg(BasicBrightYellow ()) }
func (s Style) FgBrightBlue () Style { return s.Fg(BasicBrightBlue ()) }
func (s Style) FgBrightMagenta() Style { return s.Fg(BasicBrightMagenta ())}
func (s Style) FgBrightCyan () Style { return s.Fg(BasicBrightCyan ()) }
func (s Style) FgBrightWhite () Style { return s.Fg(BasicBrightWhite ()) }
@ -313,25 +313,25 @@ func (s Style) BrightWhite () Style { return s.Fg(BasicBrightWhite ()) }
// Métodos de conveniencia para Style (colores básicos BG)
// =========================================================
func (s Style) BgBlack () Style { return s.Bg(BasicBlack ()) }
func (s Style) BgRed () Style { return s.Bg(BasicRed ()) }
func (s Style) BgGreen () Style { return s.Bg(BasicGreen ()) }
func (s Style) BgYellow () Style { return s.Bg(BasicYellow ()) }
func (s Style) BgBlue () Style { return s.Bg(BasicBlue ()) }
func (s Style) BgMagenta () Style { return s.Bg(BasicMagenta ()) }
func (s Style) BgCyan () Style { return s.Bg(BasicCyan ()) }
func (s Style) BgWhite () Style { return s.Bg(BasicWhite ()) }
func (s Style) BgBlack () Style { return s.Bg(BasicBlack ()) }
func (s Style) BgRed () Style { return s.Bg(BasicRed ()) }
func (s Style) BgGreen () Style { return s.Bg(BasicGreen ()) }
func (s Style) BgYellow () Style { return s.Bg(BasicYellow ()) }
func (s Style) BgBlue () Style { return s.Bg(BasicBlue ()) }
func (s Style) BgMagenta () Style { return s.Bg(BasicMagenta ()) }
func (s Style) BgCyan () Style { return s.Bg(BasicCyan ()) }
func (s Style) BgWhite () Style { return s.Bg(BasicWhite ()) }
// Colores brillantes BG
func (s Style) BgBrightBlack () Style { return s.Bg(BasicBrightBlack ()) }
func (s Style) BgBrightRed () Style { return s.Bg(BasicBrightRed ()) }
func (s Style) BgBrightGreen () Style { return s.Bg(BasicBrightGreen ()) }
func (s Style) BgBrightYellow () Style{ return s.Bg(BasicBrightYellow ()) }
func (s Style) BgBrightBlue () Style { return s.Bg(BasicBrightBlue ()) }
func (s Style) BgBrightMagenta() Style { return s.Bg(BasicBrightMagenta ()) }
func (s Style) BgBrightCyan () Style { return s.Bg(BasicBrightCyan ()) }
func (s Style) BgBrightWhite () Style { return s.Bg(BasicBrightWhite ()) }
func (s Style) BgBrightBlack () Style { return s.Bg(BasicBrightBlack ()) }
func (s Style) BgBrightRed () Style { return s.Bg(BasicBrightRed ()) }
func (s Style) BgBrightGreen () Style { return s.Bg(BasicBrightGreen ()) }
func (s Style) BgBrightYellow () Style { return s.Bg(BasicBrightYellow()) }
func (s Style) BgBrightBlue () Style { return s.Bg(BasicBrightBlue ()) }
func (s Style) BgBrightMagenta () Style { return s.Bg(BasicBrightMagenta())}
func (s Style) BgBrightCyan () Style { return s.Bg(BasicBrightCyan ()) }
func (s Style) BgBrightWhite () Style { return s.Bg(BasicBrightWhite ()) }
@ -340,33 +340,30 @@ func (s Style) BgBrightWhite () Style { return s.Bg(BasicBrightWhite ()) }
// Métodos para otros tipos de colores
// =========================================================
// Colores RGB
// Colores True Color
func (s Style) RGBColor (r, g, b uint8) Style { return s.Fg(MakeTrueColor(r, g, b)) }
func (s Style) RGBBgColor(r, g, b uint8) Style { return s.Bg(MakeTrueColor(r, g, b)) }
func (s Style) TrueFgColor(r, g, b uint8) Style { return s.Fg(MakeTrueColor(r, g, b)) }
func (s Style) TrueBgColor(r, g, b uint8) Style { return s.Bg(MakeTrueColor(r, g, b)) }
// Colores indexados
func (s Style) IndexColor (index uint8) Style { return s.Fg(MakeIndexColor(index)) }
func (s Style) IndexBgColor (index uint8) Style { return s.Bg(MakeIndexColor(index)) }
func (s Style) IndexFgColor(index uint8) Style { return s.Fg(MakeIndexColor(index)) }
func (s Style) IndexBgColor(index uint8) Style { return s.Bg(MakeIndexColor(index)) }
// Escala de grises
func (s Style) GrayColor (gray uint8) Style { return s.Fg(MakeGrayColor(gray)) }
func (s Style) GrayBgColor (gray uint8) Style { return s.Bg(MakeGrayColor(gray)) }
func (s Style) GrayFgColor(gray uint8) Style { return s.Fg(MakeGrayColor(gray)) }
func (s Style) GrayBgColor(gray uint8) Style { return s.Bg(MakeGrayColor(gray)) }
func (s Style) Build () AnsiStyle {
hsFg := s & (maskFgType) != 0
hsBg := s & (maskBgType) != 0
hsFm := s & (maskTextFormat) != 0
if !(hsFg || hsBg || hsFm) {
hsFg := s & (maskFgType)
hsBg := s & (maskBgType)
hsFm := s & (maskTextFormat)
if hsFg | hsBg | hsFm == 0{
return NoStyle
}
@ -374,7 +371,7 @@ func (s Style) Build () AnsiStyle {
bf = append(bf,ansiFormatBegin...)
hs := false
if hsFg {
if hsFg != 0 {
hs = true
switch s.GetFgColorType() {
case ColorTypeBasic:
@ -401,7 +398,7 @@ func (s Style) Build () AnsiStyle {
}
}
if hsBg {
if hsBg != 0 {
if hs {
bf = append(bf, ansiCodeSep)
} else {
@ -433,7 +430,7 @@ func (s Style) Build () AnsiStyle {
}
if hsFm {
if hsFm != 0 {
fm := s&(maskTextFormat)
for i:=0; i<numBitsFormat; i++ {
if fm & (1 << i) != 0 {
@ -475,36 +472,36 @@ func Overlined () func(Style) Style { return func(s Style) Style { return s.Over
// Helpers de colores básicos FG
func FgBlack () func(Style) Style { return func(s Style) Style { return s.Black () } }
func FgRed () func(Style) Style { return func(s Style) Style { return s.Red () } }
func FgGreen () func(Style) Style { return func(s Style) Style { return s.Green () } }
func FgYellow () func(Style) Style { return func(s Style) Style { return s.Yellow () } }
func FgBlue () func(Style) Style { return func(s Style) Style { return s.Blue () } }
func FgMagenta () func(Style) Style { return func(s Style) Style { return s.Magenta () } }
func FgCyan () func(Style) Style { return func(s Style) Style { return s.Cyan () } }
func FgWhite () func(Style) Style { return func(s Style) Style { return s.White () } }
func FgBlack () func(Style) Style { return func(s Style) Style { return s.FgBlack () } }
func FgRed () func(Style) Style { return func(s Style) Style { return s.FgRed () } }
func FgGreen () func(Style) Style { return func(s Style) Style { return s.FgGreen () } }
func FgYellow () func(Style) Style { return func(s Style) Style { return s.FgYellow () } }
func FgBlue () func(Style) Style { return func(s Style) Style { return s.FgBlue () } }
func FgMagenta () func(Style) Style { return func(s Style) Style { return s.FgMagenta () } }
func FgCyan () func(Style) Style { return func(s Style) Style { return s.FgCyan () } }
func FgWhite () func(Style) Style { return func(s Style) Style { return s.FgWhite () } }
// Helpers de colores brillantes FG
func FgBrightBlack () func(Style) Style { return func(s Style) Style { return s.BrightBlack () } }
func FgBrightRed () func(Style) Style { return func(s Style) Style { return s.BrightRed () } }
func FgBrightGreen () func(Style) Style { return func(s Style) Style { return s.BrightGreen () } }
func FgBrightYellow () func(Style) Style { return func(s Style) Style { return s.BrightYellow () } }
func FgBrightBlue () func(Style) Style { return func(s Style) Style { return s.BrightBlue () } }
func FgBrightMagenta() func(Style) Style { return func(s Style) Style { return s.BrightMagenta () } }
func FgBrightCyan () func(Style) Style { return func(s Style) Style { return s.BrightCyan () } }
func FgBrightWhite () func(Style) Style { return func(s Style) Style { return s.BrightWhite () } }
func FgBrightBlack () func(Style) Style { return func(s Style) Style { return s.FgBrightBlack () } }
func FgBrightRed () func(Style) Style { return func(s Style) Style { return s.FgBrightRed () } }
func FgBrightGreen () func(Style) Style { return func(s Style) Style { return s.FgBrightGreen () } }
func FgBrightYellow () func(Style) Style { return func(s Style) Style { return s.FgBrightYellow () } }
func FgBrightBlue () func(Style) Style { return func(s Style) Style { return s.FgBrightBlue () } }
func FgBrightMagenta() func(Style) Style { return func(s Style) Style { return s.FgBrightMagenta() } }
func FgBrightCyan () func(Style) Style { return func(s Style) Style { return s.FgBrightCyan () } }
func FgBrightWhite () func(Style) Style { return func(s Style) Style { return s.FgBrightWhite () } }
// Helpers de colores básicos BG
func BgBlack () func(Style) Style { return func(s Style) Style { return s.BgBlack () } }
func BgRed () func(Style) Style { return func(s Style) Style { return s.BgRed () } }
func BgGreen () func(Style) Style { return func(s Style) Style { return s.BgGreen () } }
func BgYellow () func(Style) Style { return func(s Style) Style { return s.BgYellow () } }
func BgBlue () func(Style) Style { return func(s Style) Style { return s.BgBlue () } }
func BgMagenta () func(Style) Style { return func(s Style) Style { return s.BgMagenta () } }
func BgCyan () func(Style) Style { return func(s Style) Style { return s.BgCyan () } }
func BgWhite () func(Style) Style { return func(s Style) Style { return s.BgWhite () } }
func BgBlack () func(Style) Style { return func(s Style) Style { return s.BgBlack () } }
func BgRed () func(Style) Style { return func(s Style) Style { return s.BgRed () } }
func BgGreen () func(Style) Style { return func(s Style) Style { return s.BgGreen () } }
func BgYellow () func(Style) Style { return func(s Style) Style { return s.BgYellow () } }
func BgBlue () func(Style) Style { return func(s Style) Style { return s.BgBlue () } }
func BgMagenta () func(Style) Style { return func(s Style) Style { return s.BgMagenta () } }
func BgCyan () func(Style) Style { return func(s Style) Style { return s.BgCyan () } }
func BgWhite () func(Style) Style { return func(s Style) Style { return s.BgWhite () } }
// Helpers de colores brillantes BG
@ -519,12 +516,12 @@ func BgBrightWhite () func(Style) Style { return func(s Style) Style { return s.
// Helpers avanzados para colores personalizados
func FgIndex(index uint8) func(Style) Style { return func(s Style) Style { return s.IndexColor (index) } }
func BgIndex(index uint8) func(Style) Style { return func(s Style) Style { return s.IndexBgColor (index) } }
func FgIndexColor(index uint8) func(Style) Style { return func(s Style) Style { return s.IndexFgColor (index) } }
func BgIndexColor(index uint8) func(Style) Style { return func(s Style) Style { return s.IndexBgColor (index) } }
func FgGray (gray uint8) func(Style) Style { return func(s Style) Style { return s.GrayColor (gray) } }
func BgGray (gray uint8) func(Style) Style { return func(s Style) Style { return s.GrayBgColor (gray) } }
func FgGrayColor(gray uint8) func(Style) Style { return func(s Style) Style { return s.GrayFgColor (gray) } }
func BgGrayColor(gray uint8) func(Style) Style { return func(s Style) Style { return s.GrayBgColor (gray) } }
func FgRGB (r, g, b uint8) func(Style) Style { return func(s Style) Style { return s.RGBColor (r, g, b) } }
func BgRGB (r, g, b uint8) func(Style) Style { return func(s Style) Style { return s.RGBBgColor (r, g, b) } }
func FgTrueColor(r, g, b uint8) func(Style) Style { return func(s Style) Style { return s.TrueFgColor (r, g, b) } }
func BgTrueColor(r, g, b uint8) func(Style) Style { return func(s Style) Style { return s.TrueBgColor (r, g, b) } }

@ -0,0 +1,147 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto WIAWAIW
—————————————————————————————————————————————————————————————————————————————
Fichero z_build_benchmark_test.go
Package ansi2
Autor Juan V. Navarro juanvnl@activething.com
Creado 28/08/2025
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/wiawiaw/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | wiawiaw.com
git : g.activething.com | github.com/activething
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2025 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package ansi2
import (
"testing"
"github.com/logrusorgru/aurora"
)
// Variable global para evitar optimizaciones del compilador
var sink2 string
// Benchmarks para Style.Build (base/ansi2) vs aurora.Value.String (Aurora)
func BenchmarkBuild(b *testing.B) {
styles := []struct {
name string
style Style
auroraValue aurora.Value
skipAurora bool // Para casos RGB no soportados por Aurora
}{
{
name: "BasicColor",
style: MakeStyle(FgRed()), // \033[31m (rojo)
auroraValue: aurora.Red(""), // aurora.Red() genera \033[31m
skipAurora: false,
},
{
name: "8BitColor",
style: MakeStyle(FgIndexColor(255)), // \033[38;5;255m
auroraValue: aurora.Index(255, ""), // aurora.Index(255) genera \033[38;5;255m
skipAurora: false,
},
{
name: "BasicColorWithBold",
style: MakeStyle(Bold(), FgRed()), // \033[1;31m
auroraValue: aurora.Red("").Bold(), // aurora.Red().Bold() genera \033[1;31m
skipAurora: false,
},
{
name: "8BitColorWithBoldUnderline",
style: MakeStyle(Bold(), Underline(), FgIndexColor(255)), // \033[1;4;38;5;255m
auroraValue: aurora.Index(255, "").Bold().Underline(), // aurora.Index(255).Bold().Underline() genera \033[1;4;38;5;255m
skipAurora: false,
},
{
name: "TrueFgColor",
style: MakeStyle(FgTrueColor(255, 128, 0)), // \033[38;2;255;128;0m
skipAurora: true, // Aurora no soporta RGB
},
{
name: "RGBColorWithBoldUnderline",
style: MakeStyle(Bold(), Underline(), FgTrueColor(255, 128, 0)), // \033[1;4;38;2;255;128;0m
skipAurora: true, // Aurora no soporta RGB
},
}
// Benchmarks para base/ansi2
for _, s := range styles {
b.Run("base/ansi2/"+s.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
sink2 = string(s.style.Build())
}
})
}
// Benchmarks para Aurora (excluyendo casos RGB)
for _, s := range styles {
if s.skipAurora {
continue
}
b.Run("aurora/"+s.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
sink2 = s.auroraValue.String()
}
})
}
}
func BenchmarkStylize(b *testing.B) {
//style := MakeStyle(Bold(), FgRed())
//style := Style(0).Bold().Red()
//auroraStyle := aurora.Red("").Bold()
text := "Hello, World!"
b.Run("base/ansi2", func(b *testing.B) {
for i := 0; i < b.N; i++ {
//_ = style.Build().Stylize(text)
_ = Style(0).Bold().Red().Build().Stylize(text)
}
})
b.Run("aurora", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = aurora.Colorize(text, aurora.GreenFg|aurora.BoldFm).String()
}
})
}

@ -0,0 +1,241 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto WIAWAIW
—————————————————————————————————————————————————————————————————————————————
Fichero z_itoa_benchmark_test.go
Package ansi2
Autor Juan V. Navarro juanvnl@activething.com
Creado 28/08/2025
—————————————————————————————————————————————————————————————————————————————
LICENSES AND TERMS OF USE
-------------------------
This software is licensed under the Elastic License v2.0 (the "License").
For full terms and additional information regarding permitted and prohibited
uses, please visit:
https://activething.com/wiawiaw/licenses
You may use, copy, modify, and redistribute this software internally within
your organization for any purpose, including research, development, and
testing, subject to the terms of this License.
You may NOT, however, use, provide, distribute, or make this software
available to any third party as part of a hosted service, SaaS offering, or
commercial product without first obtaining a commercial license from
Active Thing.
You may combine this software with other code, provided that such
combination does not circumvent the restrictions of this License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. In no event shall
the authors or copyright holders be liable for any claim, damages, or other
liability arising from the use of this software.
—————————————————————————————————————————————————————————————————————————————
Web : activething.com | wiawiaw.com
git : g.activething.com | github.com/activething
Correo : dev@activething.com
—————————————————————————————————————————————————————————————————————————————
No deseo caminar sobre el agua", dijo Siddhartha.
Que los antiguos chamanes se contenten con tales habilidades.
—— Hermann Hesse, Siddhartha
—————————————————————————————————————————————————————————————————————————————
Copyright (c) 2025 Active Thing
————————————————————————————————————————————————————————————————————————————— */
package ansi2
import (
"strconv"
"testing"
)
// Variable global para evitar optimizaciones
var globalSink []byte
var digitTable = [10]byte{ '0', '1', '2', '3', '4', '5', '6', '7','8','9'}
// AppendItoa convierte un uint8 a bytes usando la tabla de dígitos
func AppendItoaTable (buffer []byte, num uint8) []byte {
if num < 10 {
return append(buffer, digitTable[num])
}
if num < 100 {
return append(buffer, digitTable[num / 10],digitTable[num % 10])
}
// Números de 100 a 255
cn := num % 100
return append(buffer, digitTable[num / 100],digitTable[cn / 10],digitTable[cn % 10])
}
func appendItoaOld(buffer []byte, num byte) []byte {
var (
a [3]byte
j = 2
)
for i := 0; i < 3; i, j = i+1, j-1 {
a[j] = '0' + num%10
num /= 10
if num == 0 {
break
}
}
return append(buffer, a[j:]...)
}
// appendItoaStrconv (usando strconv.AppendUint)
func appendItoaStrconv(buffer []byte, num uint8) []byte {
return strconv.AppendUint(buffer, uint64(num), 10)
}
// Benchmarks sin buffer prealocado
func BenchmarkAppendItoaOld(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
globalSink = appendItoaOld(nil, num)
}
})
}
}
func BenchmarkAppendItoaTable(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
globalSink = AppendItoaTable(nil, num)
}
})
}
}
func BenchmarkAppendItoa(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
globalSink = AppendItoa(nil, num)
}
})
}
}
func BenchmarkAppendItoaStrconv(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
globalSink = appendItoaStrconv(nil, num)
}
})
}
}
// Benchmarks con buffer prealocado
func BenchmarkAppendItoaOldAllocated(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
buffer := make([]byte, 0, 4)
b.ResetTimer()
for i := 0; i < b.N; i++ {
globalSink = appendItoaOld(buffer, num)
}
})
}
}
func BenchmarkAppendItoaTableAllocated(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
buffer := make([]byte, 0, 4)
b.ResetTimer()
for i := 0; i < b.N; i++ {
globalSink = AppendItoaTable(buffer, num)
}
})
}
}
func BenchmarkAppendItoaAllocated(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
buffer := make([]byte, 0, 4)
b.ResetTimer()
for i := 0; i < b.N; i++ {
globalSink = AppendItoa(buffer, num)
}
})
}
}
func BenchmarkAppendItoaStrconvAllocated(b *testing.B) {
nums := []uint8{5, 42, 255}
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
buffer := make([]byte, 0, 4)
b.ResetTimer()
for i := 0; i < b.N; i++ {
globalSink = appendItoaStrconv(buffer, num)
}
})
}
}
/*
Benchmark results for appendItoaOld, appendItoaTable, AppendItoa, and appendItoaStrconv
--------------------------------------------------
Performed on: Intel(R) Xeon(R) Gold 6132 CPU @ 2.60GHz
Date: August 28, 2025
GOOS: windows
GOARCH: amd64
Function | Number | Iterations | Time (ns/op) | Memory (B/op) | Allocs (allocs/op)
----------------------------------|--------|--------------|--------------|---------------|-------------------
appendItoaOld | 5 | 18,987,706 | 54.43 | 8 | 1
appendItoaOld | 42 | 20,387,463 | 57.17 | 8 | 1
appendItoaOld | 255 | 17,526,307 | 67.70 | 8 | 1
appendItoaTable | 5 | 23,709,376 | 54.40 | 8 | 1
appendItoaTable | 42 | 20,149,946 | 59.88 | 8 | 1
appendItoaTable | 255 | 46,109,864 | 48.97 | 8 | 1
AppendItoa | 5 | 19,463,488 | 52.58 | 8 | 1
AppendItoa | 42 | 26,400,847 | 55.44 | 8 | 1
AppendItoa | 255 | 20,205,202 | 55.33 | 8 | 1
appendItoaStrconv | 5 | 19,726,150 | 62.46 | 8 | 1
appendItoaStrconv | 42 | 15,472,570 | 71.24 | 8 | 1
appendItoaStrconv | 255 | 20,564,776 | 63.50 | 8 | 1
appendItoaOldAllocated | 5 | 262,203,392 | 4.441 | 0 | 0
appendItoaOldAllocated | 42 | 201,631,832 | 5.861 | 0 | 0
appendItoaOldAllocated | 255 | 120,035,353 | 9.829 | 0 | 0
appendItoaTableAllocated | 5 | 778,472,636 | 1.369 | 0 | 0
appendItoaTableAllocated | 42 | 512,075,523 | 2.380 | 0 | 0
appendItoaTableAllocated | 255 | 381,060,286 | 2.982 | 0 | 0
AppendItoaAllocated | 5 | 898,060,413 | 1.229 | 0 | 0
AppendItoaAllocated | 42 | 601,781,271 | 1.749 | 0 | 0
AppendItoaAllocated | 255 | 469,761,086 | 2.410 | 0 | 0
appendItoaStrconvAllocated | 5 | 209,319,392 | 5.147 | 0 | 0
appendItoaStrconvAllocated | 42 | 203,858,691 | 5.601 | 0 | 0
appendItoaStrconvAllocated | 255 | 83,911,713 | 13.66 | 0 | 0
--------------------------------------------------
Notes:
- AppendItoaAllocated (no table, using '0' + num) is the fastest with preallocated buffer: ~10.4% faster than appendItoaTableAllocated for num=5, ~26.5% for num=42, ~19.2% for num=255.
- AppendItoa uses zero static memory, compared to 10 bytes for appendItoaTable.
- Without preallocation, times (~48–71 ns/op) are dominated by dynamic allocation (8 B/op, 1 alloc/op).
- With preallocated buffer (make([]byte, 0, 4)), all functions show 0 B/op and 0 allocs/op, and times drop to ~1.2–13.66 ns/op.
- AppendItoaAllocated shows expected time increase for num=255 (2.410 ns/op) due to additional arithmetic operations.
- Previous benchmark (~0.313 ns/op for AppendItoa) likely benefited from aggressive compiler optimizations or different environment.
*/

@ -1,7 +1,7 @@
/* ——————————————————————————————————————————————————————————————————————————
Proyecto WIAWAIW
—————————————————————————————————————————————————————————————————————————————
Fichero z_itoa_table_benchmark_test.go
Fichero z_itoa_test.go
Package ansi2
Autor Juan V. Navarro juanvnl@activething.com
Creado 28/08/2025
@ -51,29 +51,27 @@ package ansi2
import "testing"
// Benchmark para appendItoa
func BenchmarkAppendItoa(b *testing.B) {
nums := []uint8{5, 42, 255} // Casos: 1 dígito, 2 dígitos, 3 dígitos
for _, num := range nums {
b.Run("num="+string(appendItoaOld(nil, num)), func(b *testing.B) {
buffer := make([]byte, 0, 4)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = appendItoaOld(buffer, num)
}
})
func TestAppendItoa(t *testing.T) {
tests := []struct {
num uint8
expected string
}{
{0, "0"},
{5, "5"},
{9, "9"},
{10, "10"},
{42, "42"},
{99, "99"},
{100, "100"},
{123, "123"},
{255, "255"},
}
}
// Benchmark para AppendItoa
func BenchmarkAppendItoaTable(b *testing.B) {
nums := []uint8{5, 42, 255} // Casos: 1 dígito, 2 dígitos, 3 dígitos
for _, num := range nums {
b.Run("num="+string(AppendItoa(nil, num)), func(b *testing.B) {
buffer := make([]byte, 0, 4)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = AppendItoa(buffer, num)
for _, tt := range tests {
t.Run("num="+tt.expected, func(t *testing.T) {
buffer := AppendItoa([]byte{}, tt.num)
if got := string(buffer); got != tt.expected {
t.Errorf("AppendItoa(%d) = %q, want %q", tt.num, got, tt.expected)
}
})
}

@ -2,13 +2,4 @@ module base
go 1.24
require (
github.com/fatih/color v1.18.0
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
)
require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
golang.org/x/sys v0.25.0 // indirect
)
require github.com/logrusorgru/aurora v2.0.3+incompatible

@ -1,13 +1,2 @@
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=

Loading…
Cancel
Save

Powered by TurnKey Linux.