@@ -3,6 +3,7 @@ package ansitags
33import (
44 "bufio"
55 "bytes"
6+ "fmt"
67 "io"
78 "os"
89 "strconv"
@@ -15,18 +16,19 @@ type parseMode uint8
1516type ParseBehavior uint8
1617
1718const (
18- tagStart byte = '<'
19- tagEnd byte = '>'
20-
21- tagOpen string = "ansi" // will be wrapped in tagStart and tagEnd
22- tagClose string = "/ansi" // will be wrapped in tagStart and tagEnd
23-
2419 parseModeNone parseMode = 0
2520 parseModeMatching parseMode = 1
2621
2722 StripTags ParseBehavior = iota // remove all valid ansitags
2823 Monochrome // ignore any color changing properties
24+ )
2925
26+ var (
27+ tagStart byte = '<'
28+ tagEnd byte = '>'
29+
30+ tagOpen string = "ansi" // will be wrapped in tagStart and tagEnd
31+ tagClose string = "/ansi" // will be wrapped in tagStart and tagEnd
3032)
3133
3234func Parse (str string , behaviors ... ParseBehavior ) string {
@@ -42,6 +44,9 @@ func Parse(str string, behaviors ...ParseBehavior) string {
4244
4345func ParseStreaming (inbound * bufio.Reader , outbound * bufio.Writer , behaviors ... ParseBehavior ) {
4446
47+ rwLock .RLock ()
48+ defer rwLock .RUnlock ()
49+
4550 var stripAllTags bool = false
4651 var stripAllColor bool = false
4752
@@ -64,13 +69,13 @@ func ParseStreaming(inbound *bufio.Reader, outbound *bufio.Writer, behaviors ...
6469
6570 for {
6671 input , err := inbound .ReadByte ()
72+
6773 if err != nil && err == io .EOF {
6874 break
6975 }
7076
7177 // If not currently in any modes, look for any tags
7278 if mode == parseModeNone {
73-
7479 if input != tagStart {
7580 // If it's not an opening tag and we're looking for it (zero position)
7681 // Write it to the output string and go to next
@@ -89,6 +94,7 @@ func ParseStreaming(inbound *bufio.Reader, outbound *bufio.Writer, behaviors ...
8994 closeMatch , closeMatchDone := closeMatcher .MatchNext (input )
9095
9196 if openMatch {
97+
9298 currentTagBuilder .WriteByte (input )
9399
94100 if ! openMatchDone {
@@ -161,6 +167,10 @@ func ParseStreaming(inbound *bufio.Reader, outbound *bufio.Writer, behaviors ...
161167 // No close match was found. Reset the matcher
162168 closeMatcher .Reset ()
163169
170+ if closeMatchDone && openMatchDone {
171+ currentTagBuilder .WriteByte (input )
172+ }
173+
164174 // open and close both failed to match. Reset everything
165175 mode = parseModeNone
166176
@@ -188,57 +198,115 @@ func ParseStreaming(inbound *bufio.Reader, outbound *bufio.Writer, behaviors ...
188198 outbound .Flush ()
189199}
190200
191- func LoadAliases ( yamlFilePath string ) error {
201+ func SetAlias ( alias string , value int , aliasGroup ... string ) error {
192202
193- data := make (map [string ]map [string ]string , 100 )
203+ rwLock .Lock ()
204+ defer rwLock .Unlock ()
205+
206+ if value < 0 || value > 255 {
207+ return fmt .Errorf (`value "%d" out of allowable range for alias "%s"` , value , alias )
208+ }
194209
195- if yfile , err := os .ReadFile (yamlFilePath ); err != nil {
196- return err
210+ g := `color256`
211+ if len (aliasGroup ) > 0 {
212+ if aliasGroup [0 ] == `color8` {
213+ g = `color8`
214+ }
215+ }
216+
217+ if g == "color8" {
218+ colorMap8 [alias ] = value
197219 } else {
198- if err := yaml .Unmarshal (yfile , & data ); err != nil {
199- return err
220+ colorMap256 [alias ] = value
221+ }
222+
223+ return nil
224+ }
225+
226+ func SetAliases (aliases map [string ]int , aliasGroup ... string ) error {
227+
228+ rwLock .Lock ()
229+ defer rwLock .Unlock ()
230+
231+ g := `color256`
232+ if len (aliasGroup ) > 0 {
233+ if aliasGroup [0 ] == `color8` {
234+ g = `color8`
200235 }
201236 }
202237
203- for aliasGroup , aliases := range data {
204-
205- if aliasGroup == "color8" {
206- for alias , real := range aliases {
207- // try mapping to an existing color alias
208- if val , ok := colorMap8 [real ]; ok {
209- colorMap8 [alias ] = val
210- } else {
211- // allow a numeric mapping
212- if numVal , err := strconv .Atoi (real ); err == nil {
213- colorMap8 [alias ] = numVal
238+ for alias , value := range aliases {
239+ if value < 0 || value > 255 {
240+ return fmt .Errorf (`value "%d" out of allowable range for alias "%s"` , value , alias )
241+ }
242+
243+ if g == "color8" {
244+ colorMap8 [alias ] = value
245+ } else {
246+ colorMap256 [alias ] = value
247+ }
248+ }
249+
250+ return nil
251+ }
252+
253+ func LoadAliases (yamlFilePaths ... string ) error {
254+
255+ rwLock .Lock ()
256+ defer rwLock .Unlock ()
257+
258+ data := make (map [string ]map [string ]string , 100 )
259+
260+ for _ , yamlFilePath := range yamlFilePaths {
261+
262+ if yfile , err := os .ReadFile (yamlFilePath ); err != nil {
263+ return err
264+ } else {
265+ if err := yaml .Unmarshal (yfile , & data ); err != nil {
266+ return err
267+ }
268+ }
269+
270+ for aliasGroup , aliases := range data {
271+
272+ if aliasGroup == "color8" {
273+ for alias , real := range aliases {
274+ // try mapping to an existing color alias
275+ if val , ok := colorMap8 [real ]; ok {
276+ colorMap8 [alias ] = val
277+ } else {
278+ // allow a numeric mapping
279+ if numVal , err := strconv .Atoi (real ); err == nil {
280+ colorMap8 [alias ] = numVal
281+ }
214282 }
215283 }
216284 }
217- }
218285
219- if aliasGroup == "color256" {
220- for alias , real := range aliases {
221- // try mapping to an existing color alias
222- if val , ok := colorMap256 [real ]; ok {
223- colorMap256 [alias ] = val
224- } else {
225- // allow a numeric mapping
226- if numVal , err := strconv .Atoi (real ); err == nil {
227- colorMap256 [alias ] = numVal
286+ if aliasGroup == "color256" {
287+ for alias , real := range aliases {
288+ // try mapping to an existing color alias
289+ if val , ok := colorMap256 [real ]; ok {
290+ colorMap256 [alias ] = val
291+ } else {
292+ // allow a numeric mapping
293+ if numVal , err := strconv .Atoi (real ); err == nil {
294+ colorMap256 [alias ] = numVal
295+ }
228296 }
229297 }
230298 }
231- }
232299
233- if aliasGroup == "position" {
234- for alias , real := range aliases {
235- posArr := strings .Split (real , "," )
236- if len (posArr ) == 2 {
237- positionMap [alias ] = posArr
300+ if aliasGroup == "position" {
301+ for alias , real := range aliases {
302+ posArr := strings .Split (real , "," )
303+ if len (posArr ) == 2 {
304+ positionMap [alias ] = posArr
305+ }
238306 }
239307 }
240- }
241308
309+ }
242310 }
243311
244312 return nil
0 commit comments