bpaul-webgen

html generator for bpaul.xyz
Log | Files | Refs | README

commit 0dea7100b0dabcbe8458ad1f913a194fa7ad7e97
parent 99f12d209eb0712cd3b02cf7ca1a146038550d9c
Author: benjamin paul <bpaul@bpaul.xyz>
Date:   Thu,  5 Aug 2021 21:32:55 +1000

everything

Diffstat:
MMakefile | 3+++
Mmain.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -10,3 +10,6 @@ all: $(NAME) $(NAME): $(OBJS) $(CC) $(LDFLAGS) -o $(NAME) $(OBJS) + +clean: + rm $(OBJS) $(NAME) diff --git a/main.c b/main.c @@ -1,10 +1,176 @@ +#include <dirent.h> +#include <errno.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +struct links_entry { + char *href; + int minx, miny; + int maxx, maxy; +}; + +size_t +line_count(const char *buf) { + const char *ptr = buf; + size_t cnt = 0; + while (*ptr != '\0') { + if (*ptr == '\n') cnt++; + ptr++; + } + return cnt; +} + +size_t +fsize(FILE *f) { + size_t len; + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + return len; +} + +char * +add_path(const char *dir, const char *name) { + size_t len = strlen(dir) + strlen(name) + 1; + char *buf = malloc(len); + memcpy(buf, dir, len); + + strcat(buf, name); + + return buf; +} + +void +iterate(DIR *d, const char *curdir) { + struct dirent *entry; + + /* If the end of the stream is reached, exit. + * Errno is reset to determine whether the NULL value means end of stream + * of error */ + errno = 0; + if ((entry = readdir(d)) == NULL) { + if (errno) { + perror("readdir"); + } + return; + } + + /* Skip dotfiles */ + if (entry->d_name[0] == '.') { goto skip; } + + if (entry->d_type == DT_REG) { + /* Only want files without file extensions */ + if (strrchr(entry->d_name, '.') != NULL) { goto skip; } + + char *buf = add_path(curdir, entry->d_name); + char *link = add_path(buf, ".links"); + char *html = add_path(buf, ".html"); + + /* Only want files which have a .links file */ + if (access(link, F_OK) != 0) { goto skip; } + + /* Read the .links file */ + char *links_buf; + size_t len; + FILE *linkf = fopen(link, "r"); + len = fsize(linkf); + links_buf = malloc(len); + fread(links_buf, 1, len, linkf); + + fclose(linkf); + + size_t entry_cnt; + entry_cnt = line_count(links_buf); + + /* Store each entry in the .links file into this struct array */ + struct links_entry *entries = + malloc(sizeof(struct links_entry) * entry_cnt); + + for (size_t i = 0; i < entry_cnt; i++, links_buf = NULL) { + entries[i].href = strtok(links_buf, " \n"); + entries[i].miny = atoi(strtok(NULL, " \n")); + entries[i].minx = atoi(strtok(NULL, " \n")); + entries[i].maxy = atoi(strtok(NULL, " \n")); + entries[i].maxx = atoi(strtok(NULL, " \n")); + } + + /* Read ascii file and add links when needed */ + FILE *f = fopen(buf, "r"); + char *c = malloc(1); + len = fsize(f); + int x=1, y=1; + int opened = 0; + for (size_t j = 0; j < len; j++) { + fread(c, 1, 1, f); + for (size_t i = 0; i < entry_cnt; i++) { + if (y >= entries[i].miny + && y <= entries[i].maxy + && x == entries[i].minx) { + printf("<a href=\"%s\">", entries[i].href); + opened = i; + } else if (y >= entries[i].miny + && y <= entries[i].maxy + && x == entries[i].maxx+1) { + printf("</a>"); + opened = 0; + } + } + x++; + if (*c == '\n') { + if (opened) { + while (x <= entries[opened].maxx+1) { putchar(' '); x++; } + printf("</a>"); + } + x=1; y++; + } + putchar(*c); + } + + free(buf); + free(link); + free(links_buf); + } else if (entry->d_type == DT_DIR) { + /* For directories, reiterate */ + + /* Create a string that appends the directory name to the current + * directory name */ + char *buf = add_path(curdir, entry->d_name); + strcat(buf, "/"); + + DIR *newd; + if ((newd = opendir((buf))) == NULL) { + perror("opendir"); + return; + } + + /* Iterate */ + iterate(newd, buf); + + free(buf); + } +skip: + seekdir(d, entry->d_off); + iterate(d, curdir); +} int main(int argc, char **argv) { if (argc < 2) { puts("Please specify a directory"); + exit(0); + } + + DIR *d; + + if ((d = opendir(argv[1])) == NULL) { + puts("That is not a valid directory"); + exit(0); } + strcat(argv[1], "/"); + iterate(d, argv[1]); return 0; }