Skip to content

Commit

Permalink
added possibility to escape formatting characters
Browse files Browse the repository at this point in the history
see #562
  • Loading branch information
bbernhard committed Dec 24, 2024
1 parent 3d51571 commit a70c299
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ func (a *Api) Send(c *gin.Context) {

// @Summary Send a signal message.
// @Tags Messages
// @Description Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: *italic text*, **bold text**, ~strikethrough text~.
// @Description Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: *italic text*, **bold text**, ~strikethrough text~. If you want to escape a character, prefix it with two backslashes ('\\')
// @Accept json
// @Produce json
// @Success 201 {object} SendMessageResponse
Expand Down
2 changes: 1 addition & 1 deletion src/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2014,7 +2014,7 @@ const docTemplate = `{
},
"/v2/send": {
"post": {
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: *italic text*, **bold text**, ~strikethrough text~.",
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: *italic text*, **bold text**, ~strikethrough text~. If you want to escape a character, prefix it with two backslashes ('\\\\')",
"consumes": [
"application/json"
],
Expand Down
2 changes: 1 addition & 1 deletion src/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2011,7 +2011,7 @@
},
"/v2/send": {
"post": {
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: *italic text*, **bold text**, ~strikethrough text~.",
"description": "Send a signal message. Set the text_mode to 'styled' in case you want to add formatting to your text message. Styling Options: *italic text*, **bold text**, ~strikethrough text~. If you want to escape a character, prefix it with two backslashes ('\\\\')",
"consumes": [
"application/json"
],
Expand Down
3 changes: 2 additions & 1 deletion src/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1754,7 +1754,8 @@ paths:
- application/json
description: 'Send a signal message. Set the text_mode to ''styled'' in case
you want to add formatting to your text message. Styling Options: *italic
text*, **bold text**, ~strikethrough text~.'
text*, **bold text**, ~strikethrough text~. If you want to escape a character,
prefix it with two backslashes (''\\'')'
parameters:
- description: Input Data
in: body
Expand Down
32 changes: 28 additions & 4 deletions src/utils/textstyleparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const (
SpoilerBegin = 9
)

const EscapeCharacter rune = '\\'

func getUtf16StringLength(s string) int {
runes := []rune(s) //turn string to slice

Expand Down Expand Up @@ -74,7 +76,6 @@ type TextstyleParser struct {
tokens Stack
fullString string
signalCliFormatStrings []string
//numOfControlTokens int
}

func NewTextstyleParser(input string) *TextstyleParser {
Expand All @@ -93,9 +94,6 @@ func (l *TextstyleParser) next() (rune rune) {
l.width = 0
return eof
}
//r := []rune(l.input[l.pos:])[0]
//l.width = utf16.RuneLen(r)
//l.pos += l.width
rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
l.pos += l.width
return rune
Expand Down Expand Up @@ -129,6 +127,7 @@ func (l *TextstyleParser) handleToken(tokenType int, signalCliStylingType string
}

func (l *TextstyleParser) Parse() (string, []string) {
var prevChar rune
for {
c := l.next()
if c == eof {
Expand All @@ -140,20 +139,45 @@ func (l *TextstyleParser) Parse() (string, []string) {
if c == '*' {
if nextRune == '*' { //Bold
l.next()
if prevChar == EscapeCharacter {
prevChar = c
continue
}
l.handleToken(BoldBegin, Bold)
} else { //Italic
if prevChar == EscapeCharacter {
prevChar = c
continue
}
l.handleToken(ItalicBegin, Italic)
}
} else if (c == '|') && (nextRune == '|') {
l.next()
if prevChar == EscapeCharacter {
prevChar = c
continue
}
l.handleToken(SpoilerBegin, Spoiler)
} else if c == '~' {
if prevChar == EscapeCharacter {
prevChar = c
continue
}
l.handleToken(StrikethroughBegin, Strikethrough)
} else if c == '`' {
if prevChar == EscapeCharacter {
prevChar = c
continue
}
l.handleToken(MonoSpaceBegin, Monospace)
} else if ((c == EscapeCharacter) && (nextRune == '*')) || ((c == EscapeCharacter) && (nextRune == '`')) || ((c == EscapeCharacter) && (nextRune == '|')) || ((c == EscapeCharacter) && (nextRune == '~')) {
prevChar = c
continue
} else {
l.fullString += string(c)
}

prevChar = c
}

return l.fullString, l.signalCliFormatStrings
Expand Down
28 changes: 28 additions & 0 deletions src/utils/textstyleparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,31 @@ func TestBoldTextInsideSpoiler(t *testing.T) {
expectMessageEqual(t, message, "this is a bold text inside a spoiler")
expectFormatStringsEqual(t, signalCliFormatStrings, []string{"0:36:BOLD", "0:36:SPOILER"})
}

func TestEscapeAsterisks(t *testing.T) {
textstyleParser := NewTextstyleParser("\\*escaped text\\*")
message, signalCliFormatStrings := textstyleParser.Parse()
expectMessageEqual(t, message, "escaped text")
expectFormatStringsEqual(t, signalCliFormatStrings, []string{})
}

func TestEscapeAsterisks1(t *testing.T) {
textstyleParser := NewTextstyleParser("\\**escaped text\\**")
message, signalCliFormatStrings := textstyleParser.Parse()
expectMessageEqual(t, message, "escaped text")
expectFormatStringsEqual(t, signalCliFormatStrings, []string{})
}

func TestEscapeBackticks(t *testing.T) {
textstyleParser := NewTextstyleParser("\\`escaped text\\`")
message, signalCliFormatStrings := textstyleParser.Parse()
expectMessageEqual(t, message, "escaped text")
expectFormatStringsEqual(t, signalCliFormatStrings, []string{})
}

func TestEscapeTilde(t *testing.T) {
textstyleParser := NewTextstyleParser("\\~escaped text\\~")
message, signalCliFormatStrings := textstyleParser.Parse()
expectMessageEqual(t, message, "escaped text")
expectFormatStringsEqual(t, signalCliFormatStrings, []string{})
}

0 comments on commit a70c299

Please sign in to comment.