commit c21412ce4899c134ea315cbdde0ab1f056de1463
parent 67be1bfcb8643531ce7063423a7e45a2225439b8
Author: Karl Bartel <karl42@gmail.com>
Date: Sat, 28 Sep 2019 23:27:18 +0200
Handle nested parens in links
Example input:
[With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
Diffstat:
M | smu.c | | | 21 | ++++++++++++++++----- |
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/smu.c b/smu.c
@@ -233,7 +233,7 @@ dolineprefix(const char *begin, const char *end, int newblock) {
int
dolink(const char *begin, const char *end, int newblock) {
- int img, len, sep;
+ int img, len, sep, parens_depth = 1;
const char *desc, *link, *p, *q, *descend, *linkend;
const char *title = NULL, *titleend = NULL;
@@ -251,8 +251,20 @@ dolink(const char *begin, const char *end, int newblock) {
return 0;
descend = p;
link = p + 2;
- if(!(q = strchr(link, ')')) || q > end)
- return 0;
+
+ /* find end of link while handling nested parens */
+ q = link;
+ while(parens_depth) {
+ if(!(q = strpbrk(q, "()")) || q > end)
+ return 0;
+ if(*q == '(')
+ parens_depth++;
+ else
+ parens_depth--;
+ if(parens_depth && q < end)
+ q++;
+ }
+
if((p = strpbrk(link, "\"'")) && p < end && q > p) {
sep = p[0]; /* separator: can be " or ' */
title = p + 1;
@@ -261,12 +273,11 @@ dolink(const char *begin, const char *end, int newblock) {
if(!(p = strchr(title, sep)) || q > end || p > q)
return 0;
titleend = p;
- len = p + 2 - begin;
}
else {
linkend = q;
- len = q + 1 - begin;
}
+ len = q + 1 - begin;
if(img) {
fputs("<img src=\"", stdout);
hprint(link, linkend);