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;
+}