diff --git a/doc/irc.luadoc b/doc/irc.luadoc
index bf3ceec..36c5242 100644
--- a/doc/irc.luadoc
+++ b/doc/irc.luadoc
@@ -125,6 +125,7 @@ function irc:shutdown()
--- Class representing an IRC message. Objects of this class may contain the following fields:
--
+-- tags
- A table of IRCv3 tags.
-- prefix
- Prefix of the message.
-- user
- A User object describing the sender of the message.
-- command
- The IRC command.
diff --git a/messages.lua b/messages.lua
index 00c0bd3..62aa108 100644
--- a/messages.lua
+++ b/messages.lua
@@ -1,6 +1,7 @@
local assert = assert
local setmetatable = setmetatable
local unpack = unpack
+local pairs = pairs
module "irc"
@@ -17,7 +18,28 @@ function Message(cmd, args)
end
function msg_meta:toRFC1459()
- s = self.command
+ s = ""
+
+ if self.tags then
+ s = s.."@"
+ for key, value in pairs(self.tags) do
+ s = s..key
+ if value ~= true then
+ assert(not value:find("[%z\07\r\n; ]"),
+ "NUL, BELL, CR, LF, semicolon, and"
+ .." space are not allowed in RFC1459"
+ .." formated tag values.")
+ s = s.."="..value
+ end
+ s = s..";"
+ end
+ -- Strip trailing semicolon
+ s = s:sub(1, -2)
+ s = s.." "
+ end
+
+ s = s..self.command
+
argnum = #self.args
for i = 1, argnum do
local arg = self.args[i]
@@ -33,6 +55,7 @@ function msg_meta:toRFC1459()
end
s = s..arg
end
+
return s
end
diff --git a/util.lua b/util.lua
index d22f16a..0e0f5ff 100644
--- a/util.lua
+++ b/util.lua
@@ -14,8 +14,25 @@ module "irc"
function parse(line)
local msg = Message()
+ -- IRCv3 tags
+ if line:sub(1, 1) == "@" then
+ msg.tags = {}
+ local space = line:find(" ", 1, true)
+ -- For each semicolon-delimited section from after
+ -- the @ character to before the space character.
+ for tag in line:sub(2, space - 1):gmatch("([^;]+)") do
+ local eq = tag:find("=", 1, true)
+ if eq then
+ msg.tags[tag:sub(1, eq - 1)] = tag:sub(eq + 1)
+ else
+ msg.tags[tag] = true
+ end
+ end
+ line = line:sub(space + 1)
+ end
+
if line:sub(1, 1) == ":" then
- local space = line:find(" ")
+ local space = line:find(" ", 1, true)
msg.prefix = line:sub(2, space - 1)
msg.user = parsePrefix(msg.prefix)
line = line:sub(space + 1)