URI: 
       md2point.c - pointtools - Simple point utilities to hold text presentations.
  HTML git clone git://bitreich.org/pointtools/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/pointtools/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       md2point.c (3365B)
       ---
            1 /*
            2  * See LICENSE for license details.
            3  */
            4 #include <err.h>
            5 #include <limits.h>
            6 #include <stdio.h>
            7 #include <stdlib.h>
            8 #include <string.h>
            9 #include <unistd.h>
           10 
           11 #ifdef NEED_STRLCPY /* OpenBSD implementation */
           12 size_t
           13 strlcpy(char *dst, const char *src, size_t dsize) {
           14         const char *osrc = src;
           15         size_t nleft = dsize;
           16 
           17         if (nleft != 0) {
           18                 while (--nleft != 0) {
           19                         if ((*dst++= *src++) == '\0')
           20                                 break;
           21                 }
           22         }
           23 
           24         if (nleft == 0) {
           25                 if (dsize != 0)
           26                         *dst = '\0';
           27                 while (*src++)
           28                         ;
           29         }
           30 
           31         return(src - osrc - 1);
           32 }
           33 #endif /* NEED_STRLCPY */
           34 
           35 /* from git://bitreich.org/utf8expr */
           36 size_t
           37 utf8strlen(const char *s)
           38 {
           39         size_t i;
           40 
           41         for (i = 0; *s; s++) {
           42                 if ((*s & 0xc0) != 0x80)
           43                         i++;
           44         }
           45 
           46         return i;
           47 }
           48 
           49 void
           50 fprintunderline(FILE *fp, const char *str)
           51 {
           52         size_t i, len;
           53 
           54         fprintf(fp, "\n  %s\n  ", str);
           55         len = utf8strlen(str);
           56         for (i = 0; i <= len; ++i)
           57                 fputs("=", fp);
           58         fputs("\n\n", fp);
           59 }
           60 
           61 void
           62 escapechars(char *s)
           63 {
           64         for (; *s; s++) {
           65                 if (*s == '\n') {
           66                         *s = '\0';
           67                         return;
           68                 }
           69 
           70                 /*
           71                  * Only allow ASCII printable a-zA-Z0-9 for simplicity.
           72                  */
           73                 if ((*s >= 'a' && *s <= 'z')
           74                                 || (*s >= 'A' && *s <= 'Z')
           75                                 || (*s >= '0' && *s <= '9')) {
           76                         continue;
           77                 }
           78                 *s = '_';
           79         }
           80 }
           81 
           82 void
           83 fprintesc(FILE *fp, const char *s)
           84 {
           85         int intext = 0;
           86 
           87         fputs("  ", fp);
           88         for (; *s; s++) {
           89                 switch (*s) {
           90                 case ' ':
           91                         fputc(' ', fp);
           92                         break;
           93                 case '\t':
           94                         fprintf(fp, "        ");
           95                         break;
           96                 case '*':
           97                         if (intext) {
           98                                 fputc(*s, fp);
           99                         } else {
          100                                 fputc('o', fp);
          101                                 intext = 1;
          102                         }
          103                         break;
          104                 default:
          105                         intext = 1;
          106                         fputc(*s, fp);
          107                         break;
          108                 }
          109         }
          110         fputs("\n", fp);
          111 }
          112 
          113 void
          114 mkfilename(char *fname, char *str, size_t bufsiz, int i)
          115 {
          116         char buf[PATH_MAX];
          117 
          118         strlcpy(buf, str, sizeof(buf));
          119         escapechars(buf);
          120         snprintf(fname, bufsiz, "%.4d-%s.txt", i, buf);
          121 }
          122 
          123 void
          124 copyfile(char *dst, char *src)
          125 {
          126         int c;
          127         FILE *fsrc, *fdst;
          128 
          129         if (src[0] == '\0' || dst[0] == '\0' ||
          130                 !(fsrc = fopen(src, "r")) || !(fdst = fopen(dst, "w")))
          131                 err(1, "copyfile: %s -> %s", src, dst);
          132 
          133         while ((c = fgetc(fsrc)) != EOF)
          134                 fputc(c, fdst);
          135 
          136         fclose(fsrc);
          137         fclose(fdst);
          138 }
          139 
          140 int
          141 main(void)
          142 {
          143         size_t i = 0;
          144         char *line = NULL;
          145         size_t linesize = 0;
          146         ssize_t linelen;
          147         char title[PATH_MAX] = "", fname[PATH_MAX] = "", fname_old[PATH_MAX] = "";
          148         FILE *fp = NULL;
          149 
          150         while ((linelen = getline(&line, &linesize, stdin)) > 0) {
          151                 if (line[linelen - 1] == '\n')
          152                         line[--linelen] = '\0';
          153 
          154                 if (line[0] == '%')
          155                         continue;
          156 
          157                 if (line[0] == '\\') {
          158                         if (line[1] == '\0')
          159                                 continue;
          160 
          161                         /* ignore text before first header */
          162                         if (fp)
          163                                 fprintesc(fp, line+1);
          164                 } else if (line[0] == '#' && line[1] == '#') {
          165                         if (fp) {
          166                                 fclose(fp);
          167                                 fp = NULL;
          168                         }
          169                         strlcpy(title, line + 2, sizeof(title));
          170                         mkfilename(fname, title, sizeof(fname), i++);
          171                         if (!(fp = fopen(fname, "w")))
          172                                 err(1, "fopen: %s", fname);
          173                         if (line[2] == '\0')
          174                                 fputs("\n", fp);
          175                         else
          176                                 fprintunderline(fp, title);
          177                 } else if (linelen > 5 && !strncmp(line, "#pause", linelen)) {
          178                         if (fp) {
          179                                 fclose(fp);
          180                                 fp = NULL;
          181                         }
          182                         strlcpy(fname_old, fname, sizeof(fname_old));
          183                         mkfilename(fname, title, sizeof(fname), i++);
          184                         copyfile(fname, fname_old);
          185                         if (fname[0] != '\0' && !(fp = fopen(fname, "a")))
          186                                 err(1, "fopen: %s", fname);
          187                 } else {
          188                         /* ignore text before first header */
          189                         if (fp)
          190                                 fprintesc(fp, line);
          191                 }
          192         }
          193 
          194         free(line);
          195 
          196         return 0;
          197 }