added --template, --begin and --end
This commit is contained in:
@@ -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. [Using the command-line interface](#using-the-command-line-interface)
|
||||||
1. [--style](#--style)
|
1. [--style](#--style)
|
||||||
1. [--prefix](#--prefix)
|
1. [--prefix](#--prefix)
|
||||||
|
1. [--template, --begin and --end](#--template---begin-and---end)
|
||||||
1. [Using the library](#using-the-library)
|
1. [Using the library](#using-the-library)
|
||||||
1. [License](#license)
|
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`.
|
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 `<c2html>` and `</c2html>` 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
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<title>My awesome web page!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Hey, look at this C code:
|
||||||
|
<c2html>
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
print("Hello, world!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
</c2html>
|
||||||
|
Crazy, isn't it??
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
the command
|
||||||
|
```sh
|
||||||
|
c2html --input index.html --output processed_index.html --template
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<title>My awesome web page!</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Hey, look at this C code:
|
||||||
|
<div class="c2h-code">
|
||||||
|
<div class="c2h-code-inner">
|
||||||
|
<table>
|
||||||
|
<tr><td>1</td><td></td></tr>
|
||||||
|
<tr><td>2</td><td><span class="c2h-kword c2h-kword-int">int</span> <span class="c2h-identifier c2h-fdeclname">main</span>()</td></tr>
|
||||||
|
<tr><td>3</td><td>{</td></tr>
|
||||||
|
<tr><td>4</td><td> <span class="c2h-identifier c2h-fcallname">print</span>(<span class="c2h-val-str">"Hello, world!\n"</span>);</td></tr>
|
||||||
|
<tr><td>5</td><td> <span class="c2h-kword c2h-kword-return">return</span> <span class="c2h-val-int">0</span>;</td></tr>
|
||||||
|
<tr><td>6</td><td>}</td></tr>
|
||||||
|
<tr><td>7</td><td> </td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Crazy, isn't it??
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 `<c2html>` and `</c2html>` 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
|
## Using the library
|
||||||
The library only exports one function
|
The library only exports one function
|
||||||
```c
|
```c
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "c2html.h"
|
#include "c2html.h"
|
||||||
|
|
||||||
@@ -99,6 +100,101 @@ static char *load_file(const char *file, long *size)
|
|||||||
return data;
|
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 = "<c2html>";
|
||||||
|
|
||||||
|
if(token_end == NULL)
|
||||||
|
token_end = "</c2html>";
|
||||||
|
|
||||||
|
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 <c2html> 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,
|
static int fileconv(FILE *in_fp, FILE *out_fp,
|
||||||
const char *style_file,
|
const char *style_file,
|
||||||
const char *prefix)
|
const char *prefix)
|
||||||
@@ -172,23 +268,38 @@ static void print_help(FILE *fp, char *name) {
|
|||||||
" to the generated output, you get the highliting!\n"
|
" to the generated output, you get the highliting!\n"
|
||||||
"\n"
|
"\n"
|
||||||
" The usage is:\n"
|
" The usage is:\n"
|
||||||
" $ %s [-i file.c] [-o file.html] [--style file.css] [-p <prefix>]\n"
|
" $ %s [-i file.c] [-o file.html] [--style file.css] [-p <prefix>] [-t [-s <token>] [-e <token>]]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" ..and here's a table of all available options:\n"
|
" ..and here's a table of all available options:\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -h, --help Show this message\n"
|
" -h, --help Show this message\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -i, --input file.c File containing C code that needs\n"
|
" -i, --input file.c File containing C code that needs\n"
|
||||||
" to be converted\n"
|
" to be converted\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -o, --output file.html HTML file where the output will be\n"
|
" -o, --output file.html HTML file where the output will be\n"
|
||||||
" written to\n"
|
" written to\n"
|
||||||
"\n"
|
"\n"
|
||||||
" --style style.css CSS stylesheet that will be added\n"
|
" --style style.css CSS stylesheet that will be added\n"
|
||||||
" to the HTML output\n"
|
" to the HTML output\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -p, --prefix <prefix> The prefix of the HTML element's\n"
|
" -p, --prefix <prefix> The prefix of the HTML element's\n"
|
||||||
" class names. The default is \"c2h-\"\n"
|
" class names. The default is \"c2h-\"\n"
|
||||||
|
"\n"
|
||||||
|
" -t, --template Only highlight the substrings of the\n"
|
||||||
|
" input between the <c2html> and </c2html>\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 <string> Specify the start of each substring to\n"
|
||||||
|
" be converted. It only work when --template\n"
|
||||||
|
" is also specified\n"
|
||||||
|
"\n"
|
||||||
|
" -e, --end <string> Specify the end of each substring to be\n"
|
||||||
|
" be converted. It only works when --template\n"
|
||||||
|
" is also specified\n"
|
||||||
"\n", name);
|
"\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +309,10 @@ int main(int argc, char **argv)
|
|||||||
char *input_file = NULL,
|
char *input_file = NULL,
|
||||||
*output_file = NULL,
|
*output_file = NULL,
|
||||||
*style_file = NULL,
|
*style_file = NULL,
|
||||||
|
*templ_begin = NULL,
|
||||||
|
*templ_end = NULL,
|
||||||
*prefix = NULL;
|
*prefix = NULL;
|
||||||
|
bool template = 0;
|
||||||
|
|
||||||
for(int i = 1; i < argc; i += 1) {
|
for(int i = 1; i < argc; i += 1) {
|
||||||
if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||||
@@ -227,6 +341,28 @@ int main(int argc, char **argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
prefix = argv[i];
|
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")) {
|
} else if(!strcmp(argv[i], "--style")) {
|
||||||
i += 1;
|
i += 1;
|
||||||
if(i == argc || argv[i][0] == '-') {
|
if(i == argc || argv[i][0] == '-') {
|
||||||
@@ -267,8 +403,16 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rescode = fileconv(in_fp, out_fp,
|
int rescode;
|
||||||
style_file, prefix);
|
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_stdin) fclose(in_fp);
|
||||||
if(!use_stdout) fclose(out_fp);
|
if(!use_stdout) fclose(out_fp);
|
||||||
|
|||||||
Reference in New Issue
Block a user