Skip to content
This repository has been archived by the owner on May 27, 2021. It is now read-only.

Commit

Permalink
Updated packages
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielOaks committed Dec 26, 2017
1 parent efe484a commit 9cd8d1a
Show file tree
Hide file tree
Showing 379 changed files with 158,484 additions and 32,400 deletions.
26 changes: 16 additions & 10 deletions github.com/goshuirc/irc-go/ircfmt/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ and such.
The escape character we use in this library is the dollar sign ("$"), along
with the given escape characters:
----------------------------
Name | Escape | Raw
----------------------------
Dollarsign | $$ | $
Bold | $b | 0x02
Colour | $c | 0x03
Italic | $i | 0x1d
Underscore | $u | 0x1f
Reset | $r | 0x0f
----------------------------
-------------------------------
Name | Escape | Raw
-------------------------------
Dollarsign | $$ | $
Bold | $b | 0x02
Colour | $c | 0x03
Monospace | $m | 0x11
Italic | $i | 0x1d
Strikethrough | $s | 0x1e
Underscore | $u | 0x1f
Reset | $r | 0x0f
-------------------------------
Colours are escaped in a slightly different way, using the actual names of them
rather than just the raw numbers.
Expand Down Expand Up @@ -74,6 +76,10 @@ Here are the colour names and codes we recognise:
13 | pink
14 | grey
15 | light grey
99 | default
--------------------
These other colours aren't given names:
https://modern.ircdocs.horse/formatting.html#colors-16-98
*/
package ircfmt
266 changes: 134 additions & 132 deletions github.com/goshuirc/irc-go/ircfmt/ircfmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,60 +9,65 @@ import (

const (
// raw bytes and strings to do replacing with
bold string = "\x02"
colour string = "\x03"
italic string = "\x1d"
underline string = "\x1f"
reset string = "\x0f"
bold string = "\x02"
colour string = "\x03"
monospace string = "\x11"
italic string = "\x1d"
strikethrough string = "\x1e"
underline string = "\x1f"
reset string = "\x0f"

runecolour rune = '\x03'

// valid characters for an initial colour code, for speed
// valid characters in a colour code character, for speed
colours1 string = "0123456789"
)

var (
// valtoescape replaces most of IRC characters with our escapes.
// colour is not replaced here because of what we need to do involving colour names.
valtoescape = strings.NewReplacer("$", "$$", bold, "$b", italic, "$i", underline, "$u", reset, "$r")
valtoescape = strings.NewReplacer("$", "$$", colour, "$c", bold, "$b", italic, "$i", strikethrough, "$s", underline, "$u", monospace, "$m", reset, "$r")

// escapetoval contains most of our escapes and how they map to real IRC characters.
escapetoval = map[byte]string{
// intentionally skips colour, since that's handled elsewhere.
escapetoval = map[rune]string{
'$': "$",
'b': bold,
'i': italic,
's': strikethrough,
'u': underline,
'm': monospace,
'r': reset,
}

// valid colour codes
numtocolour = [][]string{
{"15", "light grey"},
{"14", "grey"},
{"13", "pink"},
{"12", "light blue"},
{"11", "light cyan"},
{"10", "cyan"},
{"09", "light green"},
{"08", "yellow"},
{"07", "orange"},
{"06", "magenta"},
{"05", "brown"},
{"04", "red"},
{"03", "green"},
{"02", "blue"},
{"01", "black"},
{"00", "white"},
{"9", "light green"},
{"8", "yellow"},
{"7", "orange"},
{"6", "magenta"},
{"5", "brown"},
{"4", "red"},
{"3", "green"},
{"2", "blue"},
{"1", "black"},
{"0", "white"},
numtocolour = map[string]string{
"99": "default",
"15": "light grey",
"14": "grey",
"13": "pink",
"12": "light blue",
"11": "light cyan",
"10": "cyan",
"09": "light green",
"08": "yellow",
"07": "orange",
"06": "magenta",
"05": "brown",
"04": "red",
"03": "green",
"02": "blue",
"01": "black",
"00": "white",
"9": "light green",
"8": "yellow",
"7": "orange",
"6": "magenta",
"5": "brown",
"4": "red",
"3": "green",
"2": "blue",
"1": "black",
"0": "white",
}

// full and truncated colour codes
Expand All @@ -83,6 +88,7 @@ var (
"pink": "13",
"grey": "14",
"light grey": "15",
"default": "99",
}
colourcodesTruncated = map[string]string{
"white": "0",
Expand All @@ -101,6 +107,7 @@ var (
"pink": "13",
"grey": "14",
"light grey": "15",
"default": "99",
}
)

Expand All @@ -112,57 +119,53 @@ func Escape(in string) string {
// replace all our usual escapes
in = valtoescape.Replace(in)

// replace colour codes
out := ""
var skip int
for i, x := range in {
// skip chars if necessary
if 0 < skip {
skip--
continue
}

if x == runecolour {
inRunes := []rune(in)
var out string
for 0 < len(inRunes) {
if 1 < len(inRunes) && inRunes[0] == '$' && inRunes[1] == 'c' {
// handle colours
out += "$c"
i++ // to refer to color code
inRunes = inRunes[2:] // strip colour code chars

if len(in) < i+2 || !strings.Contains(colours1, string(in[i])) {
if len(inRunes) < 1 || !strings.Contains(colours1, string(inRunes[0])) {
out += "[]"
continue
}

out += "["

in = in[i:]
for _, vals := range numtocolour {
code, name := vals[0], vals[1]
if strings.HasPrefix(in, code) {
in = strings.TrimPrefix(in, code)
out += name
i = 0 // refer to char after colour code
skip += len(code)

if i+2 < len(in) && in[i] == ',' {
i++ // refer to colour code after comma
skip++
in := in[i:]
for _, vals = range numtocolour {
code, name = vals[0], vals[1]
if strings.HasPrefix(in, code) {
out += ","
out += name
skip += len(code)
break
}
}
}
break
var foreBuffer, backBuffer string
foreBuffer += string(inRunes[0])
inRunes = inRunes[1:]
if 0 < len(inRunes) && strings.Contains(colours1, string(inRunes[0])) {
foreBuffer += string(inRunes[0])
inRunes = inRunes[1:]
}
if 1 < len(inRunes) && inRunes[0] == ',' && strings.Contains(colours1, string(inRunes[1])) {
backBuffer += string(inRunes[1])
inRunes = inRunes[2:]
if 0 < len(inRunes) && strings.Contains(colours1, string(inRunes[0])) {
backBuffer += string(inRunes[0])
inRunes = inRunes[1:]
}
}

foreName, exists := numtocolour[foreBuffer]
if !exists {
foreName = foreBuffer
}
backName, exists := numtocolour[backBuffer]
if !exists {
backName = backBuffer
}

out += "[" + foreName
if backName != "" {
out += "," + backName
}
out += "]"

} else {
out += string(x)
out += string(inRunes[0])
inRunes = inRunes[1:]
}
}

Expand All @@ -176,80 +179,79 @@ func Escape(in string) string {
func Unescape(in string) string {
out := ""

var skip int
for i, x := range in {
// skip if necessary
if 0 < skip {
skip--
continue
}
remaining := []rune(in)
for 0 < len(remaining) {
char := remaining[0]
remaining = remaining[1:]

if char == '$' && 0 < len(remaining) {
char = remaining[0]
remaining = remaining[1:]

// chars exist and formatting code thrown our way
i++ // to now refer to the formatting code character
if x == '$' && 0 < len(in)-i {
val, exists := escapetoval[in[i]]
if exists == true {
skip++ // to skip the formatting code character
val, exists := escapetoval[char]
if exists {
out += val
} else if in[i] == 'c' {
skip++ // to skip the formatting code character
} else if char == 'c' {
out += colour

// ensure '[' follows before doing further processing
i++ // refer to the opening bracket
if (len(in)-i) < 1 || in[i] != '[' {
if len(remaining) < 2 || remaining[0] != '[' {
continue
} else {
// strip leading '['
skip++
}

var buffer string
var colournames []string
for j, y := range in {
// get to color names and all
if j <= i {
continue
}
// get colour names
var coloursBuffer string
remaining = remaining[1:]
for remaining[0] != ']' {
coloursBuffer += string(remaining[0])
remaining = remaining[1:]
}
remaining = remaining[1:] // strip final ']'

// skip this character in the real loop as well
skip++
// so we can refer to the char after the loop as well
i = j
colours := strings.Split(coloursBuffer, ",")
var foreColour, backColour string
foreColour = colours[0]
if 1 < len(colours) {
backColour = colours[1]
}

// record color names
if y == ']' {
i++
break
} else if y == ',' {
colournames = append(colournames, buffer)
buffer = ""
} else {
buffer += string(y)
}
// decide whether we can use truncated colour codes
canUseTruncated := len(remaining) < 1 || !strings.Contains(colours1, string(remaining[0]))

// turn colour names into real codes
var foreColourCode, backColourCode string
var exists bool

if backColour != "" || canUseTruncated {
foreColourCode, exists = colourcodesTruncated[foreColour]
} else {
foreColourCode, exists = colourcodesFull[foreColour]
}
if exists {
foreColour = foreColourCode
}
colournames = append(colournames, buffer)

if len(colournames) > 1 {
out += colourcodesTruncated[colournames[0]]
out += ","
if i < len(in) && strings.Contains(colours1, string(in[i])) {
out += colourcodesFull[colournames[1]]
if backColour != "" {
if canUseTruncated {
backColourCode, exists = colourcodesTruncated[backColour]
} else {
out += colourcodesTruncated[colournames[1]]
backColourCode, exists = colourcodesFull[backColour]
}
} else {
if i < len(in) && strings.Contains(colours1, string(in[i])) {
out += colourcodesFull[colournames[0]]
} else {
out += colourcodesTruncated[colournames[0]]
if exists {
backColour = backColourCode
}
}

// output colour codes
out += foreColour
if backColour != "" {
out += "," + backColour
}
} else {
// unknown formatting character, intentionally fall-through
// unknown char
out += string(char)
}
} else {
out += string(x)
out += string(char)
}
}

Expand Down
3 changes: 2 additions & 1 deletion github.com/goshuirc/irc-go/ircfmt/ircfmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ var escapetests = []testcase{
}

var unescapetests = []testcase{
{"te$st", "test"},
{"te$xt", "text"},
{"te$st", "te\x1et"},
{"test$c", "test\x03"},
}

Expand Down

0 comments on commit 9cd8d1a

Please sign in to comment.