summary refs log tree commit diff
diff options
context:
space:
mode:
authorwrmr2024-11-06 17:22:46 -0500
committerwrmr2024-11-06 17:22:46 -0500
commitb977942932bf1cd625f8d7a6f310b0d3a537f72e (patch)
tree9bae300b4bbe5bd689b4c85058c6a87ca609b9ad
parent18fbd7061610c9e7aa9c5019efa13993d3a4d8f5 (diff)
add plaintext url parsing
-rw-r--r--parse.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/parse.c b/parse.c
index 601c6b1..a57c1b3 100644
--- a/parse.c
+++ b/parse.c
@@ -1,11 +1,44 @@
+#include <ctype.h>
+#include <string.h>
+
 #include "parse.h"
 #include "err.h"
 
+struct str_slice {
+	const char *s;
+	size_t n;
+};
+
+int isurlch(char c) {
+	return isalpha(c) || isdigit(c) || c == '-' || c == '.' || c == '_' || c == '~' || c == '!' || c == '$' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '+' || c == ',' || c == ';' || c == '=' || c == '%' || c == '@' || c == ':' || c == '/';
+}
+
+void parse_plain_url(struct doc *d, struct doc_line *l, size_t i) {
+	char url[l->len + 1];
+	size_t start = i - 1;
+	while (start > 0 && isalpha(l->txt[start])) start--;
+	if (!isalpha(l->txt[start])) start++;
+	size_t end = i + 3;
+	while (end < l->len && isurlch(l->txt[end])) end++;
+	if (end == i + 3) return;
+	size_t urln = end - start;
+	memcpy(url, &l->txt[start], urln);
+	url[urln] = 0;
+	l->link = doc_add_link(d, url);
+}
+
 int parse_plain(struct doc *d, const buf_t *b) {
 	doc_init(d);
 	for (size_t i = 0; i < b->sz; i++) {
 		char c = b->buf[i];
 		if (c == '\n') {
+			struct doc_line *l = doc_line_at(d, d->latest);
+			for (size_t i = 1; i + 2 < l->len; i++) {
+				if (l->txt[i] == ':' && l->txt[i + 1] == '/' && l->txt[i + 2] == '/') {
+					parse_plain_url(d, l, i);
+					break;
+				}
+			}
 			doc_new_line(d);
 		} else {
 			doc_add_textn(d, &c, 1);
@@ -14,11 +47,6 @@ int parse_plain(struct doc *d, const buf_t *b) {
 	return 0;
 }
 
-struct str_slice {
-	const char *s;
-	size_t n;
-};
-
 static struct str_slice gmbit(size_t *i, const char *s, size_t n) {
 	struct str_slice ss = {
 		&s[*i],