From 913c7e3bc4a8ba2b9ec46e4cd33286c713968f0b Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Mon, 10 Mar 2025 15:40:01 -0400 Subject: add figure support --- main.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file 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("
"); for (Line *l = blk->lines; l; l = l->next) { - O(str_trim(str_skip(l->txt, 1))); + O(l->txt); if (l->next) Os("
\n"); } Os(""); break; case LN_ULIST: Os("\n"); - Otl("
- ", str_skip(l->txt, 2), "
\n"); + Otl("- ", l->txt, "
\n"); Os(""); break; case LN_OLIST: Os("
\n"); - Otl("
- ", str_trim(str_cut(l->txt, '.').tail), "
\n"); + Otl("- ", l->txt, "
\n"); Os(""); break; case LN_HDR1: - Otl("
", str_trim(str_skip(l->txt,1)), "
"); + Otl("", l->txt, "
"); break; case LN_HDR2: - Otl("", str_trim(str_skip(l->txt,2)), "
"); + Otl("", l->txt, "
"); break; case LN_HDR3: - Otl("", str_trim(str_skip(l->txt,3)), "
"); + Otl("", l->txt, "
"); 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; -- cgit 1.4.1-2-gfad0