Rewrite md2point in c and add minimal manpage - 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 --- DIR commit d8eed1a76732e11cf44c4724f71dfc0072d40adc DIR parent fd83f17fab6afefa04c18b6e8f2938b916b9d008 HTML Author: Anders Damsgaard <anders@adamsgaard.dk> Date: Wed, 29 Apr 2020 15:59:19 +0200 Rewrite md2point in c and add minimal manpage Signed-off-by: Christoph Lohmann <20h@r-36.net> Diffstat: M Makefile | 14 ++++++++++++++ R bin/md2point -> bin/md2point.sh | 0 A md2point.1 | 42 +++++++++++++++++++++++++++++++ A md2point.c | 164 +++++++++++++++++++++++++++++++ 4 files changed, 220 insertions(+), 0 deletions(-) --- DIR diff --git a/Makefile b/Makefile @@ -1,11 +1,25 @@ PREFIX= /usr/local +bin/md2point: md2point.o + ${CC} -o $@ md2point.o ${LDFLAGS} + +.c.o: + ${CC} -c ${CFLAGS} $< + install: install -m755 bin/dir2point $(PREFIX)/bin/dir2point install -m755 bin/md2point $(PREFIX)/bin/md2point install -m755 bin/point2pdf $(PREFIX)/bin/point2pdf + install -m644 md2point.1 $(PREFIX)/share/man/man1/md2point.1 uninstall: rm -f $(PREFIX)/bin/dir2point rm -f $(PREFIX)/bin/md2point rm -f $(PREFIX)/bin/point2pdf + rm -f $(PREFIX)/share/man/man1/md2point.1 + +clean: + rm -f bin/md2point + rm -f md2point.o + +.PHONY: install uninstall clean DIR diff --git a/bin/md2point b/bin/md2point.sh DIR diff --git a/md2point.1 b/md2point.1 @@ -0,0 +1,42 @@ +.Dd $Mdocdate$ +.Dt MD2POINT 1 +.Os +.Sh NAME +.Nm md2point +.Nd converts markdown into catpoint presentation files +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +The +.Nm +utility reads markdown from stdin and writes formatted text files +to the current directory. The output text files are intended for +use with catpoint. The output files are named in a consecutive +manner with the title in the file name. +.Sh MARKDOWN FORMAT +.Pp +Lines beginning with +.Em ## +are treated as slide titles, and serve as delimiters between output +slides. +.Pp +Lines beginning with +.Em % +are treated as comments, and are not reproduced in the output. +.Pp +Lines beginning with +.Em #pause +denote breaks within slides. +.Pp +Any other text and formatting is reproduced exactly in the output. +.Sh EXIT STATUS +.Nm +exits with 0 on success, and >0 if a a runtime error occurs. +.Sh SEE ALSO +.Xr catpoint +.Xr dir2point +.Sh AUTHORS +.An Anders Damsgaard Aq Mt anders@adamsgaard.dk , +and +.An Christoph Lohmann Aq Mt 20h@r-36.net +(original implementation). DIR diff --git a/md2point.c b/md2point.c @@ -0,0 +1,164 @@ +#include <stdio.h> +#include <stdlib.h> +#include <err.h> +#include <string.h> + +#define PATH_MAX 128 + +char buf[PATH_MAX]; + +/* from git://bitreich.org/utf8expr */ +size_t +utf8strlen(char *s) +{ + size_t i; + + i = 0; + for (; s[0]; s++) { + if ((s[0] & 0xc0) != 0x80) + i++; + } + + return i; +} + +void +fprintunderline(FILE *fp, char *str, size_t linelen) +{ + size_t i; + fprintf(fp, "\n %s\n ", str); + for (i=0; i<=utf8strlen(str); ++i) + fputs("=", fp); + fputs("\n\n", fp); +} + +void +escapechars(char *s, size_t linelen) +{ + size_t i; + for (i=0; i<linelen && *s != '\0'; (void)*s++, i++) + switch (*s) { + case '#': + case ' ': + case ' ': + case ':': + case '.': + case '(': + case ')': + case '/': + *s = '_'; + break; + case '\n': + *s = '\0'; + return; + default: + break; + } +} + +void +fprintesc(FILE *fp, char *s, ssize_t len) +{ + ssize_t i; + int intext; + + intext = 0; + fputs(" ", fp); + for (i=0; i<len && s[i] != '\0'; i++) + switch (s[i]) { + case ' ': + fputc(' ', fp); + break; + case '\t': + fprintf(fp, " "); + break; + case '*': + if (!intext) { + fputc('o', fp); + break; + } + default: + intext = 1; + fputc(s[i], fp); + break; + } + fputs("\n", fp); +} + +void +mkfilename(char *fname, char *str, size_t len, int i) +{ + strlcpy(buf, str, len); + escapechars(buf, len); + snprintf(fname, len, "%.4d-%s.txt", i, buf); +} + +void +copyfile(char *dst, char *src) +{ + char c; + FILE *fsrc, *fdst; + + if (strlen(src) < 1 || strlen(dst) < 1 || + !(fsrc = fopen(src, "r")) || !(fdst = fopen(dst, "w"))) + err(1, "copyfile: %s -> %s", src, dst); + + while ((c = fgetc(fsrc)) != EOF) + fputc(c, fdst); + + fclose(fsrc); + fclose(fdst); +} + +int +main(int argc, char* argv[]) +{ + int i; + static char *line; + static size_t linesize; + ssize_t linelen; + char title[PATH_MAX], fname[PATH_MAX], fname_old[PATH_MAX]; + FILE *fp; + + fp = NULL; + title[0] = fname[0] = fname_old[0] = '\0'; + i = 0; + while ((linelen = getline(&line, &linesize, stdin)) > 0) { + + if (line[linelen-1] == '\n') + line[--linelen] = '\0'; + + if (linelen > 1 && line[0] == '#' && line[1] == '#') { + if (fp) + fclose(fp); + strlcpy(title, line+2, PATH_MAX); + mkfilename(fname, title, PATH_MAX, i++); + if (!(fp = fopen(fname, "w"))) + err(1, "fopen: %s", fname); + if (linelen == 2) + fputs("\n", fp); + else + fprintunderline(fp, title, linelen); + + } else if (linelen > 0 && line[0] == '%') { + continue; + + } else if (linelen > 5 && !strncmp(line, "#pause", linelen)) { + if (fp) + fclose(fp); + strlcpy(fname_old, fname, PATH_MAX); + mkfilename(fname, title, PATH_MAX, i++); + copyfile(fname, fname_old); + if (strlen(fname) > 0 && !(fp = fopen(fname, "a"))) + err(1, "fopen: %s", fname); + + } else { + /* ignore text before first header */ + if (fp) + fprintesc(fp, line, linelen); + } + } + + free(line); + return 0; +}