diff options
| author | Alexander M Pickering <alex@cogarr.net> | 2024-09-05 14:17:11 -0500 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2024-09-05 14:17:11 -0500 |
| commit | d78fd5db8895075216c3dc1675512118dcfc47b6 (patch) | |
| tree | feaaf990522bd00480376d1b9a90117b07f631b5 | |
| parent | 5d4044ca0f92efbcb7f5c395bc75909910aef120 (diff) | |
| download | libctemplates-d78fd5db8895075216c3dc1675512118dcfc47b6.tar.gz libctemplates-d78fd5db8895075216c3dc1675512118dcfc47b6.tar.bz2 libctemplates-d78fd5db8895075216c3dc1675512118dcfc47b6.zip | |
| -rw-r--r-- | README.md | 550 |
1 files changed, 303 insertions, 247 deletions
@@ -27,7 +27,9 @@ instructions on creating and sending git patches [here](http://cogarr.net/source Run the make file. libctemplates should compile on any system with a c99 complaint c compiler. If you are on linux, cd into the root directory and run - make && make install +```bash +make && make install +``` <section id="Usage"></section> ## Usage @@ -35,7 +37,9 @@ complaint c compiler. If you are on linux, cd into the root directory and run Just include the ctemplates.h header and make sure you're linking against libctemplates.a, for example: - gcc main.c -lctemplates +```bash +gcc main.c -lctemplates +``` <section id="Quick refrence"></section> ## Quick reference @@ -52,7 +56,9 @@ libctemplates.a, for example: ### Functions - int TMPL_alloc_template(char* template_string, struct TMPL_templates **t) +```c +int TMPL_alloc_template(char* template_string, struct TMPL_templates **t) +``` Creates a template from the given string. This can be pretty expensive so try to only do it once for each template you need, and call render() @@ -60,65 +66,89 @@ as many times as you need on that template. If there was a problem building the template, the returned value will be non-zero, and you can retrive an error message with `TMPL_err()` - void TMPL_free_template(struct TMPL_templates* template) +```c +void TMPL_free_template(struct TMPL_templates* template) +``` Frees a previously allocated template. - struct TMPL_varlist* TMPL_alloc_varlist() +```c +struct TMPL_varlist* TMPL_alloc_varlist() +``` Allocates a variable list that you can add variables and loops to. - void TMPL_free_varlist(struct TMPL_varlist* varlist) +```c +void TMPL_free_varlist(struct TMPL_varlist* varlist) +``` Frees a previously allocated varlist, and any loops that have been added. - struct TMPL_loop* TMPL_alloc_loop() +```c +struct TMPL_loop* TMPL_alloc_loop() +``` Allocates a loop that you can add varlists to. - void TMPL_free_loop(struct TMPL_loop* loop) +```c +void TMPL_free_loop(struct TMPL_loop* loop) +``` Frees a previously allocated loop, and any varlists that have been added. - void TMPL_add_var_to_varlist(struct TMPL_varlist* vl, char* name, char* value) +```c +void TMPL_add_var_to_varlist(struct TMPL_varlist* vl, char* name, char* value) +``` Adds a variable to a variable list - void TMPL_add_loop_to_varlist(struct TMPL_varlist* vl,char* name,struct TMPL_loop* loop) +```c +void TMPL_add_loop_to_varlist(struct TMPL_varlist* vl,char* name,struct TMPL_loop* loop) +``` Adds a loop to a varlist - void TMPL_add_varlist_to_loop(struct TMPL_loop* l, struct TMPL_varlist* vl) +```c +void TMPL_add_varlist_to_loop(struct TMPL_loop* l, struct TMPL_varlist* vl) +``` Adds a varlist that should be used one iteration through the loop - char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* vl, size_t* length) +```c +char* TMPL_render(struct TMPL_templates* t, struct TMPL_varlist* vl, size_t* length) +``` Turns a template and varlist into a string. The returned char\* should NOT be freed. The returned char\* is only valid until TMPL\_render() is called again. If you need it even after TMPL\_render() is called, copy it. The length of the returned string is put into `length` to help in copying. ### Templating tags - <TMPL_VAR name="variable_name" default="default_value"> +```html +<TMPL_VAR name="variable_name" default="default_value"> +``` Substitutes a variable, with an optional default value. Prints the variable named "variable\_name" in it's place, if no variable named "variable\_name" is found, the default printed. If there is not variable name, and no default value, an error is logged, and it is expanded to an empty string. (If you need to have nothing printed when the variable does not exist, you should use `default=""` to keep the error log clean. - <TMPL_IF name="variable_name" value="check_value"> - : - <TMPL_ELSEIF name="variable_name" value="check_value"> - : - <TMPL_ELSE> - : - <TMPL_END> +```html +<TMPL_IF name="variable_name" value="check_value"> +: +<TMPL_ELSEIF name="variable_name" value="check_value"> +: +<TMPL_ELSE> +: +<TMPL_END> +``` Branching statements, checks if a variable is equal to a constant value. Checks if the variable "variable\_name" contains the string "check\_value". There is currently no way to check if two variables are equal. Elseif and Else clauses are optional. All `TMPL_IF` statements must be closed with `TMPL_END`. You can use `TMPL_IF` and `TMPL_ELSEIF` to check for a variable's existence by not specifying a `value` parameter. - <TMPL_LOOP name="loop_name"> - : - <TMPL_END> +```html +<TMPL_LOOP name="loop_name"> +: +<TMPL_END> +``` Loop statements, I bet you can't figure out what this does. @@ -133,107 +163,117 @@ At it's most simple, libctemplates just copies whatever template you give it. For example: *main.c* - - #include <ctemplate.h> - #include <stdio.h> - #include <stdlib.h> - - char* template = "Hello, world!"; - - int main(){ - struct TMPL_templates* t = TMPL_alloc_template(template); - if(t == NULL){ - printf("Failed to compile\n"); - exit(-1); - } - struct TMPL_varlist* vl = TMPL_alloc_varlist(); - size_t dummy; - char* output = TMPL_render(t,vl,&dummy); - printf("Output: %s\n",output); - printf("Length: %d\n",(int)dummy); - TMPL_free_varlist(vl); - TMPL_free_template(t); - return 0; + +```c +#include <ctemplate.h> +#include <stdio.h> +#include <stdlib.h> + +char* template = "Hello, world!"; + +int main(){ + struct TMPL_templates* t = TMPL_alloc_template(template); + if(t == NULL){ + printf("Failed to compile\n"); + exit(-1); } + struct TMPL_varlist* vl = TMPL_alloc_varlist(); + size_t dummy; + char* output = TMPL_render(t,vl,&dummy); + printf("Output: %s\n",output); + printf("Length: %d\n",(int)dummy); + TMPL_free_varlist(vl); + TMPL_free_template(t); + return 0; +} +``` *output* - Output: Hello, world! - Length: 13 +```plaintext +Output: Hello, world! +Length: 13 +``` ### Variable substitution *template.html* - Value is:<TMPL_VAR name="varname" default="optional default"> +```html +Value is:<TMPL_VAR name="varname" default="optional default"> +``` *main.c* - #include <ctemplates.h> - #include <stdio.h> - #include <stdlib.h> - - int main(){ - /* - It usually helps to seperate the template from the - C code. You need to read in a file though. - Try to only call TMPL_alloc_template() once for each - template you have, and then use TMPL_render() whenever - you need to use them. - */ - FILE* fp = fopen("template.html","r"); - if(fp == NULL){ - printf("Failed to open file!\n"); - exit(-1); - } - fseek(fp,0,SEEK_END); - size_t file_len = ftell(fp); - fseek(fp,0,SEEK_SET); - char template[file_len]; - fread(template,sizeof(char),file_len,fp); - - struct TMPL_templates* t; - struct TMPL_varlist* vl; - size_t dummy; - - /* - Render the template without a variable named "varname" - This will use the variable's default, if it has one. - If the variable has no default and is not supplied a value, - it subsitutes an empty string and logs an error message. You - can check for error messages by checking if template->error is - non-zero. You can retrive error messages with TMPL_get_error() - */ - t = TMPL_alloc_template(template); - vl = TMPL_alloc_varlist(); - char* without_variable = TMPL_render(t,vl,&dummy); - printf("Without variable:\n%s\n",without_variable); - TMPL_free_template(t); - TMPL_free_varlist(vl); - - /* - Now render a template with a variable, use the - TMPL_add_var_to_varlist() to supply the template with - variables. - */ - t = TMPL_alloc_template(template); - vl = TMPL_alloc_varlist(); - TMPL_add_var_to_varlist(vl,"varname","Hello, world!"); - char* with_variable = TMPL_render(t,vl,&dummy); - printf("With variable:\n%s\n",with_variable); - TMPL_free_template(t); - TMPL_free_varlist(vl); - - return 0; +```c +#include <ctemplates.h> +#include <stdio.h> +#include <stdlib.h> + +int main(){ + /* + It usually helps to seperate the template from the + C code. You need to read in a file though. + Try to only call TMPL_alloc_template() once for each + template you have, and then use TMPL_render() whenever + you need to use them. + */ + FILE* fp = fopen("template.html","r"); + if(fp == NULL){ + printf("Failed to open file!\n"); + exit(-1); } + fseek(fp,0,SEEK_END); + size_t file_len = ftell(fp); + fseek(fp,0,SEEK_SET); + char template[file_len]; + fread(template,sizeof(char),file_len,fp); + + struct TMPL_templates* t; + struct TMPL_varlist* vl; + size_t dummy; + + /* + Render the template without a variable named "varname" + This will use the variable's default, if it has one. + If the variable has no default and is not supplied a value, + it subsitutes an empty string and logs an error message. You + can check for error messages by checking if template->error is + non-zero. You can retrive error messages with TMPL_get_error() + */ + t = TMPL_alloc_template(template); + vl = TMPL_alloc_varlist(); + char* without_variable = TMPL_render(t,vl,&dummy); + printf("Without variable:\n%s\n",without_variable); + TMPL_free_template(t); + TMPL_free_varlist(vl); + + /* + Now render a template with a variable, use the + TMPL_add_var_to_varlist() to supply the template with + variables. + */ + t = TMPL_alloc_template(template); + vl = TMPL_alloc_varlist(); + TMPL_add_var_to_varlist(vl,"varname","Hello, world!"); + char* with_variable = TMPL_render(t,vl,&dummy); + printf("With variable:\n%s\n",with_variable); + TMPL_free_template(t); + TMPL_free_varlist(vl); + + return 0; +} +``` *output* - Without variable: - Value is:optional default +```plaintext +Without variable: +Value is:optional default - With variable: - Value is:Hello, world! +With variable: +Value is:Hello, world! +``` ### If/Elseif/Else @@ -241,87 +281,93 @@ If and elseif statements check if strings are the same. They do a strcmp(), so b *template.html* - What happened: - <TMPL_IF name="varname" value="1234"> - "varname" was "1234" - <TMPL_ELSEIF name="var2" value="pass"> - "var2" was "pass" - <TMPL_ELSE> - "varname" was not "1234", and "var2" was not "pass" - <TMPL_END> +```html +What happened: +<TMPL_IF name="varname" value="1234"> + "varname" was "1234" +<TMPL_ELSEIF name="var2" value="pass"> + "var2" was "pass" +<TMPL_ELSE> + "varname" was not "1234", and "var2" was not "pass" +<TMPL_END> +``` *main.c* - #include <stdlib.h> - #include <stdio.h> - #include <ctemplates.h> - - int main(){ - /* - Same as before, just read a file in - */ - FILE* fp = fopen("template.html","r"); - if(fp == NULL){ - printf("Failed to open file!\n"); - exit(-1); - } - fseek(fp,0,SEEK_END); - size_t file_len = ftell(fp); - rewind(fp); - char template[file_len]; - fread(template,sizeof(char),file_len,fp); - - /* - No need to rebuild the template each time, - just alloc it once. - */ - struct TMPL_templates* t = TMPL_alloc_template(template); - struct TMPL_varlist* vl; - - /* - If the variable the "if" or "elseif" is looking for dosn't exist, - the condition is considered false. - */ - vl = TMPL_alloc_varlist(); - size_t dummy; - char* without_variable = TMPL_render(t,vl,&dummy); - printf("Without variable:\n%s\n",without_variable); - - /* - Add a variable to make the second condition true, and reprint - After we call TMPL_render() again, whatever pointer it returned - last time may have been freed. Be sure to copy it into your own - buffer if you still need it. - */ - TMPL_add_var_to_varlist(vl,"var2","pass"); - size_t dummy; - char* with_one = TMPL_render(t,vl,&dummy); - printf("With 1 variable:\n%s\n",with_one); - - /* - Always be sure to free things! - */ - TMPL_free_varlist(vl); - TMPL_free_template(t); - - return 0; +```c +#include <stdlib.h> +#include <stdio.h> +#include <ctemplates.h> + +int main(){ + /* + Same as before, just read a file in + */ + FILE* fp = fopen("template.html","r"); + if(fp == NULL){ + printf("Failed to open file!\n"); + exit(-1); } + fseek(fp,0,SEEK_END); + size_t file_len = ftell(fp); + rewind(fp); + char template[file_len]; + fread(template,sizeof(char),file_len,fp); + + /* + No need to rebuild the template each time, + just alloc it once. + */ + struct TMPL_templates* t = TMPL_alloc_template(template); + struct TMPL_varlist* vl; + + /* + If the variable the "if" or "elseif" is looking for dosn't exist, + the condition is considered false. + */ + vl = TMPL_alloc_varlist(); + size_t dummy; + char* without_variable = TMPL_render(t,vl,&dummy); + printf("Without variable:\n%s\n",without_variable); + + /* + Add a variable to make the second condition true, and reprint + After we call TMPL_render() again, whatever pointer it returned + last time may have been freed. Be sure to copy it into your own + buffer if you still need it. + */ + TMPL_add_var_to_varlist(vl,"var2","pass"); + size_t dummy; + char* with_one = TMPL_render(t,vl,&dummy); + printf("With 1 variable:\n%s\n",with_one); + + /* + Always be sure to free things! + */ + TMPL_free_varlist(vl); + TMPL_free_template(t); + + return 0; +} +``` *output* - Without variable: +```plaintext +Without variable: - What happened: - - "varname" was not "1234", and "var2" was not "pass" +What happened: + + "varname" was not "1234", and "var2" was not "pass" - With 1 variable: +With 1 variable: - What happened: - - "var2" was "pass" +What happened: + + "var2" was "pass" +``` Notice that the tabs in the template are preserved in the output. This is not @@ -334,85 +380,91 @@ only variables that have been added to the namespace are accessible in the loop. *template.html* - What happened: - <TMPL_LOOP name="myloop"> - This time through the loop, my variable is <TMPL_VAR name="loopvar"> - <TMPL_END> +```html +What happened: +<TMPL_LOOP name="myloop"> + This time through the loop, my variable is <TMPL_VAR name="loopvar"> +<TMPL_END> +``` *main.c* - #include <stdlib.h> - #include <stdio.h> - #include <ctemplates.h> - - int main(){ - /* - Same as before - */ - FILE* fp = fopen("template.html","r"); - if(fp == NULL){ - printf("Failed to open file!\n"); - exit(-1); - } - fseek(fp,0,SEEK_END); - size_t file_len = ftell(fp); - rewind(fp); - char template[file_len]; - fread(template,sizeof(char),file_len,fp); - - /* - Same as before - */ - struct TMPL_templates* t = TMPL_alloc_template(template); - struct TMPL_varlist* vl = TMPL_alloc_varlist(); - - /* - Now create a loop variable and add some things to it. - This is usually not as verbose as it looks here, since you'll - usually do this in a C loop. - */ - struct TMPL_loop* loop = TMPL_alloc_loop(); - - struct TMPL_varlist* first = TMPL_alloc_varlist(); - TMPL_add_var_to_varlist(first,"loopvar","first"); - TMPL_add_varlist_to_loop(loop,first); - - struct TMPL_varlist* second = TMPL_alloc_varlist(); - TMPL_add_var_to_varlist(second,"loopvar","second"); - TMPL_add_varlist_to_loop(loop,second); - - struct TMPL_varlist* third = TMPL_alloc_varlist(); - TMPL_add_var_to_varlist(third,"loopvar","third"); - TMPL_add_varlist_to_loop(loop,third); - - /* - Remember to add the loop to the varlist you'll eventually - pass to TMPL_render() with the correct name. - */ - TMPL_add_loop_to_varlist(vl,"myloop",loop); - size_t size; - char* output = TMPL_render(t,vl,&size); - printf("Output:\n%s\n",output); - - /* - When freeing a varlist, any loops it has are automatically - also freed. When freeing a loop, any varlists it contains - are also automatically freed. This means you only need to - free your top-level varlist! - */ - TMPL_free_varlist(vl); - TMPL_free_template(t); +```c +#include <stdlib.h> +#include <stdio.h> +#include <ctemplates.h> + +int main(){ + /* + Same as before + */ + FILE* fp = fopen("template.html","r"); + if(fp == NULL){ + printf("Failed to open file!\n"); + exit(-1); } + fseek(fp,0,SEEK_END); + size_t file_len = ftell(fp); + rewind(fp); + char template[file_len]; + fread(template,sizeof(char),file_len,fp); + + /* + Same as before + */ + struct TMPL_templates* t = TMPL_alloc_template(template); + struct TMPL_varlist* vl = TMPL_alloc_varlist(); + + /* + Now create a loop variable and add some things to it. + This is usually not as verbose as it looks here, since you'll + usually do this in a C loop. + */ + struct TMPL_loop* loop = TMPL_alloc_loop(); + + struct TMPL_varlist* first = TMPL_alloc_varlist(); + TMPL_add_var_to_varlist(first,"loopvar","first"); + TMPL_add_varlist_to_loop(loop,first); + + struct TMPL_varlist* second = TMPL_alloc_varlist(); + TMPL_add_var_to_varlist(second,"loopvar","second"); + TMPL_add_varlist_to_loop(loop,second); + + struct TMPL_varlist* third = TMPL_alloc_varlist(); + TMPL_add_var_to_varlist(third,"loopvar","third"); + TMPL_add_varlist_to_loop(loop,third); + + /* + Remember to add the loop to the varlist you'll eventually + pass to TMPL_render() with the correct name. + */ + TMPL_add_loop_to_varlist(vl,"myloop",loop); + size_t size; + char* output = TMPL_render(t,vl,&size); + printf("Output:\n%s\n",output); + + /* + When freeing a varlist, any loops it has are automatically + also freed. When freeing a loop, any varlists it contains + are also automatically freed. This means you only need to + free your top-level varlist! + */ + TMPL_free_varlist(vl); + TMPL_free_template(t); +} +``` *output* - Output: - What happened: - This time through the loop, my variable is first - This time through the loop, my variable is second - This time through the loop, my variable is theird - Done! +```plaintext +Output: +What happened: +This time through the loop, my variable is first +This time through the loop, my variable is second +This time through the loop, my variable is third +Done! +``` <!-- Some styling, make it pretty! --> <style> @@ -427,3 +479,7 @@ pre{ border-radius:5; } </style> +<!-- Highlight.js --> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css"> +<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> +<script>hljs.highlightAll();</script> |
