summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c124
1 files changed, 89 insertions, 35 deletions
diff --git a/main.c b/main.c
index 553ed06..267c56f 100644
--- a/main.c
+++ b/main.c
@@ -88,6 +88,7 @@ typedef enum {
LN_PAR,
LN_CODE,
LN_LINK,
+ LN_IMG,
LN_BQUOT,
LN_ULIST,
LN_OLIST,
@@ -99,7 +100,7 @@ typedef enum {
typedef struct Line Line;
struct Line {
- Str txt;
+ Str txt, url;
Line *next;
};
@@ -148,6 +149,64 @@ LineType classify_line(Str line, LineType prev) {
}
}
+int has_image_ext(Str url) {
+ return str_ends(url, S(".png"))
+ || str_ends(url, S(".jpg"))
+ || str_ends(url, S(".jpeg"))
+ || str_ends(url, S(".webp"));
+}
+
+/* can change the line type based on parsing */
+LineType line_init(Line *l, Str txt, LineType t) {
+ Cut c;
+ switch (t) {
+ case LN_LINK:
+ c = str_cut(str_trim(str_skip(txt, 2)), ' ');
+ c.tail = str_trim(c.tail);
+ l->url = c.head;
+ l->txt = c.tail.n > 0 ? c.tail : c.head;
+ return has_image_ext(l->url) ? LN_IMG : LN_LINK;
+ case LN_HDR1:
+ l->txt = str_trim(str_skip(txt, 1));
+ break;
+ case LN_HDR2:
+ l->txt = str_trim(str_skip(txt, 2));
+ break;
+ case LN_HDR3:
+ l->txt = str_trim(str_skip(txt, 3));
+ break;
+ case LN_ULIST:
+ l->txt = str_skip(txt, 2);
+ break;
+ case LN_OLIST:
+ l->txt = str_trim(str_cut(l->txt, '.').tail);
+ break;
+ case LN_BQUOT:
+ l->txt = str_trim(str_skip(txt, 1));
+ break;
+ default:
+ l->txt = txt;
+ break;
+ }
+ return t;
+}
+
+Block *blk_push(BlockList *blk, Line **lptr, LineType t, Arena *perm) {
+ if (blk->cap <= blk->len) {
+ size_t c = blk->cap;
+ if (!c) c = 16;
+ while (c <= blk->len) c <<= 1;
+ blk->data = resize(perm, blk->data,
+ blk->cap, c);
+ blk->cap = c;
+ }
+ Block *b = &blk->data[blk->len++];
+ b->type = t;
+ b->lines = NULL;
+ *lptr = NULL;
+ return b;
+}
+
BlockList blk_gather(Str src, Arena *perm) {
Str line;
LineType last = LN_NONE;
@@ -160,25 +219,18 @@ BlockList blk_gather(Str src, Arena *perm) {
} else if (t == LN_CODE) {
last = LN_CODE;
} else {
- if (blk.len < 1 || t != blk.data[blk.len-1].type) {
- if (blk.cap <= blk.len) {
- size_t c = blk.cap;
- if (!c) c = 16;
- while (c <= blk.len) c <<= 1;
- blk.data = resize(perm, blk.data,
- blk.cap, c);
- blk.cap = c;
- }
- Block *b = &blk.data[blk.len++];
- b->type = t;
- b->lines = NULL;
- lptr = NULL;
+ Block *b = blk.len > 0 ? &blk.data[blk.len-1] : NULL;
+ if (!b || t != b->type) {
+ b = blk_push(&blk, &lptr, t, perm);
}
Line *l = new(perm, Line);
- l->txt = line;
+ LineType nt = line_init(l, line, t);
+ if (b->type != nt) {
+ if (b->lines) b = blk_push(&blk, &lptr, nt, perm);
+ else b->type = nt;
+ }
if (lptr) lptr->next = l;
lptr = l;
- Block *b = &blk.data[blk.len-1];
if (!b->lines) b->lines = lptr;
}
last = t;
@@ -212,42 +264,51 @@ void str_cat_blk(Str *out, Block *blk, Arena *perm, Arena *scratch) {
case LN_LINK:
Os("<ul>\n");
for (Line *l = blk->lines; l; l = l->next) {
- Cut c = str_cut(str_trim(str_skip(l->txt, 2)), ' ');
- Str url = c.head, txt = c.tail.n > 0 ? c.tail : c.head;
Os("<li><a href=");
- str_cat_uri(out, str_contains(url, S("://")) ? url :
- str_replace_end(url, S(".gmi"),
- S(".html"), scratch), perm);
- Ot(">", txt, "</a></li>\n");
+ str_cat_uri(out, str_contains(l->url, S("://"))
+ ? l->url
+ : str_replace_end(l->url,
+ S(".gmi"), S(".html"),
+ scratch), perm);
+ Ot(">", l->txt, "</a></li>\n");
}
Os("</ul>");
break;
+ case LN_IMG:
+ for (Line *l = blk->lines; l; l = l->next) {
+ Os("<figure>\n");
+ Ot("<figcaption>", l->txt, "</figcaption>\n<img src=");
+ str_cat_uri(out, l->url, perm);
+ Os(">\n</figcaption>");
+ if (l->next) Os("\n");
+ }
+ break;
case LN_BQUOT:
Os("<blockquote>");
for (Line *l = blk->lines; l; l = l->next) {
- O(str_trim(str_skip(l->txt, 1)));
+ O(l->txt);
if (l->next) Os("<br>\n");
}
Os("<blockquote>");
break;
case LN_ULIST:
Os("<ul>\n");
- Otl("<li>", str_skip(l->txt, 2), "</li>\n");
+ Otl("<li>", l->txt, "</li>\n");
Os("<ul>");
break;
case LN_OLIST:
Os("<ol>\n");
- Otl("<li>", str_trim(str_cut(l->txt, '.').tail), "</li>\n");
+ Otl("<li>", l->txt, "</li>\n");
Os("<ol>");
break;
case LN_HDR1:
- Otl("<h1>", str_trim(str_skip(l->txt,1)), "</h1>");
+ Otl("<h1>", l->txt, "</h1>");
break;
case LN_HDR2:
- Otl("<h2>", str_trim(str_skip(l->txt,2)), "</h2>");
+ Otl("<h2>", l->txt, "</h2>");
break;
case LN_HDR3:
- Otl("<h3>", str_trim(str_skip(l->txt,3)), "</h3>");
+ Otl("<h3>", l->txt, "</h3>");
break;
default:
case LN_PAR:
@@ -262,13 +323,6 @@ void str_cat_blk(Str *out, Block *blk, Arena *perm, Arena *scratch) {
Os("\n");
}
-int has_image_ext(Str url) {
- return str_ends(url, S(".png"))
- || str_ends(url, S(".jpg"))
- || str_ends(url, S(".jpeg"))
- || str_ends(url, S(".webp"));
-}
-
int wdoc(FILE *f, Doc **dp, Arena *perm, Arena *scratch) {
Str buf;
if (read_all(f, &buf, scratch)) return -1;