commit c45e2fd11bf7b654631b1135baf8c4e8abf48a66
parent a1999ca863950860606ac34999a48df10b614b4a
Author: Paco Esteban <paco@e1e0.net>
Date: Wed, 1 Jul 2020 11:34:47 +0200
add automatic index generation
Diffstat:
M | helpers.h | | | 1 | + |
M | ssnail.c | | | 83 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
2 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/helpers.h b/helpers.h
@@ -19,6 +19,7 @@
#define HEADER "_header.html"
#define FOOTER "_footer.html"
+#define SHORT_DATE_Z 12
const struct ssnail_error *copy_file(const char *, const char *, int);
diff --git a/ssnail.c b/ssnail.c
@@ -57,9 +57,11 @@ LIST_HEAD(listhead, article) head;
__dead static void usage(void);
static void free_article(struct article *);
static void free_articleq(struct listhead *);
+static void add_index_entry(char **, struct article *);
struct article *init_article(void);
static struct article *populate_article_entry(char *, char *);
+static struct article *generate_index(char *, char *);
static const struct ssnail_error *process_dir(char *, char *, int);
static const struct ssnail_error *write_html(struct article *, char *, char *);
@@ -69,7 +71,7 @@ static const struct ssnail_error *gen_html(struct article *);
__dead static void
usage(void)
{
- fprintf(stderr, "usage: %s [-F] [-f footer] [-h header] "
+ fprintf(stderr, "usage: %s [-F] [-f footer] [-h header] [-i] "
"src_folder dst_folder\n", getprogname());
exit(1);
}
@@ -77,11 +79,12 @@ usage(void)
int
main(int argc, char *argv[])
{
- struct article *ap = NULL;
+ struct article *ap = NULL, *ip = NULL;
const struct ssnail_error *error = NULL;
- int ch, force = 0;
- char *header_tpl = NULL, *footer_tpl = NULL;
+ int ch, index = 0, force = 0;
+ char *header_tpl = NULL, *footer_tpl = NULL,
+ *index_listing = "";
header_tpl = strdup(HEADER);
if (header_tpl == NULL) {
@@ -94,7 +97,7 @@ main(int argc, char *argv[])
goto done;
}
- while ((ch = getopt(argc, argv, "Ff:h:")) != -1) {
+ while ((ch = getopt(argc, argv, "Ff:h:i")) != -1) {
switch (ch) {
case 'F':
force = 1;
@@ -115,6 +118,9 @@ main(int argc, char *argv[])
goto done;
}
break;
+ case 'i':
+ index = 1;
+ break;
default:
usage();
}
@@ -142,11 +148,26 @@ main(int argc, char *argv[])
if (error)
goto done;
}
+ if (strcmp(ap->type, "article") == 0) {
+ add_index_entry(&index_listing, ap);
+ }
+ }
+
+ if (index || force) {
+ printf("Generate index ... \n");
+ ip = generate_index(argv[1], index_listing);
+ if (ip == NULL) {
+ error = ssnail_error_msg(2, "index");
+ goto done;
+ }
+ error = write_html(ip, header_tpl, footer_tpl);
}
done:
free(header_tpl);
free(footer_tpl);
+ free(index_listing);
+ free_article(ip);
free_articleq(&head);
if (error) {
@@ -467,6 +488,58 @@ sort_articleq(struct listhead *h)
return NULL;
}
+static struct article *
+generate_index(char *dst_path, char *index_listing) {
+ assert(index_listing != NULL);
+
+ struct article *a = init_article();
+ struct tm *timeinfo;
+ time_t now;
+
+ if ((a->dst_path = build_full_path(dst_path, "index.html")) == NULL)
+ goto error;
+
+ a->author = malloc(LOGIN_NAME_MAX);
+ if ((getlogin_r(a->author, LOGIN_NAME_MAX)) != 0)
+ goto error;
+
+ time(&now);
+ timeinfo = localtime(&now);
+ a->date = malloc(SHORT_DATE_Z);
+ if (strftime(a->date, SHORT_DATE_Z, "%Y-%m-%d", timeinfo) == 0)
+ goto error;
+
+ if ((a->title = strdup("index")) == NULL)
+ goto error;
+ if ((a->type = strdup("index")) == NULL)
+ goto error;
+ int ret = asprintf(&a->html_content, "<ul>\n%s</ul>\n", index_listing);
+ if (ret == -1)
+ goto error;
+ a->htmlz = strlen(a->html_content);
+
+ return a;
+
+error:
+ free_article(a);
+ return NULL;
+}
+
+static void
+add_index_entry(char **index_listing, struct article *a)
+{
+ if (!index_listing || !a)
+ return;
+
+ const char *entry_format =
+ "%s<li><a href=\"%s\" title=\"%s\">%s</a></li>\n";
+ char *href = strstr(a->dst_path, "/");
+
+ if (href)
+ asprintf(index_listing, entry_format, *index_listing,
+ href, a->date, a->title);
+}
+
struct article *
init_article(void)
{