commit 64da685028f1f9a748136f731eb3eaa266f14e1e
parent 2c6457791c0da7b55b1c7cc138025c2e584c097f
Author: sin <sin@2f30.org>
Date: Thu, 8 May 2014 08:32:30 +0100
Add new highlighter by Hiltjo Posthuma <hiltjo@codemadness.org>
Diffstat:
A | highlight.c | | | 160 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 160 insertions(+), 0 deletions(-)
diff --git a/highlight.c b/highlight.c
@@ -0,0 +1,160 @@
+/*
+ * highlight chat for ii similar in style to irssi.
+ *
+ * supports:
+ * - highlight own nick + beep (urgent hint).
+ * - highlight own messages.
+ * - highlight urls.
+ * - highlight server messages.
+ * - align nicknames.
+ * - ignore words.
+ * - remove date-prefix.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <regex.h>
+
+/* escape codes: colors, reset */
+static const char *green = "\x1b[1;32m";
+static const char *yellow = "\x1b[1;33m";
+static const char *blue = "\x1b[1;34m";
+/*static const char *magenta = "\x1b[1;35m";*/
+static const char *white = "\x1b[1;37m";
+static const char *reset = "\x1b[1;0m";
+
+/* regex to match */
+/*static const char *regexaction = "ACTION (.*)?";*/ /* TODO */
+static const char *regexnick = "(((evil_bob|bob|hiltjo)";
+static const char *regexnickalign = "^[0-9]{2}:[0-9]{2} <";
+static const char *regexserver = "^(.* -!- .*)$";
+static const char *regextimestamp = "^[0-9]{4}-[0-9]{2}-[0-9]{2} ";
+static const char *regexignore = "penis";
+static const char *regexurl =
+ "(((https?|ftp)|mailto):(//)?[^ <>\"[:blank:]]*|(www|ftp)[0-9]?\\.[-a-z0-9.]+)";
+
+static regex_t nick, nickalign, server, timestamp, ignore, url;
+
+static void
+eprintf(const char *s) {
+ fprintf(stderr, "%s\n", s);
+ exit(EXIT_FAILURE);
+}
+
+static void
+printalign(const char *s, size_t len, size_t maxlen) {
+ size_t i;
+
+ if(len < maxlen) {
+ for(i = 0; i < maxlen - len; i++)
+ putchar(' ');
+ }
+ for(i = 0; i < len && i < maxlen; i++)
+ putchar(*s++);
+}
+
+int
+main(void) {
+ char buffer[BUFSIZ];
+ regmatch_t match;
+ const char *p, *search;
+ int hasmatch, ret;
+
+ /* compile regex, for science */
+ if(regcomp(&nick, regexnick, REG_EXTENDED | REG_ICASE))
+ eprintf("invalid regex: nick");
+ if(regcomp(&nickalign, regexnickalign, REG_EXTENDED))
+ eprintf("invalid regex: nickalign");
+ if(regcomp(&server, regexserver, REG_EXTENDED))
+ eprintf("invalid regex: server");
+ if(regcomp(×tamp, regextimestamp, REG_EXTENDED))
+ eprintf("invalid regex: timestamp");
+ if(regcomp(&ignore, regexignore, REG_EXTENDED | REG_ICASE))
+ eprintf("invalid regex: ignore");
+ if(regcomp(&url, regexurl, REG_EXTENDED | REG_ICASE))
+ eprintf("invalid regex: url");
+
+ /* NOTE: assumes line length is lower than sizeof(buffer) */
+ while(fgets(buffer, sizeof(buffer), stdin)) {
+ p = buffer;
+
+ /* skip date of timestamp part */
+ if((ret = regexec(×tamp, p, 1, &match, 0)) != REG_NOMATCH)
+ p += match.rm_eo - match.rm_so;
+
+ /* skip date of timestamp part */
+ if((ret = regexec(&server, p, 1, &match, 0)) != REG_NOMATCH) {
+ fputs(green, stdout);
+ fputs(p, stdout);
+ fputs(reset, stdout);
+ continue;
+ }
+
+ /* ignore */
+ if((ret = regexec(&ignore, p, 1, &match, 0)) != REG_NOMATCH)
+ continue;
+
+ /* align nicknames */
+ if((ret = regexec(&nickalign, p, 1, &match, 0)) != REG_NOMATCH &&
+ match.rm_so == 0)
+ {
+ fwrite(p, 1, match.rm_eo, stdout);
+ p += match.rm_eo;
+ /* own nick ?: highlight */
+ if((ret = regexec(&nick, p, 1, &match, 0)) != REG_NOMATCH &&
+ match.rm_so == 0)
+ {
+ fputs(white, stdout);
+ printalign(p, match.rm_eo, 10);
+ fputs(reset, stdout);
+ p += match.rm_eo;
+ } else {
+ if((search = strchr(p, '>'))) {
+ printalign(p, search - p, 10);
+ p = search;
+ }
+ }
+ }
+
+ hasmatch = 1;
+ while(hasmatch) {
+ hasmatch = 0;
+ /* highlight nick */
+ if((ret = regexec(&nick, p, 1, &match, 0)) != REG_NOMATCH) {
+ fwrite(p, 1, match.rm_so, stdout);
+ fputs(yellow, stdout);
+ p += match.rm_so;
+ fwrite(p, 1, match.rm_eo - match.rm_so, stdout);
+ fputs(reset, stdout);
+ p += match.rm_eo - match.rm_so;
+ putchar('\a'); /* beep */
+ hasmatch = 1;
+ }
+ /* highlight url */
+ if((ret = regexec(&url, p, 1, &match, 0)) != REG_NOMATCH) {
+ fwrite(p, 1, match.rm_so, stdout);
+ fputs(blue, stdout);
+ p += match.rm_so;
+ fwrite(p, 1, match.rm_eo - match.rm_so, stdout);
+ fputs(reset, stdout);
+ p += match.rm_eo - match.rm_so;
+ hasmatch = 1;
+ }
+ }
+ fputs(p, stdout); /* rest */
+ }
+
+ /* free regex */
+ regfree(&nick);
+ regfree(&nickalign);
+ regfree(&server);
+ regfree(×tamp);
+ regfree(&ignore);
+ regfree(&url);
+
+ return EXIT_SUCCESS;
+}