diff options
Diffstat (limited to 'html.c')
-rw-r--r-- | html.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/html.c b/html.c new file mode 100644 index 0000000..1f78adb --- /dev/null +++ b/html.c @@ -0,0 +1,303 @@ +#include <sys/types.h> +#include <sys/stat.h> + +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "gemtext.h" + +static int +_case_text(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_text_strlen(line); + *outlen += 7; /* <p></p> */ + + app = realloc(*out, (*outlen+1)); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<p>", (*outlen+1)); + strlcat(*out, gemtext_text_string(line), (*outlen)+1); + strlcat(*out, "</p>", (*outlen)+1); + + return 0; +} + +static int +_case_link(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_link_link_strlen(line); + *outlen += gemtext_link_label_strlen(line); + *outlen += 22; /* <p><a href=""></a></p> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<p><a href=\"", (*outlen)+1); + strlcat(*out, gemtext_link_link_string(line), (*outlen)+1); + strlcat(*out, "\">", (*outlen)+1); + if (gemtext_link_has_label(line)) + strlcat(*out, gemtext_link_label_string(line), (*outlen)+1); + strlcat(*out, "</a></p>", (*outlen)+1); + + return 0; +} + +static int +_case_pre(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_pre_strlen(line); + *outlen += 18; /* <p><pre></pre></p> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<p><pre>", (*outlen)+1); + strlcat(*out, gemtext_pre_string(line), (*outlen)+1); + strlcat(*out, "</pre></p>", (*outlen)+1); + + return 0; +} + +static int +_case_h1(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_h1_strlen(line); + *outlen += 9; /* <h1></h1> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<h1>", (*outlen)+1); + strlcat(*out, gemtext_h1_string(line), (*outlen)+1); + strlcat(*out, "</h1>", (*outlen)+1); + + return 0; +} + +static int +_case_h2(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_h2_strlen(line); + *outlen += 9; /* <h2></h2> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<h2>", (*outlen)+1); + strlcat(*out, gemtext_h2_string(line), (*outlen)+1); + strlcat(*out, "</h2>", (*outlen)+1); + + return 0; +} + +static int +_case_h3(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_h3_strlen(line); + *outlen += 9; /* <h3></h3> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<h3>", (*outlen)+1); + strlcat(*out, gemtext_h3_string(line), (*outlen)+1); + strlcat(*out, "</h3>", (*outlen)+1); + + return 0; +} + +static int +_case_ul(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_ul_strlen(line); + *outlen += 9; /* <li></li> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<li>", (*outlen)+1); + strlcat(*out, gemtext_ul_string(line), (*outlen)+1); + strlcat(*out, "</li>", (*outlen)+1); + + return 0; +} + +static int +_case_qt(struct gemtext *line, char **out, size_t *outlen) +{ + char *app; + + *outlen += gemtext_qt_strlen(line); + *outlen += 25; /* <blockquote></blockquote> */ + + app = realloc(*out, (*outlen)+1); + if (app == NULL) + return -1; + *out = app; + + strlcat(*out, "<blockquote>", (*outlen)+1); + strlcat(*out, gemtext_qt_string(line), (*outlen)+1); + strlcat(*out, "</blockquote>", (*outlen)+1); + + return 0; +} + +int +gemtext_list_encode_to_html(struct gemtext **list, char **out, size_t *outlen) +{ + char *app; + int i; + int ulindic; + + *out = NULL; + *outlen = 0; + ulindic = 0; + + *out = malloc(1); + if (*out == NULL) + return -1; + *out[0] = '\0'; /* for strlcat() */ + + for (i = 0; list[i] != NULL; i++) { + if (gemtext_type(list[i]) != GEMTEXT_UL && ulindic) { + *outlen += 5; /* </ul> */ + app = realloc(*out, (*outlen)+1); + if (app == NULL) { + free(*out); + return -1; + } + *out = app; + strlcat(*out, "</ul>", (*outlen)+1); + ulindic = 0; + } + switch (gemtext_type(list[i])) { + case GEMTEXT_TEXT: + if (_case_text(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_LINK: + if (_case_link(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_PRE: + if (_case_pre(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_H1: + if (_case_h1(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_H2: + if (_case_h2(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_H3: + if (_case_h3(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_UL: + if (!ulindic) { + *outlen += 4; /* <ul> */ + app = realloc(*out, (*outlen)+1); + if (app == NULL) { + free(*out); + return -1; + } + *out = app; + strlcat(*out, "<ul>", (*outlen)+1); + ulindic = 1; + } + if (_case_ul(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + case GEMTEXT_QT: + if (_case_qt(list[i], out, outlen) == -1) { + free(*out); + return -1; + } + break; + } + } + + return 0; +} + +int +gemtext_list_encode_to_html_fd(struct gemtext **list, int fd) +{ + char *out; + size_t len; + + if (gemtext_list_encode_to_html(list, &out, &len) == -1) + return -1; + if (write(fd, out, len) == -1) { + free(out); + return -1; + } + free(out); + + return 0; +} + +int +gemtext_list_encode_to_html_file(struct gemtext **list, const char *file) +{ + int fd; + + fd = open(file, O_WRONLY|O_TRUNC|O_CREAT); + if (fd == -1) + return -1; + /* file does not have to be owned by user, so errors are expected */ + fchmod(fd, 0644); + if (gemtext_list_encode_to_html_fd(list, fd) == -1) { + close(fd); + return -1; + } + close(fd); + + return 0; +} |