From 7ddf10843fa6c5247a809824344d391d7729fc73 Mon Sep 17 00:00:00 2001 From: Ali Fardan Date: Wed, 4 Nov 2020 07:24:41 +0300 Subject: html write html generator --- Makefile | 2 +- gemlog.h | 4 + html.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 40 +++++----- 4 files changed, 283 insertions(+), 19 deletions(-) create mode 100644 html.c diff --git a/Makefile b/Makefile index 9694799..100e062 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ OUT = gemlog PREFIX = /usr -OBJS = gemlog.o free.o main.o strlcpy.o strlcat.o +OBJS = gemlog.o html.o free.o main.o strlcpy.o strlcat.o MANPAGES = all: $(OUT) diff --git a/gemlog.h b/gemlog.h index 7c84039..e74058b 100644 --- a/gemlog.h +++ b/gemlog.h @@ -1,5 +1,6 @@ #define GEMLOG_TITLE_FILENAME "title" #define GEMLOG_CONTENT_FILENAME "content.gmi" +#define GEMLOG_CONTENT_HTML_FILENAME "content.html" struct gemlog_entry { char *title; @@ -16,6 +17,9 @@ size_t strlcat(char *, const char *, size_t); /* gemlog.c */ struct gemlog_entry **gemlog_readdir(const char *); +/* html.c */ +int gemlog_write_html(struct gemlog_entry **, const char *); + /* free.c */ void gemlog_entry_free(struct gemlog_entry *); void gemlog_entry_list_free(struct gemlog_entry **); diff --git a/html.c b/html.c new file mode 100644 index 0000000..fa83f2c --- /dev/null +++ b/html.c @@ -0,0 +1,256 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gemlog.h" + +/* TODO: allow user to specify custom header/footer */ +#define HTML_HEADER_BEGIN "" +#define HTML_HEADER_END "" +#define HTML_FOOTER "" + +static int +gemlog_write_html_text(struct gemtext *text, int fd) +{ + if (write(fd, "

", strlen("

")) == -1) + return -1; + if (write(fd, ((struct gemtext_text *)text)->text, strlen(((struct gemtext_text *)text)->text)) == -1) + return -1; + if (write(fd, "

\n", strlen("

