| 1 | /* |
| 2 | variables available |
| 3 | read-only: |
| 4 | inAccount, inProtocol, inChannel, inGateway, inEvent |
| 5 | outAccount, outProtocol, outChannel, outGateway, outEvent |
| 6 | msgUserID |
| 7 | |
| 8 | read-write: |
| 9 | msgDrop, msgText, msgUsername |
| 10 | */ |
| 11 | |
| 12 | text := import("text") |
| 13 | fmt := import("fmt") |
| 14 | |
| 15 | doQuote_ := func(reply, nick, ctx) { |
| 16 | // on discord, wrap links inside ctx with <...> to prevent embeds |
| 17 | if outProtocol == "discord" { |
| 18 | re := text.re_compile( |
| 19 | `(https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[-a-zA-Z0-9]{1,16}\b[-a-zA-Z0-9@:%_+.~#?&/=]*)` |
| 20 | ) |
| 21 | if re.match(ctx) { |
| 22 | ctx = re.replace(ctx, "<$1>") |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | if outProtocol == "xmpp" || outProtocol == "discord" { |
| 27 | // split multiline context and prepend lines with a ">" |
| 28 | ctx = text.join(text.split(ctx, "\n"), "\n> ") |
| 29 | prefix := "> ↪ " |
| 30 | if outProtocol == "discord" { prefix = "> -# ↪ " } |
| 31 | return prefix + nick + |
| 32 | "\n> " + ctx + "\n" + |
| 33 | reply |
| 34 | } else { |
| 35 | ctx = text.join(text.split(ctx, "\n"), " ") |
| 36 | return reply + " (in reply to " + nick + ": " + ctx + ")" |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | // match $1 must be the reply |
| 41 | // match $2 must be the nick |
| 42 | // match $3 must be the context |
| 43 | doQuote := func(...reStrs) { |
| 44 | for reStr in reStrs { |
| 45 | re := text.re_compile(reStr) |
| 46 | if re.match(msgText) { |
| 47 | reply := re.replace(msgText, "$1") |
| 48 | nick := re.replace(msgText, "$2") |
| 49 | ctx := re.replace(msgText, "$3") |
| 50 | msgText = doQuote_(reply, nick, ctx) |
| 51 | break |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | // start - strip irc colors |
| 57 | // if we're not sending to an irc bridge we strip the IRC colors |
| 58 | if inProtocol == "irc" && outProtocol != "irc" { |
| 59 | re := text.re_compile(`\x03(?:\d{1,2}(?:,\d{1,2})?)?|[[:cntrl:]]`) |
| 60 | msgText=re.replace(msgText,"") |
| 61 | } |
| 62 | // end - strip irc colors |
| 63 | |
| 64 | // if we're not sending to a discord bridge, |
| 65 | // then convert custom emoji tags into url's |
| 66 | if (inProtocol == "discord" && outProtocol != "discord") { |
| 67 | rePNG := text.re_compile(`<:.*?:([0-9]+)>`) |
| 68 | msgText = rePNG.replace(msgText,"https://cdn.discordapp.com/emojis/$1.png") |
| 69 | reGIF := text.re_compile(`<a:.*?:([0-9]+)>`) |
| 70 | msgText = reGIF.replace(msgText,"https://cdn.discordapp.com/emojis/$1.gif") |
| 71 | } |
| 72 | |
| 73 | // convert emoji URLs back into the emojis themselves on discord |
| 74 | if (inProtocol != "discord" && outProtocol == "discord") { |
| 75 | rePNG := text.re_compile(`https://cdn\.discordapp\.com/emojis/([0-9]+)\.png`) |
| 76 | msgText = rePNG.replace(msgText, "<:_:$1>") |
| 77 | } |
| 78 | |
| 79 | // format replies from all protocols to all protocols |
| 80 | doQuote(`(?s)(.*?) \(in reply to (.*?): (.*?)\)$`) |
| 81 | |