diff options
author | June McEnroe <june@causal.agency> | 2020-07-12 19:58:20 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-07-12 19:58:20 -0400 |
commit | 984faba65ba6f8aa7f35e0caf530bc15609935d8 (patch) | |
tree | 61346817d512c1039a31f38d1db597d4428952f8 | |
parent | Render all types of events (diff) | |
download | scooper-984faba65ba6f8aa7f35e0caf530bc15609935d8.tar.gz scooper-984faba65ba6f8aa7f35e0caf530bc15609935d8.zip |
Linkify IRC messages
-rw-r--r-- | html.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/html.c b/html.c index 2d987f8..ae4c76f 100644 --- a/html.c +++ b/html.c @@ -14,10 +14,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> #include <err.h> #include <inttypes.h> +#include <regex.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sysexits.h> #include <time.h> @@ -389,9 +392,39 @@ htmlEvent(struct khtmlreq *html, struct Scope scope, struct Event event) { || khtml_closeelem(html, 1); } +enum kcgi_err linkify(struct khtmlreq *html, const char *str, size_t len) { + static const char *Pattern = "https?://([^[:space:]>\"()]|[(][^)]*[)])+"; + static regex_t regex; + if (!regex.re_nsub) { + int error = regcomp(®ex, Pattern, REG_EXTENDED); + assert(!error); + } + + regmatch_t match = {0}; + while (!regexec(®ex, str, 1, &match, 0)) { + if ((size_t)match.rm_eo > len) break; + + char *href = strndup(&str[match.rm_so], match.rm_eo - match.rm_so); + if (!href) err(EX_OSERR, "strndup"); + + enum kcgi_err error = 0 + || khtml_write(str, match.rm_so, html) + || khtml_attr(html, KELEM_A, KATTR_HREF, href, KATTR__MAX) + || khtml_write(&str[match.rm_so], match.rm_eo - match.rm_so, html) + || khtml_closeelem(html, 1); + free(href); + if (error) return error; + + str += match.rm_eo; + len -= match.rm_eo; + } + if (len) return khtml_write(str, len, html); + return KCGI_OK; +} + enum kcgi_err htmlIRC(struct khtmlreq *html, const char *str) { return 0 || khtml_attr(html, KELEM_SPAN, KATTR_CLASS, "irc", KATTR__MAX) - || khtml_puts(html, str) + || linkify(html, str, strlen(str)) || khtml_closeelem(html, 1); } |