\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_link(struct gemtext *text, int fd) +{ + if (write(fd, "

link, strlen(((struct gemtext_link *)text)->link)) == -1) + return -1; + if (write(fd, "\">", strlen("\">")) == -1) + return -1; + if (((struct gemtext_link *)text)->name) { + if (write(fd, ((struct gemtext_link *)text)->name, strlen(((struct gemtext_link *)text)->name)) == -1) + return -1; + } + if (write(fd, "

\n", strlen("

\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_pre(struct gemtext *text, int fd) +{ + if (write(fd, "

", strlen("

")) == -1)
+		return -1;
+	if (write(fd, ((struct gemtext_pre *)text)->text, strlen(((struct gemtext_pre *)text)->text)) == -1)
+		return -1;
+	if (write(fd, "

\n", strlen("

\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_h1(struct gemtext *text, int fd) +{ + if (write(fd, "

", strlen("

")) == -1) + return -1; + if (write(fd, ((struct gemtext_h1 *)text)->text, strlen(((struct gemtext_h1 *)text)->text)) == -1) + return -1; + if (write(fd, "

\n", strlen("\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_h2(struct gemtext *text, int fd) +{ + if (write(fd, "

", strlen("

")) == -1) + return -1; + if (write(fd, ((struct gemtext_h2 *)text)->text, strlen(((struct gemtext_h2 *)text)->text)) == -1) + return -1; + if (write(fd, "

\n", strlen("\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_h3(struct gemtext *text, int fd) +{ + if (write(fd, "

", strlen("

")) == -1) + return -1; + if (write(fd, ((struct gemtext_h3 *)text)->text, strlen(((struct gemtext_h3 *)text)->text)) == -1) + return -1; + if (write(fd, "

\n", strlen("\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_ul(struct gemtext *text, int fd) +{ + if (write(fd, "
  • ", strlen("
  • ")) == -1) + return -1; + if (write(fd, ((struct gemtext_ul *)text)->text, strlen(((struct gemtext_ul *)text)->text)) == -1) + return -1; + if (write(fd, "
  • \n", strlen("\n")) == -1) + return -1; + return 0; +} + +static int +gemlog_write_html_qt(struct gemtext *text, int fd) +{ + if (write(fd, "
    ", strlen("
    ")) == -1) + return -1; + if (write(fd, ((struct gemtext_qt *)text)->text, strlen(((struct gemtext_qt *)text)->text)) == -1) + return -1; + if (write(fd, "
    \n", strlen("
    \n")) == -1) + return -1; + return 0; +} + +int +gemlog_write_html(struct gemlog_entry **feed, const char *path) +{ + int i; + int x; + int ulindicator; + int fd; + char pathbuf[PATH_MAX+1]; + char fmtbuf[PATH_MAX+1]; + + if (mkdir(path, 0755) == -1) { + if (errno != EEXIST) + return -1; + } + + for (i = 0; feed[i] != NULL; i++) { + strlcpy(pathbuf, path, sizeof(pathbuf)); + strlcat(pathbuf, "/", sizeof(pathbuf)); + snprintf(fmtbuf, sizeof(fmtbuf), "%d", feed[i]->date.tm_year+1900); + strlcat(pathbuf, fmtbuf, sizeof(pathbuf)); + if (mkdir(pathbuf, 0755) == -1) { + if (errno != EEXIST) + return -1; + } + + strlcat(pathbuf, "/", sizeof(pathbuf)); + snprintf(fmtbuf, sizeof(fmtbuf), "%d", feed[i]->date.tm_mon+1); + strlcat(pathbuf, fmtbuf, sizeof(pathbuf)); + if (mkdir(pathbuf, 0755) == -1) { + if (errno != EEXIST) + return -1; + } + + strlcat(pathbuf, "/", sizeof(pathbuf)); + snprintf(fmtbuf, sizeof(fmtbuf), "%d", feed[i]->date.tm_mday); + strlcat(pathbuf, fmtbuf, sizeof(pathbuf)); + if (mkdir(pathbuf, 0755) == -1) { + if (errno != EEXIST) + return -1; + } + + strlcat(pathbuf, "/", sizeof(pathbuf)); + snprintf(fmtbuf, sizeof(fmtbuf), "%d", feed[i]->date.tm_hour); + strlcat(pathbuf, fmtbuf, sizeof(pathbuf)); + if (mkdir(pathbuf, 0755) == -1) { + if (errno != EEXIST) + return -1; + } + + strlcat(pathbuf, "/", sizeof(pathbuf)); + strlcat(pathbuf, GEMLOG_CONTENT_HTML_FILENAME, sizeof(pathbuf)); + fd = open(pathbuf, O_WRONLY|O_CREAT|O_TRUNC); + if (fd == -1) + return -1; + if (chmod(pathbuf, 0644) == -1) { + close(fd); + return -1; + } + + /* write header */ + if (write(fd, HTML_HEADER_BEGIN, strlen(HTML_HEADER_BEGIN)) == -1) { + close(fd); + return -1; + } + if (write(fd, "", strlen("<title>")) == -1) { + close(fd); + return -1; + } + if (write(fd, feed[i]->title, strlen(feed[i]->title)) == -1) { + close(fd); + return -1; + } + if (write(fd, "", strlen("")) == -1) { + close(fd); + return -1; + } + if (write(fd, HTML_HEADER_END, strlen(HTML_HEADER_END)) == -1) { + close(fd); + return -1; + } + + ulindicator = 0; + for (x = 0; feed[i]->content[x] != NULL; x++) { + if (ulindicator) { + if (gemtext_type(feed[i]->content[x]) != GEMTEXT_UL) { + if (write(fd, "\n", strlen("\n")) == -1) { + close(fd); + return -1; + } + ulindicator = 0; + } + } + switch (gemtext_type(feed[i]->content[x])) { + case GEMTEXT_TEXT: + gemlog_write_html_text(feed[i]->content[x], fd); + break; + case GEMTEXT_LINK: + gemlog_write_html_link(feed[i]->content[x], fd); + break; + case GEMTEXT_PRE: + gemlog_write_html_pre(feed[i]->content[x], fd); + break; + case GEMTEXT_H1: + gemlog_write_html_h1(feed[i]->content[x], fd); + break; + case GEMTEXT_H2: + gemlog_write_html_h2(feed[i]->content[x], fd); + break; + case GEMTEXT_H3: + gemlog_write_html_h3(feed[i]->content[x], fd); + break; + case GEMTEXT_UL: + if (!ulindicator) { + if (write(fd, "
      \n", strlen("
        \n")) == -1) { + close(fd); + return -1; + } + ulindicator = 1; + } + gemlog_write_html_ul(feed[i]->content[x], fd); + break; + case GEMTEXT_QT: + gemlog_write_html_qt(feed[i]->content[x], fd); + break; + default: + close(fd); + return -1; + } + } + close(fd); + } + + return 0; +} diff --git a/main.c b/main.c index 1d4577f..713fcae 100644 --- a/main.c +++ b/main.c @@ -14,8 +14,8 @@ _print_gemlog(struct gemlog_entry **list) char timestamp[50]; for (i = 0; list[i] != NULL; i++) { - strftime(timestamp, sizeof(timestamp), "%F: ", &(list[i]->date)); - printf("%s%s\n", timestamp, list[i]->title); + strftime(timestamp, sizeof(timestamp), "%F", &(list[i]->date)); + printf("%s %d: %s\n", timestamp, list[i]->date.tm_hour, list[i]->title); } } @@ -23,35 +23,29 @@ int main(int argc, char *argv[]) { struct gemlog_entry **log; - int aflag; - int hflag; + char *aflag; + char *hflag; int ch; - aflag = 0; - hflag = 0; + aflag = NULL; + hflag = NULL; - while ((ch = getopt(argc, argv, "ah")) != -1) { + while ((ch = getopt(argc, argv, "a:h:")) != -1) { switch (ch) { case 'a': - aflag = 1; + aflag = optarg; break; case 'h': - hflag = 1; + hflag = optarg; break; default: - fprintf(stderr, "Usage: %s <-a | -h> \n", argv[0]); + fprintf(stderr, "Usage: %s [-a file] [-h path] path\n", argv[0]); return 1; } } - if (aflag && hflag) - errx(1, "can't have -a and -h used simultaneously"); - if (!aflag && !hflag) { - fprintf(stderr, "Usage: %s <-a | -h> \n", argv[0]); - return 1; - } if (optind >= argc) { - fprintf(stderr, "Usage: %s <-a | -h> \n", argv[0]); + fprintf(stderr, "Usage: %s [-a file] [-h path] path\n", argv[0]); return 1; } @@ -59,7 +53,17 @@ main(int argc, char *argv[]) if (log == NULL) err(1, "gemlog_readdir"); - _print_gemlog(log); + if (!aflag && !hflag) + _print_gemlog(log); + +// if (aflag) { +// if (gemlog_write_atom(log, aflag) == -1) +// err(1, "gemlog_write_atom"); +// } + if (hflag) { + if (gemlog_write_html(log, hflag) == -1) + err(1, "gemlog_write_html"); + } gemlog_entry_list_free(log); return 0; -- cgit 1.4.1-2-gfad0