чување 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:
| M | slweb.c | | | 315 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
| A | test01.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*)" ";
- /* 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*)"‑";
- /* 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>