pointtools

Simple point utilities to hold text presentations.
git clone git://r-36.net/pointtools
Log | Files | Refs | LICENSE

commit d8eed1a76732e11cf44c4724f71dfc0072d40adc
parent fd83f17fab6afefa04c18b6e8f2938b916b9d008
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:
Makefile | 14++++++++++++++
bin/md2point | 45---------------------------------------------
bin/md2point.sh | 45+++++++++++++++++++++++++++++++++++++++++++++
md2point.1 | 42++++++++++++++++++++++++++++++++++++++++++
md2point.c | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 265 insertions(+), 45 deletions(-)

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 diff --git a/bin/md2point b/bin/md2point @@ -1,45 +0,0 @@ -#!/bin/sh - -mkfilename() { - printf "%.4d-%s" "$1" "$2" | tr '# :.()/' '_' - printf ".txt" -} - -mkunderline() { - i=$1 - while [ $i -gt 1 ]; - do - printf "%s" "$2" - i=$(($i - 1)) - done -} - -fname="" -snum=0 - -while IFS=' -' read -r line; -do - case $line in - \#\#*) - titlelen="$(utf8expr length "$line")" - title="$(utf8expr substr "$line" 3 $titlelen)" - fname="$(mkfilename "$snum" "$title")" - snum=$((snum + 1)) - printf "\n %s\n %s\n\n" \ - "$title" "$(mkunderline $titlelen "=")" > $fname - ;; - \#pause) - fname="$(mkfilename "$snum" "$title")" - cat "$(mkfilename "$((snum - 1))" "$title")" >> $fname - snum=$((snum + 1)) - ;; - *) - [ -n "$fname" ] && \ - printf " %s\n" "$line" \ - | sed 's, , ,' \ - | sed 's,^\([[:blank:]]*\)\*,\1o,' >> $fname - ;; - esac -done - diff --git a/bin/md2point.sh b/bin/md2point.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +mkfilename() { + printf "%.4d-%s" "$1" "$2" | tr '# :.()/' '_' + printf ".txt" +} + +mkunderline() { + i=$1 + while [ $i -gt 1 ]; + do + printf "%s" "$2" + i=$(($i - 1)) + done +} + +fname="" +snum=0 + +while IFS=' +' read -r line; +do + case $line in + \#\#*) + titlelen="$(utf8expr length "$line")" + title="$(utf8expr substr "$line" 3 $titlelen)" + fname="$(mkfilename "$snum" "$title")" + snum=$((snum + 1)) + printf "\n %s\n %s\n\n" \ + "$title" "$(mkunderline $titlelen "=")" > $fname + ;; + \#pause) + fname="$(mkfilename "$snum" "$title")" + cat "$(mkfilename "$((snum - 1))" "$title")" >> $fname + snum=$((snum + 1)) + ;; + *) + [ -n "$fname" ] && \ + printf " %s\n" "$line" \ + | sed 's, , ,' \ + | sed 's,^\([[:blank:]]*\)\*,\1o,' >> $fname + ;; + esac +done + 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). 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; +}