чување 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:
| M | defs.h | | | 5 | +++-- |
| M | slweb.1.in | | | 15 | +++++++++------ |
| M | slweb.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);