ssnail

crappy and opinionated static site generator
git clone https://git.e1e0.net/ssnail.git
Log | Files | Refs | README | LICENSE

commit c45e2fd11bf7b654631b1135baf8c4e8abf48a66
parent a1999ca863950860606ac34999a48df10b614b4a
Author: Paco Esteban <paco@e1e0.net>
Date:   Wed,  1 Jul 2020 11:34:47 +0200

add automatic index generation

Diffstat:
Mhelpers.h | 1+
Mssnail.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) {