QUOTE: Kindness is always fashionable.

feat: Added header file and examples to README - ctl - Static template generator for C

ctl

Static template generator for C
git clone git@soophie.de:/srv/git/ctl
log | files | refs | readme

commit d523e0699a113bc63ce765f381b237621b0f969e
parent 09a6ec4d59f4030a1b1ff7a7b2646eb5292d47b3
Author: Sophie <info@soophie.de>
Date:   Sat, 14 Dec 2024 23:29:31 +0000

feat: Added header file and examples to README

Diffstat:
MMakefile | 1+
MREADME.md | 35+++++++++++++++++++++++++++++++++++
Asrc/libctl.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -7,6 +7,7 @@ build: src/*.c install: build cp ctl /usr/local/bin/ + cp libctl.h /usr/local/include/ rm ./ctl clean: diff --git a/README.md b/README.md @@ -1,3 +1,38 @@ # ctl Static template generator for C + +## Usage + +```html +<h1>Hello, % STRING(name) %!</h1> +<ul> + % for (int i = 0; i < len; i++) { % + <li>Item % NUMBER(i) %</li> + % } % +</ul> +``` + +```bash +ctl example.html > ctl_example.h +``` + +```c +#define LIB_CTL_IMPL +#include <libctl.h> + +#define CTL_OUT(out, x) { \ + str_append(out, x); \ +} +#define STRING(x) str_append(ctl_out, x); +#define NUMBER(x) { \ + str_appendf(ctl_out, "%d", x); \ +} + +void ctl_fn_example(char **ctl_out, ctl_ctx_t ctx) { + (void) ctx; + char *name = "world"; + int len = 10; + #include "ctl_example.h" +} +``` diff --git a/src/libctl.h b/src/libctl.h @@ -0,0 +1,57 @@ +#ifndef LIB_CTL_H +#define LIB_CTL_H + +#include <libhttp.h> +#include <libstr.h> + +typedef struct ctl_ctx ctl_ctx_t; +typedef void (*ctl_fn_t)(char **ctl_out, ctl_ctx_t ctx); + +struct ctl_ctx { + http_request_t *request; + char *title; + ctl_fn_t fn; +}; + +void ctl_init(ctl_fn_t fn); +http_response_t ctl_serve_page(http_request_t *request, const char *title, ctl_fn_t fn); +http_response_t ctl_serve_component(http_request_t *request, ctl_fn_t fn); + +#ifdef LIB_CTL_IMPL + +static ctl_fn_t ctl_fn = NULL; + +void ctl_init(ctl_fn_t fn) { + ctl_fn = fn; +} + +http_response_t ctl_serve_page(http_request_t *request, const char *title, ctl_fn_t fn) { + char *html = NULL; + ctl_ctx_t ctx = { + .request = request, + .title = title, + .fn = fn, + }; + ctl_fn(&html, ctx); + http_response_t response = http_response_create(HTTP_STATUS_OK); + http_header_set(&response, "Content-Type", "text/html"); + http_response_body(&response, html, strlen(html)); + free(html); + return response; +} + +http_response_t ctl_serve_component(http_request_t *request, ctl_fn_t fn) { + char *html = NULL; + ctl_ctx_t ctx = { + .request = request, + }; + fn(&html, ctx); + http_response_t response = http_response_create(HTTP_STATUS_OK); + http_header_set(&response, "Content-Type", "text/html"); + http_response_body(&response, html, strlen(html)); + free(html); + return response; +} + +#endif /* LIB_CTL_IMPL */ +#endif /* LIB_CTL_H */