plugins.xkcd: Change list of comics to have both map of number to name and name to number, allowing some optimizations

Sun, 23 Mar 2014 15:35:57 +0100

author
Kim Alvefur <zash@zash.se>
date
Sun, 23 Mar 2014 15:35:57 +0100
changeset 109
1c94ed0bfdec
parent 108
70db447e3669
child 110
e5903656c21a

plugins.xkcd: Change list of comics to have both map of number to name and name to number, allowing some optimizations

plugins/xkcd.lua file | annotate | diff | comparison | revisions
--- 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,"<a [^>]*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

mercurial