# HG changeset patch # User Kim Alvefur # Date 1395585357 -3600 # Node ID 1c94ed0bfdec2c447687a4ebd3de0b4d5a3cc00c # Parent 70db447e3669af4c73346f1aa34b8934c161f68e plugins.xkcd: Change list of comics to have both map of number to name and name to number, allowing some optimizations diff -r 70db447e3669 -r 1c94ed0bfdec plugins/xkcd.lua --- a/plugins/xkcd.lua Sun Mar 23 15:32:21 2014 +0100 +++ b/plugins/xkcd.lua Sun Mar 23 15:35:57 2014 +0100 @@ -32,56 +32,55 @@ end function handle_xkcd_command(command) - local xkcdnum = command.param; - if not xkcdnum then - xkcdnum = #xkcd_list; + local xkcdnum = command.param; + if not xkcdnum then + xkcdnum = #xkcd_list; + elseif not tonumber(xkcdnum) then -- Search for an xkcd + local xkcdname = xkcdnum:lower(); + if xkcd_list[xkcdname] then + xkcdnum = xkcd_list[xkcdname]; + local xkcd = xkcd_list[xkcdnum]; + return xkcd..", http://xkcd.org/"..xkcdnum.."/"; + end + + local xkcdpat = xkcdname:gsub("[-()%[]", "%%%0") + :gsub("%%(%b[])",function(s) return (#s > 2 and "" or "%") .. s end); + local results = {}; + + for i, xkcd in pairs(xkcd_list) do + if type(i) == "number" and xkcd:lower():match(xkcdpat) then + results[#results+1] = i; + end end - if not tonumber(xkcdnum) then -- Search for an xkcd - xkcdnum = xkcdnum:lower() - local xkcdpat = xkcdnum:gsub("[()]", function(s) return "%" .. s end) - :gsub("[%[]",function(s) return "%" .. s end) - :gsub("%%(%b[])",function(s) return (#s > 2 and "" or "%") .. s end); - local results = {}; - for x, xkcd in pairs(xkcd_list) do - name = xkcd:lower() - if name == xkcdnum then -- exact match - return xkcd..", http://xkcd.org/"..x.."/"; - elseif name:match(xkcdpat) then - table.insert(results, x); - --return commands.xkcd(msg, x); - end - end - if #results == 0 then - return "Sorry, I couldn't find a match"; - elseif #results == 1 then - command.param = results[1]; - return handle_xkcd_command(command); - else - -- We have more than one match - local ret = "Multiple matches:"; - for _, x in ipairs(results) do - local xkcdnum = tostring(tonumber(x)); - local xkcd = xkcd_list[tostring(x)]; - ret = string.format("%s %s%s", ret, xkcd, ((_ < #results) and ",") or ""); - if _ > 5 then ret = ret .. " " .. (#results - 5) .. " more"; break; end - end - return ret; - end - end - -- Check that xkcdnum is a valid number - xkcdnum = tostring(tonumber(xkcdnum)); - if not xkcdnum then return "What XKCD strip number? Or enter a search string."; end - xkcd = xkcd_list[xkcdnum]; - if not xkcd then return "Sorry, I don't think there is a XKCD #"..xkcdnum; end - return xkcd..", http://xkcd.org/"..xkcdnum.."/"; + + if #results == 0 then + return "Sorry, I couldn't find a match"; + elseif #results == 1 then + xkcdnum = results[1]; + else + -- We have more than one match + local ret = "Multiple matches:"; + for i, xkcdnum in ipairs(results) do + local xkcd = xkcd_list[xkcdnum]; + ret = string.format("%s %s (%d)%s", ret, xkcd, xkcdnum, ((i < #results) and ",") or ""); + if i > 5 then ret = ret .. " " .. (#results - 5) .. " more"; break; end + end + return ret; + end + end + -- Check that xkcdnum is a valid number + xkcdnum = tonumber(xkcdnum); + local xkcd = xkcd_list[xkcdnum]; + if not xkcd then return "Sorry, I don't think there is a XKCD #"..xkcdnum; end + return xkcd..", http://xkcd.org/"..xkcdnum.."/"; end function parse_xkcd_list(t) if not t then return nil; end for number, name in string.gmatch(t,"]*href=\"/(%d+)/\"[^>]*>([^<]+)") do - xkcd_list[number] = name; - local number = tonumber(number); + number = tonumber(number); if number then + xkcd_list[name:lower()] = number; xkcd_list[number] = name; end end