Skip to content

Instantly share code, notes, and snippets.

@skeeto
Created December 29, 2025 19:56
Show Gist options
  • Select an option

  • Save skeeto/e2096e45d209bad7eb3464396dadcd2a to your computer and use it in GitHub Desktop.

Select an option

Save skeeto/e2096e45d209bad7eb3464396dadcd2a to your computer and use it in GitHub Desktop.
Basic template engine
// Basic template engine
// $ cc -o template template.c
// $ printf '<title>{{title}}</title>\nHello, <b>{{name}}</b>!\n' >index.html
// $ ./template <index.html title='Example Page' name=skeeto
// Ref: https://old.reddit.com/r/C_Programming/comments/1pypl5t
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char key[256] = {};
int len = 0;
int depth = 0;
int dir = 0;
for (int c; (c = getchar()) != EOF;) {
switch (c) {
default:
switch (depth) {
case 2:
if (len < (int)sizeof(key)) {
key[len++] = (char)c;
}
break;
case 1:
if (dir < 0) {
printf("{{%.*s}", len, key);
} else {
putchar('{');
}
// fallthrough
default:
putchar(c);
depth = 0;
}
break;
case '{':
switch (depth) {
case 0:
case 1:
depth++;
len = 0;
break;
case 2:
printf("{{%.*s", len, key);
len = 0;
break;
}
dir = +1;
break;
case '}':
switch (depth) {
case 1:
if (dir != -1) {
fputs("{}", stdout);
} else {
for (int i = 1; i < argc; i++) {
char *arg = argv[i];
char *end = strchr(arg, '=');
if (end &&
end-arg==len &&
!memcmp(key, arg, (size_t)len)) {
fputs(end+1, stdout);
}
}
}
len = depth = 0;
break;
case 2:
depth--;
break;
default:
putchar('}');
}
dir = -1;
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment