From 1333b9a5b1f75867401d4b7b02da0674173fa0e1 Mon Sep 17 00:00:00 2001 From: cozis Date: Mon, 9 May 2022 22:52:30 +0200 Subject: [PATCH] added --template, --begin and --end --- README.md | 67 ++++++++++++++++++++++ cli.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++---- makefile | 4 +- 3 files changed, 225 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 88ecd6a..e9c0d04 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ A default stylesheet you can use is provided in `style.css`. It's also well docu 1. [Using the command-line interface](#using-the-command-line-interface) 1. [--style](#--style) 1. [--prefix](#--prefix) + 1. [--template, --begin and --end](#--template---begin-and---end) 1. [Using the library](#using-the-library) 1. [License](#license) @@ -64,6 +65,72 @@ c2html --input file.c --output file.html --prefix myprefix- ``` in which case, identifiers will be generated with the `myprefix-identifier` class name instead of the usual `c2h-identifier`. +### --template, --begin and --end +When using the --template option, only the C code between the `` and `` tokens is processed. The remaining text is copied unchanged. This is useful when writing web pages containing C code. + +Lets say we have the following `index.html` +```html + + + + My awesome web page! + + + Hey, look at this C code: + +int main() +{ + print("Hello, world!\n"); + return 0; +} + + Crazy, isn't it?? + + +``` + +the command +```sh +c2html --input index.html --output processed_index.html --template +``` +will output +```html + + + + My awesome web page! + + + Hey, look at this C code: +
+
+ + + + + + + + +
1
2int main()
3{
4 print("Hello, world!\n");
5 return 0;
6}
7
+
+
+ + Crazy, isn't it?? + + +``` + +It's not possible to use `--style` in template mode. + +It's possible to change the tokens that delimit the C code using the `--begin` and `--end` options. Lets say we want to change `` and `` them to `{start}` and `{end}`. We would do it by adding: + +```sh +c2html --input index.html --output processed_index.html --template --begin "{start}" --end "{end}" +``` + +The `--begin` and `--end` can only be used alongside `--template`. + ## Using the library The library only exports one function ```c diff --git a/cli.c b/cli.c index 39f3246..7ecfd6b 100644 --- a/cli.c +++ b/cli.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "c2html.h" @@ -99,6 +100,101 @@ static char *load_file(const char *file, long *size) return data; } +static long find_substr_or_end(const char *str, long len, long i, const char *substr) +{ + long substr_len = strlen(substr); + + while(i < len && (i + substr_len > len || + strncmp(str + i, substr, substr_len))) + i += 1; + + return i; +} + +static int tmplconv(FILE *in_fp, FILE *out_fp, + const char *prefix, + const char *token_begin, + const char *token_end) +{ + if(prefix == NULL) + prefix = "c2h-"; + + if(token_begin == NULL) + token_begin = ""; + + if(token_end == NULL) + token_end = ""; + + const char *err; + + long input_size; + char *input = load_from_stream(in_fp, &input_size, &err); + if(input == NULL) { + fprintf(stderr, "Error: Failed to read input (%s)\n", err); + return -1; + } + + long i = 0; + while(1) { + + // Scan the substring that comes before the + // next occurrence of the token. + long off = i; + i = find_substr_or_end(input, input_size, i, token_begin); + long len = i - off; + + { + long written = fwrite(input + off, 1, len, out_fp); + if(written < len) { + fprintf(stderr, "Error: Failed to write to output\n"); + free(input); + return -1; + } + } + + if(i == input_size) + break; + + i += strlen(token_begin); // Consume the token. + assert(i <= input_size); + + // Now get to the ending token. + off = i; + i = find_substr_or_end(input, input_size, i, token_end); + len = i - off; + + { + long output_size; + char *output = c2html(input + off, len, prefix, + &output_size, &err); + if(output == NULL) { + fprintf(stderr, "Error: %s\n", err); + free(input); + return -1; + } + + long written = fwrite(output, 1, output_size, out_fp); + + free(output); + + if(written < len) { + fprintf(stderr, "Error: Failed to write to output\n"); + free(input); + return -1; + } + } + + if(i == input_size) + break; + + i += strlen(token_end); // Consume the token. + assert(i <= input_size); + } + + free(input); + return 0; +} + static int fileconv(FILE *in_fp, FILE *out_fp, const char *style_file, const char *prefix) @@ -172,23 +268,38 @@ static void print_help(FILE *fp, char *name) { " to the generated output, you get the highliting!\n" "\n" " The usage is:\n" - " $ %s [-i file.c] [-o file.html] [--style file.css] [-p ]\n" + " $ %s [-i file.c] [-o file.html] [--style file.css] [-p ] [-t [-s ] [-e ]]\n" "\n" " ..and here's a table of all available options:\n" "\n" - " -h, --help Show this message\n" + " -h, --help Show this message\n" "\n" - " -i, --input file.c File containing C code that needs\n" - " to be converted\n" + " -i, --input file.c File containing C code that needs\n" + " to be converted\n" "\n" - " -o, --output file.html HTML file where the output will be\n" - " written to\n" + " -o, --output file.html HTML file where the output will be\n" + " written to\n" "\n" - " --style style.css CSS stylesheet that will be added\n" - " to the HTML output\n" + " --style style.css CSS stylesheet that will be added\n" + " to the HTML output\n" "\n" - " -p, --prefix The prefix of the HTML element's\n" - " class names. The default is \"c2h-\"\n" + " -p, --prefix The prefix of the HTML element's\n" + " class names. The default is \"c2h-\"\n" + "\n" + " -t, --template Only highlight the substrings of the\n" + " input between the and \n" + " tokens. The rest is copied unchanged.\n" + " It's possible to change these tokens\n" + " with --begin and --end.\n" + " When using this mode, --style is ignored\n" + "\n" + " -b, --begin Specify the start of each substring to\n" + " be converted. It only work when --template\n" + " is also specified\n" + "\n" + " -e, --end Specify the end of each substring to be\n" + " be converted. It only works when --template\n" + " is also specified\n" "\n", name); } @@ -198,7 +309,10 @@ int main(int argc, char **argv) char *input_file = NULL, *output_file = NULL, *style_file = NULL, + *templ_begin = NULL, + *templ_end = NULL, *prefix = NULL; + bool template = 0; for(int i = 1; i < argc; i += 1) { if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { @@ -227,6 +341,28 @@ int main(int argc, char **argv) return -1; } prefix = argv[i]; + } else if(!strcmp(argv[i], "-t") || !strcmp(argv[i], "--template")) { + + template = 1; + + } else if(!strcmp(argv[i], "-b") || !strcmp(argv[i], "--begin")) { + + i += 1; + if(i == argc || argv[i][0] == '-') { + fprintf(stderr, "Error: Missing argument after %s\n", argv[i-1]); + return -1; + } + templ_begin = argv[i]; + + } else if(!strcmp(argv[i], "-e") || !strcmp(argv[i], "--end")) { + + i += 1; + if(i == argc || argv[i][0] == '-') { + fprintf(stderr, "Error: Missing argument after %s\n", argv[i-1]); + return -1; + } + templ_end = argv[i]; + } else if(!strcmp(argv[i], "--style")) { i += 1; if(i == argc || argv[i][0] == '-') { @@ -267,8 +403,16 @@ int main(int argc, char **argv) } } - int rescode = fileconv(in_fp, out_fp, - style_file, prefix); + int rescode; + if(template) { + if(style_file != NULL) + fprintf(stderr, "Warning: --style is ignored when using --template or -t\n"); + rescode = tmplconv(in_fp, out_fp, prefix, templ_begin, templ_end); + } else { + if(templ_begin != NULL || templ_end != NULL) + fprintf(stderr, "Warning: --begin and --end are ignored when not using --template\n"); + rescode = fileconv(in_fp, out_fp, style_file, prefix); + } if(!use_stdin) fclose(in_fp); if(!use_stdout) fclose(out_fp); diff --git a/makefile b/makefile index c0d12b8..5c13ddf 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ CC = gcc -CFLAGS = -Wall -Wextra -DNDEBUG -O3 #-DC2H_TIMING -# CFLAGS = -Wall -Wextra -g # When debugging +#CFLAGS = -Wall -Wextra -DNDEBUG -O3 #-DC2H_TIMING + CFLAGS = -Wall -Wextra -g # When debugging .PHONY: all install clean