/* C program that calls a shell script. * I probably should've made this wholly a shell script, but I * like writing in C, OK? * I don't do any fancy dynamic linking, so "$(CC) -o stek stek.c" * should be fine. Just make sure to add this to your $PATH. * "stek.c" */ #include #include #include #include #include #include #include #include #include #include #include #include "html.h" #define MAXPATHLEN 256 #define usage() fprintf(stderr, "Usage: stek (no trailing slash!)\n") #define TIMEOFFSET 60 int currtime; int traversedir(char *); bool ismd(char *, unsigned char); int mdtohtml(FILE *, struct dirent *); int main(int argc, char** argv) { if(argc != 2){ usage(); return -1; } currtime = time(NULL); char path[MAXPATHLEN]; strncpy(path, argv[1], MAXPATHLEN); path[strlen(path)] = '/'; if(traversedir(path) != 0){ perror("traversedir"); return -1; } return 0; } /* Traverse files in dir 'path'. Ignores symlinks, pipes, devices, socks */ int traversedir(char path[MAXPATHLEN]) { DIR* dir; struct dirent *ent; if((dir = opendir(path)) == NULL){ perror(path); return -1; } while((ent = readdir(dir)) != NULL){ /* NULL means end of directory */ bool isdir = false; if(ent->d_type == DT_DIR) isdir = true; /* Some file systems do not have support for d_type, so we need to * stat() the file to check if it is a directory. */ else if(ent->d_type == DT_UNKNOWN){ struct stat stbuf; stat(ent->d_name, &stbuf); isdir = S_ISDIR(stbuf.st_mode); } if(isdir) continue; #if defined(__APPLE__) && defined(__MACH__) if(ent->d_type == DT_REG && ismd(ent->d_name, ent->d_namlen)){ /* TODO: Probably a better way to deal with concatenating directory * names, it's very verbose right now. */ FILE* f; char *dname = ent->d_name; char *concat = malloc(strlen(path) + strlen(dname) + 1); memset(concat, 0, strlen(concat)); memcpy(concat, path, strlen(path)); strcat(concat, dname); struct stat currfile; if (stat(concat, &currfile) < 0){ free(concat); perror("stat"); return 1; } /* Only converts files that have been modified within 1 minute * of running stek. */ if ((((currtime) - currfile.st_atimespec.tv_sec) < TIMEOFFSET) && (f = fopen(concat, "r+"))){ mdtohtml(f, ent); free(concat); } #else // linux int len = strlen(ent->d_name); if(ent->d_type == DT_REG && ismd(ent->d_name, len)){ /* TODO: Probably a better way to deal with concatenating directory * names, it's very verbose right now. */ FILE* f; char *dname = ent->d_name; char *concat = malloc(strlen(path) + strlen(dname) + 1); memset(concat, 0, strlen(concat)); memcpy(concat, path, strlen(path)); strcat(concat, dname); struct stat currfile; if (stat(concat, &currfile) < 0){ free(concat); perror("stat"); return 1; } /* Only converts files that have been modified within 1 minute * of running stek. * NOTE: This particular field in Mac OS's struct stat should b * referred to as currfile.st_atimespec.tv_sec. Linux is fine * without changes. */ if ((((currtime) - currfile.st_atime) < TIMEOFFSET) && (f = fopen(concat, "r+"))){ mdtohtml(f, ent); free(concat); } #endif /* Maybe helpful for debugging. */ /* printf("when you ran stek: %d\n", currtime); printf("when %s was last modified: %ld\n", dname, currfile.st_atimespec.tv_sec); */ /* Skip file, it hasn't been touched within the last minute */ else { free(concat); continue; } } } return 0; } bool ismd(char* name, unsigned char len) { char *local = name; int nlen = strlen(".md") - 1; for(int i = 0; i < len - nlen; i++, local++){ if(strncmp(".md", local, 3) == 0) return true; else continue; } return false; } int mdtohtml(FILE *f, struct dirent *ent) { char buffer[MAXPATHLEN]; /* Should I be using system() here? Is there a more lightweight function? */ printf("Converting %s to .html file...\n", ent->d_name); snprintf(buffer, sizeof(buffer), "~/steklo/convert.sh %s", ent->d_name); return system(buffer); } -------------------------------------------------- # Shell script that is called by C program # "convert.sh" # TODO: Make this POSIX-compliant if possible. #! /usr/bin/env zsh set -e # You will probably want to change these globals... postdir="/Users/forest/Downloads/neocities-iwillneverbehappy/blog/" templatefile="./template.html" header="
\n

\" style=\"margin-bottom:1px;\">\n

" footer="
" currblog="/Users/forest/Downloads/neocities-iwillneverbehappy/blog23.html" xmlfile="/Users/forest/Downloads/neocities-iwillneverbehappy/feed.xml" tmp=".tmp.txt" blogurl="https://iwillneverbehappy.neocities.org/blog23#"; currdate="$(date '+%a, %d %b %Y %H:%M:%S')" currday="$(date '+%d')" if [[ $(pwd) == $postdir ]] then continue else cd $postdir fi newname=$(echo "$1" | cut -d"." -f 1) echo $newname if [[ ! -d "$newname.html" ]]; then touch "$newname.html" fi echo $header > "$postdir$newname.html" pandoc "$1" >> "$postdir$newname.html" echo $footer >> "$postdir$newname.html" echo "Stay in draft mode or publish to main file? [y = publish, n = draft]" read ans if [[ $ans == n ]]; then exit 0 fi echo "What would you like your post's ID to be?" read id echo "What would you like your post's title to be?" read title # This is BSD sed, so need to have the '' after the flag sed -i '' 's//'$id'/g' $postdir$newname.html || (echo "Can't find ID anchor" && exit 1) sed -i '' 's//'$title'/g' $postdir$newname.html || (echo "Can't find TITLE anchor" && exit 1) sed -i '' 's//'$currdate'/g' $postdir$newname.html || (echo "Can't find DATE anchor" && exit 1) (printf "%s\n" "//a" "$(cat $postdir$newname.html)" . w | ed -s $currblog) || (echo "Can't find POST anchor" && exit 1) # For RSS, feed.xml touch $tmp echo ' '$title' '$currdate' '$blogurl$id' ' > $tmp (printf "%s\n" "//a" "$(cat $tmp)" . w | ed -s $xmlfile) || (echo "Can't find ITEM anchor" && exit 1) rm -i $tmp # For sidebar touch $tmp # 5 tabs. lol echo '
  • '$title' '$currday'
  • ' > $tmp (printf "%s\n" "//a" "$(cat $tmp)" . w | ed -s $currblog) || (echo "Can't find SIDE anchor" && exit 1) rm -i $tmp echo "Do you wish to publish to Neocities? [y/n]" read pub if [[ $pub == "y" ]]; then neocities upload $currblog $xmlfile fi exit 0