diff options
author | June McEnroe <june@causal.agency> | 2020-04-29 12:55:28 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2020-04-29 12:55:28 -0400 |
commit | 0dbf097da16a5c27ca87d21aa0cb2bdbf1fb8154 (patch) | |
tree | 620673d6c90549b9c17b0680248031aff9293af2 | |
parent | Clean up html.c (diff) | |
download | bubger-0dbf097da16a5c27ca87d21aa0cb2bdbf1fb8154.tar.gz bubger-0dbf097da16a5c27ca87d21aa0cb2bdbf1fb8154.zip |
Turn URLs into HTML links
Diffstat (limited to '')
-rw-r--r-- | html.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/html.c b/html.c index 5147798..850e070 100644 --- a/html.c +++ b/html.c @@ -14,6 +14,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include <regex.h> #include <err.h> #include <stdio.h> #include <stdlib.h> @@ -213,6 +214,48 @@ static int htmlInlineAttrs(FILE *file, const struct BodyPart *part) { return 0; } +static void swap(char *a, char *b) { + char ch = *a; + *a = *b; + *b = ch; +} + +static int htmlMarkupURLs(FILE *file, char *buf) { + static const char *Pattern = "(^|[[:space:]<])(https?:[^[:space:]>]+)(.|$)"; + static regex_t regex; + if (!regex.re_nsub) { + int error = regcomp(®ex, Pattern, REG_EXTENDED); + if (error) { + char buf[256]; + regerror(error, ®ex, buf, sizeof(buf)); + errx(EX_SOFTWARE, "%s: %s", buf, Pattern); + } + } + + int error; + char *ptr; + regmatch_t match[4]; + for (ptr = buf; !regexec(®ex, ptr, 4, match, 0); ptr += match[2].rm_eo) { + char nul = '\0'; + + swap(&ptr[match[2].rm_so], &nul); + error = escapeXML(file, ptr); + if (error) return error; + swap(&ptr[match[2].rm_so], &nul); + + const char *template = TEMPLATE(<a href="[url]">[url]</a>); + swap(&ptr[match[3].rm_so], &nul); + struct Variable vars[] = { + { "url", &ptr[match[2].rm_so] }, + {0}, + }; + error = templateRender(file, template, vars, escapeXML); + if (error) return error; + swap(&ptr[match[3].rm_so], &nul); + } + return escapeXML(file, ptr); +} + static int htmlMarkup(FILE *file, const char *content) { int error = 0; size_t cap = 0; @@ -240,24 +283,30 @@ static int htmlMarkup(FILE *file, const char *content) { if (patch && !strncmp(buf, "@@", 2)) { error = templateRender( - file, TEMPLATE(<b>[line]</b>) "\n", vars, escapeXML + file, TEMPLATE(<b>[line]</b>), vars, escapeXML ); } else if (patch && buf[0] == '-' && strncmp(buf, "---", 3)) { error = templateRender( - file, TEMPLATE(<del>[line]</del>) "\n", vars, escapeXML + file, TEMPLATE(<del>[line]</del>), vars, escapeXML ); } else if (patch && buf[0] == '+' && strncmp(buf, "+++", 3)) { error = templateRender( - file, TEMPLATE(<ins>[line]</ins>) "\n", vars, escapeXML + file, TEMPLATE(<ins>[line]</ins>), vars, escapeXML ); + } else if (patch) { + error = escapeXML(file, buf); } else if (buf[0] == '>') { - error = templateRender( - file, TEMPLATE(<q>[line]</q>) "\n", vars, escapeXML - ); + error = 0 + || templateRender(file, TEMPLATE(<q>), NULL, NULL) + || htmlMarkupURLs(file, buf) + || templateRender(file, TEMPLATE(</q>), NULL, NULL); } else { - error = templateRender(file, "[line]\n", vars, escapeXML); + error = htmlMarkupURLs(file, buf); } if (error) break; + + error = templateRender(file, "\n", NULL, NULL); + if (error) break; } free(buf); return error; |