From ce90790838b9a6fbe1448aa8df0234d933923ac1 Mon Sep 17 00:00:00 2001 From: Kristaps Dz Date: Tue, 10 Dec 2024 09:44:18 -0800 Subject: [PATCH] Add --template to -tgemini. --- gemini.c | 20 +++++++++++++++---- template.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/gemini.c b/gemini.c index 465cd6a..3e627f7 100644 --- a/gemini.c +++ b/gemini.c @@ -67,6 +67,7 @@ struct gemini { ssize_t headers_offs; /* header offset */ struct lowdown_buf **foots; /* footnotes */ size_t footsz; /* footnotes size */ + const char *templ; /* output template */ }; /* @@ -971,20 +972,29 @@ rndr(struct lowdown_buf *ob, struct lowdown_metaq *mq, } int -lowdown_gemini_rndr(struct lowdown_buf *ob, - void *arg, const struct lowdown_node *n) +lowdown_gemini_rndr(struct lowdown_buf *ob, void *arg, + const struct lowdown_node *n) { struct gemini *st = arg; - int rc; + int rc = 0; size_t i; struct lowdown_metaq metaq; + struct lowdown_buf *tmp = NULL; TAILQ_INIT(&metaq); st->last_blank = 0; st->headers_offs = 1; - rc = rndr(ob, &metaq, st, n); + if (st->templ != NULL) { + if ((tmp = hbuf_new(64)) == NULL) + goto out; + if (!rndr(tmp, &metaq, st, n)) + goto out; + rc = lowdown_template(st->templ, tmp, ob, &metaq); + } else + rc = rndr(ob, &metaq, st, n); +out: link_freeq(&st->linkq); st->linkqsz = 0; st->nolinkqsz = 0; @@ -992,6 +1002,7 @@ lowdown_gemini_rndr(struct lowdown_buf *ob, for (i = 0; i < st->footsz; i++) hbuf_free(st->foots[i]); + hbuf_free(tmp); free(st->foots); st->footsz = 0; st->foots = NULL; @@ -1009,6 +1020,7 @@ lowdown_gemini_new(const struct lowdown_opts *opts) TAILQ_INIT(&p->linkq); p->flags = opts != NULL ? opts->oflags : 0; + p->templ = opts != NULL ? opts->templ : NULL; /* Only use one kind of flag output. */ diff --git a/template.c b/template.c index fc71188..f87cc43 100644 --- a/template.c +++ b/template.c @@ -409,7 +409,7 @@ op_eval_function_split(const struct lowdown_metaq *mq, } /* - * HTML-escape (for URL attributes) all characters in all list items. + * Escape all characters in all list items for HTML URL attributes. * Returns NULL on allocation failure. */ static struct op_resq * @@ -447,7 +447,7 @@ op_eval_function_escape_htmlurl(const struct lowdown_metaq *mq, } /* - * HTML-escape (for attributes) all characters in all list items. + * Escape all characters in all list items for HTML attributes. * Returns NULL on allocation failure. */ static struct op_resq * @@ -485,7 +485,7 @@ op_eval_function_escape_htmlattr(const struct lowdown_metaq *mq, } /* - * LaTeX-escape (for general content) all characters in all list items. + * Escape all characters in all list items for general LaTeX content. * Returns NULL on allocation failure. */ static struct op_resq * @@ -523,7 +523,48 @@ op_eval_function_escape_latex(const struct lowdown_metaq *mq, } /* - * HTML-escape (for general content) all characters in all list items. + * Escape all characters in all list items for Gemini, either over + * multiple lines or with newlines removed for a single line. + * Returns NULL on allocation failure. + */ +static struct op_resq * +op_eval_function_escape_gemini(const struct lowdown_metaq *mq, + const struct op_resq *input, int oneline) +{ + struct op_resq *nq = NULL; + struct op_res *nres; + const struct op_res *res; + struct lowdown_buf *buf; + + if ((buf = hbuf_new(32)) == NULL) + goto err; + if ((nq = malloc(sizeof(struct op_resq))) == NULL) + goto err; + TAILQ_INIT(nq); + + TAILQ_FOREACH(res, input, entries) { + hbuf_truncate(buf); + if (!lowdown_gemini_esc(buf, res->res, strlen(res->res), + oneline)) + goto err; + if ((nres = calloc(1, sizeof(struct op_res))) == NULL) + goto err; + TAILQ_INSERT_TAIL(nq, nres, entries); + nres->res = strndup(buf->data, buf->size); + if (nres->res == NULL) + goto err; + } + hbuf_free(buf); + return nq; +err: + hbuf_free(buf); + op_resq_free(nq); + return NULL; +} + +/* + * Escape all characters in all list items for roff (ms/man), either + * over multiple lines or with newlines removed for a single line. * Returns NULL on allocation failure. */ static struct op_resq * @@ -709,14 +750,18 @@ op_eval_function(const char *expr, size_t exprsz, const char *args, nq = op_eval_function_join(mq, input); else if (exprsz == 4 && strncasecmp(expr, "trim", 4) == 0) nq = op_resq_clone(input, 1); - else if (exprsz == 11 && strncasecmp(expr, "escapelatex", 11) == 0) - nq = op_eval_function_escape_latex(mq, input); + else if (exprsz == 12 && strncasecmp(expr, "escapegemini", 12) == 0) + nq = op_eval_function_escape_gemini(mq, input, 0); + else if (exprsz == 16 && strncasecmp(expr, "escapegeminiline", 16) == 0) + nq = op_eval_function_escape_gemini(mq, input, 1); else if (exprsz == 10 && strncasecmp(expr, "escapehtml", 10) == 0) nq = op_eval_function_escape_html(mq, input); else if (exprsz == 14 && strncasecmp(expr, "escapehtmlattr", 14) == 0) nq = op_eval_function_escape_htmlattr(mq, input); else if (exprsz == 13 && strncasecmp(expr, "escapehtmlurl", 13) == 0) nq = op_eval_function_escape_htmlurl(mq, input); + else if (exprsz == 11 && strncasecmp(expr, "escapelatex", 11) == 0) + nq = op_eval_function_escape_latex(mq, input); else if (exprsz == 10 && strncasecmp(expr, "escaperoff", 10) == 0) nq = op_eval_function_escape_roff(mq, input, 0); else if (exprsz == 14 && strncasecmp(expr, "escaperoffline", 14) == 0)