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("")) == -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