commit 467158f9eedd92c8b778eb632608fb4b390100e5
parent 584e542814fe57a3090c88788e20cbe60be1f8a7
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Mon, 26 May 2014 17:25:49 +0200
improve highlight.c, update README
improvements:
- separate word highlight from nick highlight.
- make regex for matching nicknames and aligning them more clear.
- improve wording of some comments.
- stricter matching on server messages for highlight.
- if regexword or regexignore is set to an empty string don't use it
  (else it would match everything).
Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>
Diffstat:
| M | README | | | 6 | +++--- | 
| M | highlight.c | | | 83 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- | 
2 files changed, 51 insertions(+), 38 deletions(-)
diff --git a/README b/README
@@ -1,9 +1,9 @@
 WTF?
 ====
 
-Edit config according to your needs.  Edit highlight.c with
-your nick information and compile it with cc -o highlight highlight.c
-Then start ./hysteria.
+Edit config according to your needs.  Edit highlight.c with your nick
+information and compile it with cc -o highlight highlight.c or run mk. Then
+start ./hysteria.
 
 KNOWN ISSUES AND WORKAROUNDS
 ============================
diff --git a/highlight.c b/highlight.c
@@ -2,13 +2,13 @@
  * highlight chat for ii similar in style to irssi.
  *
  * supports:
- * - highlight own nick + beep (urgent hint).
+ * - highlight own nick, words + beep (can set urgent hint).
  * - highlight own messages.
  * - highlight urls.
  * - highlight server messages.
  * - align nicknames.
  * - ignore words.
- * - remove date-prefix.
+ * - don't print date-prefix (YYYY-mm-dd).
  */
 
 #include <stdio.h>
@@ -23,30 +23,37 @@
 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 */
+/* highlight / color words */
+static const char *regexword = "(evil_bob|bob|hiltjo)";
+/* match nickname */
 static const char *regexnick = "(evil_bob|bob|hiltjo)";
-static const char *regexnickalign = "^[0-9]{2}:[0-9]{2} <";
-static const char *regexserver = "^(.* -!- .*)$";
+/* nickname to match and align */
+static const char *regexnickalign = "^[0-9]{2}:[0-9]{2} <([^>]+)>";
+/* match server messages */
+static const char *regexserver = "^([0-9]{2}:[0-9]{2} -!- .*)$";
+/* skip this prefix for each line (date part) */
 static const char *regextimestamp = "^[0-9]{4}-[0-9]{2}-[0-9]{2} ";
-static const char *regexignore = "penis";
+/* ignore message on match */
+static const char *regexignore = "";
+/* highlight / color urls */
 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 regex_t nick, nickalign, server, timestamp, ignore, url, word;
 
 static void
-eprintf(const char *s) {
+eprintf(const char *s)
+{
 	fprintf(stderr, "%s\n", s);
 	exit(EXIT_FAILURE);
 }
 
 static void
-printalign(const char *s, size_t len, size_t maxlen) {
+printalign(const char *s, size_t len, size_t maxlen)
+{
 	size_t i;
 
 	if(len < maxlen) {
@@ -59,12 +66,15 @@ printalign(const char *s, size_t len, size_t maxlen) {
 
 int
 main(void) {
-	char buffer[1024]; /* should be atleast 512 bytes + datetime prefix */
-	regmatch_t match;
-	const char *p, *search;
+	/* buffer: should be atleast 512 bytes (IRC RFC) + datetime prefix,
+	 * assumes line length is lower than sizeof(buffer). */
+	char buffer[1024];
+	regmatch_t match, matches[3];
+	size_t len;
+	const char *p;
 	int hasmatch, ret;
 
-	/* compile regex, for science */
+	/* compile regex */
 	if(regcomp(&nick, regexnick, REG_EXTENDED | REG_ICASE))
 		eprintf("invalid regex: nick");
 	if(regcomp(&nickalign, regexnickalign, REG_EXTENDED))
@@ -77,16 +87,17 @@ main(void) {
 		eprintf("invalid regex: ignore");
 	if(regcomp(&url, regexurl, REG_EXTENDED | REG_ICASE))
 		eprintf("invalid regex: url");
+	if(regcomp(&word, regexword, REG_EXTENDED | REG_ICASE))
+		eprintf("invalid regex: word");
 
-	/* NOTE: assumes line length is lower than sizeof(buffer) */
 	while(fgets(buffer, sizeof(buffer), stdin)) {
 		p = buffer;
 
-		/* skip date of timestamp part */
+		/* skip date part (YYY-mm-dd) of timestamp */
 		if((ret = regexec(×tamp, p, 1, &match, 0)) != REG_NOMATCH)
 			p += match.rm_eo - match.rm_so;
 
-		/* skip date of timestamp part */
+		/* highlight / color server messages */
 		if((ret = regexec(&server, p, 1, &match, 0)) != REG_NOMATCH) {
 			fputs(green, stdout);
 			fputs(p, stdout);
@@ -95,44 +106,45 @@ main(void) {
 			continue;
 		}
 
-		/* ignore */
-		if((ret = regexec(&ignore, p, 1, &match, 0)) != REG_NOMATCH)
+		/* ignore on match */
+		if(regexignore[0] && (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)
+		if((ret = regexec(&nickalign, p, 2, matches, 0)) != REG_NOMATCH)
 		{
-			fwrite(p, 1, match.rm_eo, stdout);
-			p += match.rm_eo;
-			/* own nick ?: highlight */
+			fwrite(p, 1, matches[1].rm_so, stdout);
+			putchar('@');
+			p += matches[1].rm_so;
+			len = matches[1].rm_eo - matches[1].rm_so;
+			/* own nick ?: color nickname part white */
 			if((ret = regexec(&nick, p, 1, &match, 0)) != REG_NOMATCH &&
-				match.rm_so == 0 && p[match.rm_eo] == '>')
+				match.rm_so == 0 && match.rm_eo == len)
 			{
 				fputs(white, stdout);
-				printalign(p, match.rm_eo, 10);
+				printalign(p, len, 10);
 				fputs(reset, stdout);
-				p += match.rm_eo;
 			} else {
-				if((search = strchr(p, '>'))) {
-					printalign(p, search - p, 10);
-					p = search;
-				}
+				printalign(p, len, 10);
 			}
+			p += len;
 		}
 
 		hasmatch = 1;
 		while(hasmatch) {
 			hasmatch = 0;
-			/* highlight nick */
-			if((ret = regexec(&nick, p, 1, &match, 0)) != REG_NOMATCH) {
+			/* highlight word */
+			if(regexword[0] &&
+			   (ret = regexec(&word, 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 */
+				/* beep, can be set in your terminal to set urgent hint */
+				putchar('\a');
 				hasmatch = 1;
 			}
 			/* highlight url */
@@ -151,6 +163,7 @@ main(void) {
 	}
 
 	/* free regex */
+	regfree(&word);
 	regfree(&nick);
 	regfree(&nickalign);
 	regfree(&server);