slweb

Једноставни генератор статичких веб страна
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 513313fae285a4e8d9c76c9ae38b2a4f7381186b
родитељ 0f3b3518209b85d5d63c8677139476686b595f4f
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Thu, 13 Jan 2022 11:51:21 +0100

Finish WIP includes with YAML

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
Mslweb.c | 315+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Atest01.html | 38++++++++++++++++++++++++++++++++++++++
измењених датотека: 2, додавања: 275(+), брисања: 78(-)

diff --git a/slweb.c b/slweb.c @@ -166,6 +166,9 @@ slweb_cleanup() return 0; } +int add_css(FILE* output, BOOL output_yaml); +int simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, + KeyValue** pvars); int slweb_parse(FILE* output, const char* source_filename, const u8* buffer, const BOOL body_only, const BOOL parent_read_yaml, const BOOL read_yaml_macros_and_links); @@ -349,10 +352,10 @@ print_command(FILE* output, const char* command, const u8* pass_arguments[], if (!command || !pass_arguments) exit(error(EINVAL, (u8*)"print_command: Invalid argument")); - pid_t pid = 0; + pid_t pid = 0; + int pstatus = 0; int arg_pipe_fds[2]; int output_pipe_fds[2]; - int pstatus = 0; fflush(output); pipe(arg_pipe_fds); @@ -398,10 +401,12 @@ print_command(FILE* output, const char* command, const u8* pass_arguments[], CALLOC(cmd_output_line, u8, BUFSIZE); while (!feof(cmd_output)) { + char* eol = NULL; + if (!fgets((char*)cmd_output_line, BUFSIZE, cmd_output)) continue; - char* eol = strchr((char*)cmd_output_line, '\n'); + eol = strchr((char*)cmd_output_line, '\n'); if (eol) *eol = 0; @@ -549,10 +554,9 @@ process_git_log(FILE* output) } int -process_stylesheet(FILE* output, const u8* css_filename, - BOOL read_yaml_macros_and_links) +process_stylesheet(FILE* output, const u8* css_filename, BOOL output_yaml) { - if (read_yaml_macros_and_links) + if (output_yaml) print_output(output, "stylesheet: %s\n", css_filename); else print_output(output, @@ -563,8 +567,7 @@ process_stylesheet(FILE* output, const u8* css_filename, } int -process_inline_stylesheet(FILE* output, const u8* css_filename, - BOOL read_yaml_macros_and_links) +process_inline_stylesheet(FILE* output, const u8* css_filename, BOOL output_yaml) { FILE* css = NULL; u8* bufline = NULL; @@ -578,9 +581,11 @@ process_inline_stylesheet(FILE* output, const u8* css_filename, (u8*)"process_inline_stylesheet: No such file: %s", css_filename)); - print_output(output, "process_inline_stylesheet:read_yml: %s\n", - read_yaml_macros_and_links ? "TRUE" : "FALSE"); - if (read_yaml_macros_and_links) + /* + *print_output(output, "process_inline_stylesheet:read_yml: %s\n", + * read_yaml_macros_and_links ? "TRUE" : "FALSE"); + */ + if (output_yaml) { print_output(output, "inline-stylesheet: %s\n", css_filename); output_firstcol = TRUE; @@ -1287,6 +1292,8 @@ process_include(FILE* output, const u8* token, char* pinclude_filename = NULL; pid_t pid = 0; int pstatus = 0; + int arg_pipe_fds[2]; + int output_pipe_fds[2]; if (!input_filename) return warning(1, (u8*)"Cannot use 'include' in stdin"); @@ -1296,21 +1303,76 @@ process_include(FILE* output, const u8* token, (u8*)"Directive 'include' requires" " an argument")); - print_output(output, "== Before include %s==\n", - read_yaml_macros_and_links ? "(read yaml) " : ""); + /* + *print_output(output, "== Before include %s==\n", + * read_yaml_macros_and_links ? "(read yaml) " : ""); + */ fflush(output); + pipe(arg_pipe_fds); + pipe(output_pipe_fds); pid = fork(); if (pid > 0) /* parent */ { + FILE* child_output = NULL; + u8* child_output_line = NULL; + close(arg_pipe_fds[PIPE_READ_INDEX]); + close(output_pipe_fds[PIPE_WRITE_INDEX]); + if (!(child_output + = fdopen(output_pipe_fds[PIPE_READ_INDEX], "r"))) + { + wait(&pstatus); + exit(error(1, (u8*)"Cannot fdopen")); + } + + CALLOC(child_output_line, u8, BUFSIZE); + while (!feof(child_output)) + { + char* eol = NULL; + + if (!fgets((char*)child_output_line, BUFSIZE, + child_output)) + continue; + + eol = strchr((char*)child_output_line, '\n'); + if (eol) + *eol = 0; + /* + *print_output(output, "parent: got line [%s]\n", + * child_output_line); + */ + simple_parse_yaml_line(child_output_line, &vars, + &vars_count, &pvars); + } + free(child_output_line); + fclose(child_output); + wait(&pstatus); - print_output(output, "== After include %s==\n", - read_yaml_macros_and_links ? "(read yaml) " : ""); + + /* + *print_output(output, "== After include %s==\n", + * read_yaml_macros_and_links ? "(read yaml) " : ""); + */ } else if (pid == 0) /* child */ { - char* filename = NULL; + char* filename = NULL; + FILE* input = NULL; + FILE* output = stdout; + u8* buffer = NULL; + size_t buffer_size = 0; + int result = 0; + FILE* child_output = NULL; + /* + *ULLONG saved_state = ST_NONE; + */ + prctl(PR_SET_PDEATHSIG, SIGTERM); + close(arg_pipe_fds[PIPE_WRITE_INDEX]); + close(output_pipe_fds[PIPE_READ_INDEX]); + if (!(child_output + = fdopen(output_pipe_fds[PIPE_WRITE_INDEX], "w"))) + exit(error(1, (u8*)"Cannot fdopen")); CALLOC(include_filename, char, BUFSIZE); pinclude_filename = include_filename; @@ -1329,15 +1391,6 @@ process_include(FILE* output, const u8* token, include_filename); free(include_filename); - FILE* input = NULL; - FILE* output = stdout; - u8* buffer = NULL; - size_t buffer_size = 0; - int result = 0; - /* - *ULLONG saved_state = ST_NONE; - */ - read_file_into_buffer(&input, &buffer, &buffer_size, filename, &input_dirname); @@ -1364,14 +1417,17 @@ process_include(FILE* output, const u8* token, */ state = ST_NONE; in_included_file = TRUE; - print_output(output, "process_include:child(%s):read_yml==%s\n", - filename, - read_yaml_macros_and_links ? "TRUE" : "FALSE"); + /* + *print_output(output, + *"process_include:child(%s):read_yml==%s\n", filename, + * read_yaml_macros_and_links ? "TRUE" : "FALSE"); + */ /* First pass: read YAML, macros and links */ - result = slweb_parse(output, filename, buffer, - read_yaml_macros_and_links, TRUE, TRUE); + result = slweb_parse(output, filename, buffer, TRUE, + read_yaml_macros_and_links, TRUE); + add_css(child_output, TRUE); if (result) goto process_include_child_cleanup; @@ -1383,8 +1439,8 @@ process_include(FILE* output, const u8* token, current_inline_footnote = 0; /* Second pass: parse and output */ - result = slweb_parse(output, filename, buffer, - read_yaml_macros_and_links, TRUE, FALSE); + result = slweb_parse(output, filename, buffer, TRUE, + read_yaml_macros_and_links, FALSE); /* *state = saved_state; @@ -1394,6 +1450,7 @@ process_include(FILE* output, const u8* token, slweb_cleanup(); free(filename); free(buffer); + fclose(child_output); exit(result); } else @@ -1591,7 +1648,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, state = ST_NONE; /* First pass: read YAML, macros and links */ - result = slweb_parse(output, filename, buffer, FALSE, TRUE, TRUE); + result = slweb_parse(output, filename, buffer, TRUE, + FALSE, TRUE); if (result) { @@ -1610,7 +1668,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, current_inline_footnote = 0; /* Second pass: parse and output */ - result = slweb_parse(output, filename, buffer, FALSE, TRUE, FALSE); + result = slweb_parse(output, filename, buffer, TRUE, + FALSE, FALSE); state = saved_state; @@ -2465,23 +2524,26 @@ begin_html_and_head(FILE* output) } int -add_css(FILE* output, BOOL read_yaml_macros_and_links) +add_css(FILE* output, BOOL output_yaml) { if (!vars) return -1; KeyValue* pvars = vars; - print_output(output, "=== add_css ===\n"); + /* + *print_output(output, "=== add_css ===\n"); + */ while (pvars < vars + vars_count) { if (!strcmp((char*)pvars->key, "stylesheet")) - process_stylesheet(output, pvars->value, - read_yaml_macros_and_links); + process_stylesheet(output, pvars->value, output_yaml); else if (!strcmp((char*)pvars->key, "inline-stylesheet")) process_inline_stylesheet(output, pvars->value, - read_yaml_macros_and_links); + output_yaml); pvars++; } - print_output(output, "=== /add_css ===\n"); + /* + *print_output(output, "=== /add_css ===\n"); + */ return 0; } @@ -2608,6 +2670,87 @@ end_body_and_html(FILE* output) } int +simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, + KeyValue** pvars) +{ + u8* token = NULL; + u8* ptoken = NULL; + u8* var_key = NULL; + const u8* pline = line; + BOOL in_arg = FALSE; + + if (!line || !vars || !vars_count || !pvars) + exit(error(EINVAL, + (u8*)"simple_parse_yaml_line: Invalid argument")); + + CALLOC(token, u8, BUFSIZE); + ptoken = token; + *ptoken = 0; + while (*pline) + { + if (!in_arg && *pline == ':') + { + in_arg = TRUE; + *ptoken = 0; + var_key = (u8*)strdup((char*)token); + if (!var_key) + exit(error(ENOMEM, + (u8*)"Memory allocation failed (out of " + "memory?)")); + ptoken = token; + *ptoken = 0; + pline++; + } + else if (*pline == ' ' || *pline == '\t') + pline++; + else + *ptoken++ = *pline++; + } + if (*token) + *ptoken = 0; + if (var_key && *var_key && *token) + { + BOOL found = FALSE; + KeyValue* cvar = NULL; + + cvar = *vars; + while (!found && cvar != *vars + *vars_count) + { + if (!strcmp((const char*)cvar->key, (const char*)var_key) + && cvar->value_size + && !strcmp((const char*)cvar->value, + (const char*)token)) + found = TRUE; + cvar++; + } + if (!found) + { + (*vars_count)++; + if (!*vars) + { + CALLOC(*vars, KeyValue, *vars_count); + *pvars = *vars; + } + else + { + REALLOCARRAY(*vars, KeyValue, *vars_count); + *pvars = *vars + *vars_count - 1; + } + CALLOC((*pvars)->key, u8, KEYSIZE); + strncpy((char*)(*pvars)->key, (char*)var_key, + KEYSIZE - 1); + (*pvars)->value_size = strlen((char*)token) + 1; + CALLOC((*pvars)->value, u8, (*pvars)->value_size); + strncpy((char*)(*pvars)->value, (char*)token, + (*pvars)->value_size); + } + } + free(var_key); + free(token); + return 0; +} + +int slweb_parse(FILE* output, const char* source_filename, const u8* buffer, const BOOL body_only, const BOOL parent_read_yaml, const BOOL read_yaml_macros_and_links) @@ -2690,24 +2833,38 @@ slweb_parse(FILE* output, const char* source_filename, const u8* buffer, pfootnotes = footnotes; lineno = 0; - if (in_included_file) - { - if (parent_read_yaml) - { - print_output(output, "slweb_parse:add_css[1]\n"); - add_css(output, parent_read_yaml); - } - } - else + /* + *print_output(output, + * "slweb_parse: " + * "read_yaml_macros_and_links=%s\n", + * read_yaml_macros_and_links ? "TRUE" : "FALSE"); + */ + /* + *if (in_included_file) + *{ + * if (parent_read_yaml && read_yaml_macros_and_links) + * { + * print_output(output, + *"slweb_parse(%s):add_css[1]\n", source_filename); + *add_css(output, parent_read_yaml); + * } + *} + *else + *{ + */ + if (!read_yaml_macros_and_links && !body_only) { - if (!read_yaml_macros_and_links && !body_only) - { - begin_html_and_head(output); - print_output(output, "slweb_parse:add_css[2]\n"); - add_css(output, read_yaml_macros_and_links); - end_head_start_body(output); - } + begin_html_and_head(output); + /* + *print_output(output, "slweb_parse(%s):add_css[2]\n", + * source_filename); + */ + add_css(output, FALSE); + end_head_start_body(output); } + /* + *} + */ if (!read_yaml_macros_and_links) begin_article(output, source_filename, link_prefix, @@ -2868,8 +3025,8 @@ do_line: if (strlen((char*)pline) > 1 && *(pline + 1) == '~') { u8* entity = (u8*)"&nbsp;"; - /* Handle ~~ within footnotes, headings and link text - * specially */ + /* Handle ~~ within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -2909,8 +3066,8 @@ do_line: else if (strlen((char*)pline) > 1 && *(pline + 1) == '-') { u8* entity = (u8*)"&#8209;"; - /* Handle ~- within footnotes, headings and link text - * specially */ + /* Handle ~- within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -2949,8 +3106,8 @@ do_line: } else { - /* Handle ~ within footnotes, headings and link text - * specially */ + /* Handle ~ within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -3022,8 +3179,8 @@ do_line: } else if (!ANY(state, ST_PRE | ST_TAG | ST_YAML)) { - /* Handle ` within footnotes, headings and link text - * specially */ + /* Handle ` within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -3129,8 +3286,8 @@ do_line: if (strlen((char*)pline) > 1 && *(pline + 1) == '_') { - /* Handle __ within footnotes, headings and link text - * specially */ + /* Handle __ within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -3172,8 +3329,8 @@ do_line: } else { - /* Handle _ within footnotes, headings and link text - * specially */ + /* Handle _ within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -3325,8 +3482,8 @@ do_line: } else if (pline_len > 1 && *(pline + 1) == '*') { - /* Handle ** within footnotes, headings and link text - * specially */ + /* Handle ** within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -3368,8 +3525,8 @@ do_line: } else { - /* Handle * within footnotes, headings and link text - * specially */ + /* Handle * within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -3610,8 +3767,8 @@ do_line: if (strlen((char*)pline) > 1 && *(pline + 1) == '|') { - /* Handle || within footnotes, headings and link text - * specially */ + /* Handle || within footnotes, headings and link + * text specially */ if (ANY(state, ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) @@ -4901,7 +5058,8 @@ main(const int argc, const char** argv) else { error(EINVAL, - (u8*)"Invalid argument: --%s", + (u8*)"Invalid " + "argument: --%s", arg); return usage(); } @@ -4927,7 +5085,8 @@ main(const int argc, const char** argv) break; default: error(EINVAL, - (u8*)"Invalid argument: -%c", + (u8*)"Invalid " + "argument: -%c", c); return usage(); } @@ -5017,7 +5176,7 @@ main(const int argc, const char** argv) inline_footnote_count = 0; /* First pass: read YAML, macros and links */ - result = slweb_parse(output, input_filename, buffer, FALSE, body_only, + result = slweb_parse(output, input_filename, buffer, body_only, FALSE, TRUE); if (result) @@ -5032,7 +5191,7 @@ main(const int argc, const char** argv) current_inline_footnote = 0; /* Second pass: parse and output */ - result = slweb_parse(output, input_filename, buffer, FALSE, body_only, + result = slweb_parse(output, input_filename, buffer, body_only, FALSE, FALSE); slweb_cleanup(); diff --git a/test01.html b/test01.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<title></title> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1" /> +<meta name="generator" content="slweb" /> +<style> +h1 +{ + color: blue; +} +</style> +<style> +h1 +{ + color: red; +} + +h2 +{ + color: green; +} +</style> +</head> +<body> +<h1 id="heading-1">Include test</h1> + +<p>Including test02.</p> + + +<h2 id="heading-1">Included file</h2> + +<p>This is the file test02.slw.</p> + + +</body> +</html>