slweb

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

чување d3bf607d6d8db2e723afb46e8d1cce37ab321c1d
родитељ 414e2aeedb07b5d653034cff1e640aab61999a07
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Thu, 13 Jul 2023 16:34:53 +0200

Add listonly to {incdir}; add timestamp format for listonly

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

Diffstat:
Mdefs.h | 5+++--
Mslweb.1.in | 15+++++++++------
Mslweb.c | 183++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
измењених датотека: 3, додавања: 152(+), брисања: 51(-)

diff --git a/defs.h b/defs.h @@ -32,8 +32,9 @@ #define SMALL_ARGSIZE 256 #define DATEBUFSIZE 12 -static const char timestamp_format[] = "d.m.y"; -static const char timestamp_output_ext[] = ".html"; +static const char article_timestamp_format[] = "d.m.y"; +static const char list_timestamp_format[] = "y-m-d"; +static const char timestamp_output_ext[] = ".html"; static const char CMD_GIT_LOG[] = "xargs"; static const char* CMD_GIT_LOG_ARGS[] = {"xargs", "-I{}", "git", "log", "-1", diff --git a/slweb.1.in b/slweb.1.in @@ -597,11 +597,11 @@ about the current commit would be impossible). . .IP \[bu] .BR "Subdirectory inclusion (blogging directive)" . -The command \fC{incdir "\f[CI]dirname\fC" \f[CI]num\fC =\f[CI]macroname\fC}\fR -.RI ( num -and +The command \fC{incdir "\f[CI]dirname\f[CR]" \f[CI]num\f[CR] +=\f[CI]macroname\f[CR] listonly}\fR +.RI ( num , .I macroname -are optional) will be expanded as follows: +and the literal \[lq]listonly\[rq] are optional) will be expanded as follows: . .RS .nr list 1 1 @@ -866,8 +866,11 @@ If present, this variable, assumed to be in datetime format, will be parsed to determine the timestamp in permalinks generated by the .I incdir -directive. The actual values used depend on the source-level constant -.IR timestamp_format . +directive. The actual values used depend on the source-level constants +.I article_timestamp_format +(for \fCincdir\fR without the argument \[lq]listonly\[rq]) and +.I list_timestamp_format +(for \fCincdir\fR with the argument \[lq]listonly\[rq]). . .IP \[bu] .BR ext-in-permalink . diff --git a/slweb.c b/slweb.c @@ -167,6 +167,7 @@ slweb_cleanup() } int add_css(FILE* output, int output_yaml); +u8* format_date(const u8* date_arg, const char* timestamp_format); 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, @@ -254,8 +255,7 @@ set_basedir(char** basedir, size_t* basedir_size, const char* arg) REALLOC(*basedir, char, *basedir_size); } strcpy(*basedir, arg); - *(*basedir + arg_len) = 0; - basedir_len = strlen(*basedir); + basedir_len = strlen(*basedir); if (*(*basedir + basedir_len - 1) == '/') *(*basedir + basedir_len - 1) = 0; @@ -1570,7 +1570,7 @@ int process_incdir_subdir(FILE* output, const char* subdirname, const u8* link_prefix, const int details_open, const u8* macro_body, const u8* footer_permalink_text, const char* permalink_url, - int ext_in_permalink) + const int ext_in_permalink, const int list_only) { struct dirent** namelist; struct dirent** pnamelist; @@ -1578,11 +1578,16 @@ process_incdir_subdir(FILE* output, const char* subdirname, long names_output; char* abs_subdirname = NULL; - print_output(output, "<li>\n<details%s>\n<summary>", - details_open ? " open" : ""); + if (list_only) + ; /*print_output(output, "<ul>\n");*/ + else + print_output(output, "<li>\n<details%s>\n<summary>", + details_open ? " open" : ""); if (macro_body) print_output(output, "%s", macro_body); - print_output(output, "%s</summary>\n<div>\n", subdirname); + + if (!list_only) + print_output(output, "%s</summary>\n<div>\n", subdirname); CALLOC(abs_subdirname, char, BUFSIZE); snprintf(abs_subdirname, BUFSIZE, "%s/%s/%s", basedir, incdir, @@ -1603,7 +1608,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, { int pstatus = 0; - print_output(output, "<article>\n"); + if (!list_only) + print_output(output, "<article>\n"); fflush(output); pid_t pid = fork(); @@ -1612,18 +1618,27 @@ process_incdir_subdir(FILE* output, const char* subdirname, wait(&pstatus); else if (pid == 0) { - FILE* input = NULL; - FILE* output = stdout; - u8* buffer = NULL; - size_t buffer_size = 0; - int result = 0; - ULLONG saved_state = ST_NONE; - char* filename = NULL; - - set_basedir(&basedir, &basedir_size, abs_subdirname); + FILE* input = NULL; + FILE* output = stdout; + u8* buffer = NULL; + size_t buffer_size = 0; + int result = 0; + ULLONG saved_state = ST_NONE; + char* filename = NULL; + char* link = NULL; + u8* title = NULL; + u8* date = NULL; + u8* var_incdir_only_summary = NULL; + int incdir_only_summary = 0; + u8* formatted_date = NULL; + + if (!strcmp(basedir, ".")) + set_basedir(&basedir, &basedir_size, + abs_subdirname); CALLOC(filename, char, BUFSIZE); snprintf(filename, BUFSIZE, "%s/%s", abs_subdirname, (*pnamelist)->d_name); + link = strip_ext(filename); read_file_into_buffer(&input, &buffer, &buffer_size, filename, &input_dirname); @@ -1651,19 +1666,58 @@ process_incdir_subdir(FILE* output, const char* subdirname, /* First pass: read YAML, macros and links */ result = slweb_parse(output, filename, buffer, 1, 1); - if (result) { - slweb_cleanup(); - free(filename); - free(buffer); - free(abs_subdirname); - while (names_total--) - free(namelist[names_total]); - free(namelist); - return result; + warning(1, (u8*)"slweb_parse error"); + goto incdir_subdir_child_cleanup; + } + + title = get_value(vars, vars_count, (u8*)"title"); + date = get_value(vars, vars_count, (u8*)"date"); + formatted_date + = format_date(date, list_timestamp_format); + if (!formatted_date) + exit(error(1, (u8*)"format_date error")); + + /* Have to temporarily reset this because of potential + * interaction with print_output */ + var_incdir_only_summary = get_value(vars, vars_count, + (u8*)"incdir-only-summary"); + incdir_only_summary = var_incdir_only_summary + && *var_incdir_only_summary == '1'; + if (list_only && var_incdir_only_summary) + var_incdir_only_summary[0] = '0'; + + if (list_only) + { + print_output(output, + "<li><a href=\"%s\">%s %s</a></li>\n", + permalink_url ? permalink_url : link, + formatted_date, title); + fflush(output); + /* ... and fallthrough to cleanup */ + } + else if (!result) + { + if (incdir_only_summary + && var_incdir_only_summary) + var_incdir_only_summary[0] = '1'; + goto skip_incdir_subdir_child_cleanup; } + incdir_subdir_child_cleanup: + slweb_cleanup(); + free(formatted_date); + free(link); + free(filename); + free(buffer); + free(abs_subdirname); + while (names_total--) + free(namelist[names_total]); + free(namelist); + exit(result); + + skip_incdir_subdir_child_cleanup: state = ST_INCDIR; current_footnote = 0; current_inline_footnote = 0; @@ -1675,8 +1729,6 @@ process_incdir_subdir(FILE* output, const char* subdirname, if (footer_permalink_text && incdir_only_summary) { - char* link = strip_ext(filename); - if (ext_in_permalink) strcat(link, timestamp_output_ext); @@ -1690,12 +1742,12 @@ process_incdir_subdir(FILE* output, const char* subdirname, "</footer>\n", permalink_url ? permalink_url : link, footer_permalink_text); - - free(link); } fflush(output); slweb_cleanup(); + free(formatted_date); + free(link); free(filename); free(buffer); free(abs_subdirname); @@ -1707,7 +1759,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, else exit(error(1, (u8*)"Fork failed")); - print_output(output, "</article>\n"); + if (!list_only) + print_output(output, "</article>\n"); pnamelist++; names_output++; @@ -1718,7 +1771,11 @@ process_incdir_subdir(FILE* output, const char* subdirname, free(namelist); free(abs_subdirname); - print_output(output, "</div>\n</details>\n</li>\n"); + if (list_only) + ; /*print_output(output, "</ul>\n");*/ + else + print_output(output, "</div>\n</details>\n</li>\n"); + output_firstcol = 0; return 0; } @@ -1739,6 +1796,7 @@ process_incdir(FILE* output, const u8* token, const u8* link_prefix, struct dirent** pnamelist; long names_output; int details_open = 1; + int list_only = 0; if (read_yaml_macros_and_links) return 0; @@ -1754,7 +1812,7 @@ process_incdir(FILE* output, const u8* token, const u8* link_prefix, exit(error(1, (u8*)"incdir: First argument not string")); incdir = strdup((char*)(arg + 1)); - *(incdir + strlen(incdir) - 1) = 0; + *(incdir + strlen(incdir) - 1) = 0; /* trim ending " */ arg = (u8*)strtok_r(NULL, " ", (char**)&saveptr); if (!arg) @@ -1791,6 +1849,17 @@ process_incdir(FILE* output, const u8* token, const u8* link_prefix, } } + if (!arg) + goto skip_arg; + arg = (u8*)strtok_r(NULL, " ", (char**)&saveptr); + if (arg) + { + if (!strcmp((const char*)arg, "listonly")) + list_only = 1; + else + exit(error(errno, (u8*)"incdir: Invalid argument")); + } + skip_arg: print_output(output, "<ul class=\"incdir\">\n"); @@ -1806,12 +1875,17 @@ skip_arg: names_output = 0; while (names_output < MIN(names_total, num)) { + /*if (list_only) + print_output(output, "<li>%s\n", + (*pnamelist)->d_name);*/ process_incdir_subdir(output, (*pnamelist)->d_name, link_prefix, details_open, macro_body, footer_permalink_text, - permalink_url, ext_in_permalink); + permalink_url, ext_in_permalink, list_only); details_open = 0; pnamelist++; names_output++; + /*if (list_only) + print_output(output, "</li>\n");*/ } while (names_total--) free(namelist[names_total]); @@ -1826,30 +1900,32 @@ skip_arg: int url_is_local(const char* url); -int -process_timestamp(FILE* output, const u8* link_prefix, const char* link, - const u8* permalink_macro, const u8* date, const int ext_in_permalink) +u8* +format_date(const u8* date_arg, const char* timestamp_format) { + const char* ptimestamp_format = NULL; u8* day = NULL; u8* month = NULL; u8* year = NULL; u8* formatted_date = NULL; u8* ptr = NULL; - const char* ptimestamp_format = NULL; - char* in_filename = NULL; - char* in_line = NULL; + u8* date = NULL; + + date = (u8*)strdup((const char*)date_arg); + if (!date) + goto format_date_cleanup; CALLOC(formatted_date, u8, DATEBUFSIZE); ptr = NULL; year = (u8*)strtok_r((char*)date, "-", (char**)&ptr); if (!year) - goto process_timestamp_cleanup; + goto format_date_cleanup; month = (u8*)strtok_r(NULL, "-", (char**)&ptr); if (!month) - goto process_timestamp_cleanup; + goto format_date_cleanup; day = (u8*)strtok_r(NULL, "T", (char**)&ptr); if (!day) - goto process_timestamp_cleanup; + goto format_date_cleanup; ptimestamp_format = timestamp_format; while (*ptimestamp_format) { @@ -1865,6 +1941,27 @@ process_timestamp(FILE* output, const u8* link_prefix, const char* link, ptimestamp_format++; } + return formatted_date; + +format_date_cleanup: + free(formatted_date); + free(date); + + return NULL; +} + +int +process_timestamp(FILE* output, const u8* link_prefix, const char* link, + const u8* permalink_macro, const u8* date, const int ext_in_permalink) +{ + char* in_filename = NULL; + char* in_line = NULL; + u8* formatted_date = NULL; + + formatted_date = format_date(date, article_timestamp_format); + if (!formatted_date) + goto process_timestamp_cleanup; + print_output(output, "<a href=\"%s%s%s%s\"" " class=\"timestamp\">%s%s</a>\n", @@ -1876,8 +1973,8 @@ process_timestamp(FILE* output, const u8* link_prefix, const char* link, link, ext_in_permalink ? timestamp_output_ext : "", permalink_macro ? (char*)permalink_macro : "", formatted_date); output_firstcol = 1; -process_timestamp_cleanup: +process_timestamp_cleanup: free(formatted_date); free(in_line); free(in_filename);