Static template generator for C
git clone git://soophie.de/ductape
35
#define STRING DUC_WRITE36
```38
The template `example.html` is defined (could be any kind of language), which includes the previously defined macro header file, followed by the start of the template definition `TEMPLDEF` with the first parameter being the UID and succeeding with varies parameters which allow for injecting dynamic data. The end of the template is marked with `ENDTEMPL`. Inside the template definition. the content is rendered, while content outside will be ignored.38
The template `example.html` is defined (could be any kind of language), which includes the previously defined macro header file, followed by the start of the template definition `DUC_TEMPLDEF` with the first parameter being the UID and succeeding with varies parameters which allow for injecting dynamic data. The end of the template is marked with `DUC_ENDTEMPL`. Inside the template definition. the content is rendered, while content outside will be ignored.40
The symbol `%` marks the delimiter between template and C code. In order to use the delimiter in the template it needs to be repeated twice to escape the character. All parameters passed into the template are bound to the `ctx` variable.42
```html43
% #include "macro.h" %45
% TEMPLDEF(45
% DUC_TEMPLDEF(46
example,47
char *message;48
) %50
<p>% STRING(ctx->message) %</p>52
% ENDTEMPL %52
% DUC_ENDTEMPL %53
```55
The template can be compiled with the the installed CLI command `ductape`. Simply pass a list of files to the command and it will generate the corresponding `.h` (header) and `.so` (shared library) files based on the specified UID of the template.
31
const char *dl_path;32
} duc_templref_t;34
// @macro __TEMPLDEF_MACRO34
// @macro __DUC_TEMPLDEF_MACRO35
// @internal36
#define __TEMPLDEF_MACRO($name, $params) \36
#define __DUC_TEMPLDEF_MACRO($name, $params) \37
typedef struct { \38
$params \39
} $name##_t; \
69
return 0; \70
}72
// @macro __TEMPLDEF_HEADER72
// @macro __DUC_TEMPLDEF_HEADER73
// @internal74
#define __TEMPLDEF_HEADER($name, $params) \75
__TEMPLDEF_MACRO($name, $params) \74
#define __DUC_TEMPLDEF_HEADER($name, $params) \75
__DUC_TEMPLDEF_MACRO($name, $params) \76
\77
void duc_##$name(void *out, $name##_t *ctx);79
// @macro TEMPLDEF80
#define TEMPLDEF($name, $params) \81
__TEMPLDEF_MACRO($name, $params) \79
// @macro DUC_TEMPLDEF80
#define DUC_TEMPLDEF($name, $params) \81
__DUC_TEMPLDEF_MACRO($name, $params) \82
\83
void duc_##$name(void *out, $name##_t *ctx) {85
// @macro ENDTEMPL86
#define ENDTEMPL }85
// @macro DUC_ENDTEMPL86
#define DUC_ENDTEMPL }88
// @macro TEMPLBIND89
#define TEMPLBIND($name, $data, $dl_path) \88
// @macro DUC_TEMPLBIND89
#define DUC_TEMPLBIND($name, $data, $dl_path) \90
(duc_templref_t) { \91
.fn = $name##_render, \92
.data = $data, \93
.dl_path = $dl_path, \94
},96
// @macro INCLUDE97
#define INCLUDE($name) ctx->$name.fn(duc, ctx->$name.data, ctx->$name.dl_path);96
// @macro DUC_INCLUDE97
#define DUC_INCLUDE($name) ctx->$name.fn(duc, ctx->$name.data, ctx->$name.dl_path);99
#endif // _SO_DUC_H
16
#define DUC_SYM_SPLIT "%"17
#define DUC_SYM_SPLIT_ESCAPE DUC_SYM_SPLIT DUC_SYM_SPLIT18
#define DUC_SYM_WRITE "DUC_WRITE"19
#define DUC_SYM_TEMPLDEF "TEMPLDEF"20
#define DUC_SYM_ENDTEMPL "ENDTEMPL"21
#define DUC_SYM_TEMPLDEF_HEADER "__TEMPLDEF_HEADER"19
#define DUC_SYM_TEMPLDEF "DUC_TEMPLDEF"20
#define DUC_SYM_ENDTEMPL "DUC_ENDTEMPL"21
#define DUC_SYM_TEMPLDEF_HEADER "__DUC_TEMPLDEF_HEADER"23
#define DUC_TMP_C_PATH ".duc_tmp.c"24
#define DUC_TMP_SO_PATH ".duc_tmp.so"