Permalink
Browse files

kilt: new example of library usage, compiling markdown into man

Big thanks to bapt for this renderer.
  • Loading branch information...
1 parent 92aac3a commit 965b25b0261f1abae1e36382ea48c418ab218dc3 Natacha Porté committed Oct 28, 2009
Showing with 217 additions and 2 deletions.
  1. +4 −1 BSDmakefile
  2. +4 −1 GNUmakefile
  3. +209 −0 kilt.c
View
@@ -20,7 +20,7 @@ CFLAGS=-c -g -O3 -Wall -Werror
LDFLAGS=-g -O3 -Wall -Werror
CC=gcc
-all: markdown
+all: markdown kilt
.PHONY: all clean
@@ -33,6 +33,9 @@ markdown: main.o markdown.o array.o buffer.o renderers.o
benchmark: benchmark.o markdown.o array.o buffer.o renderers.o
$(CC) $(LDFLAGS) $(.ALLSRC) -o $(.TARGET)
+kilt: kilt.o markdown.o array.o buffer.o
+ $(CC) $(LDFLAGS) $(.ALLSRC) -o $(.TARGET)
+
clean:
rm -f *.o
rm -f markdown
View
@@ -19,7 +19,7 @@ CFLAGS=-c -g -O3 -Wall -Werror
LDFLAGS=-g -O3 -Wall -Werror
CC=gcc
-all: markdown
+all: markdown kilt
.PHONY: all clean
@@ -32,6 +32,9 @@ markdown: main.o markdown.o array.o buffer.o renderers.o
benchmark: benchmark.o markdown.o array.o buffer.o renderers.o
$(CC) $(LDFLAGS) $^ -o $@
+kilt: kilt.o markdown.o array.o buffer.o
+ $(CC) $(LDFLAGS) $^ -o $@
+
clean:
rm -f *.o
rm -f markdown
View
209 kilt.c
@@ -0,0 +1,209 @@
+/* kilt.c - upskirt for man */
+
+/*
+ * Copyright (c) 2009, Baptiste Daroussin and Natacha Porté
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "markdown.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#define READ_UNIT 1024
+#define OUTPUT_UNIT 64
+
+
+/****************************
+ * MARKDOWN TO MAN RENDERER *
+ ****************************/
+
+void
+man_text_escape(struct buf *ob, char *src, size_t size) {
+ size_t i = 0, org;
+ while (i < size) {
+ /* copying directly unescaped characters */
+ org = i;
+ while (i < size && src[i] != '-')
+ i += 1;
+ if (i > org) bufput(ob, src + org, i - org);
+
+ /* escaping */
+ if (i >= size) break;
+ else if (src[i] == '-') BUFPUTSL(ob, "\\-");
+ i += 1; } }
+
+static void
+man_blockcode(struct buf *ob, struct buf *text, void *opaque) {
+ if (ob->size) bufputc(ob, '\n');
+ BUFPUTSL(ob, ".nf\n");
+ if (text) man_text_escape(ob, text->data, text->size);
+ BUFPUTSL(ob, ".fi\n"); }
+
+static int
+man_codespan(struct buf *ob, struct buf *text, void *opaque) {
+ if (ob->size) bufputc(ob, '\n');
+ BUFPUTSL(ob, ".nf\n");
+ if (text) man_text_escape(ob, text->data, text->size);
+ BUFPUTSL(ob, ".fi\n");
+ return 1; }
+
+static void
+man_header(struct buf *ob, struct buf *text, int level, void *opaque) {
+ if (ob->size) bufputc(ob, '\n');
+ switch(level) {
+ case 1:
+ bufprintf(ob,".TH ");
+ break;
+ case 2:
+ bufprintf(ob, ".SH ");
+ break;
+ case 3:
+ bufprintf(ob, ".SS ");
+ break;
+ }
+ if (text) bufput(ob, text->data, text->size);
+}
+
+static int
+man_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
+ if (!text || !text->size) return 0;
+ BUFPUTSL(ob, "\\fB");
+ bufput(ob, text->data, text->size);
+ BUFPUTSL(ob, "\\fP");
+ return 1; }
+
+static int
+man_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
+ if (!text || !text->size) return 0;
+ BUFPUTSL(ob, "\\fI");
+ if (text) bufput(ob, text->data, text->size);
+ BUFPUTSL(ob, "\\fP");
+ return 1; }
+
+static int
+man_linebreak(struct buf *ob, void *opaque) {
+ BUFPUTSL(ob, "\n.LP\n");
+ return 1; }
+
+static void
+man_paragraph(struct buf *ob, struct buf *text, void *opaque) {
+ if (ob->size) bufputc(ob, '\n');
+ BUFPUTSL(ob, ".TP\n");
+ if (text) bufput(ob, text->data, text->size);
+ BUFPUTSL(ob, "\n"); }
+
+static void
+man_list(struct buf *ob, struct buf *text, int flags, void *opaque) {
+ if (ob->size) bufputc(ob, '\n');
+ if (flags & MKD_LIST_ORDERED)
+ BUFPUTSL(ob,"\n.nr step 0 1\n");
+ else
+ BUFPUTSL(ob,".\n");
+ if (text) bufput(ob, text->data, text->size);
+ BUFPUTSL(ob, "\n"); }
+
+static void
+man_listitem(struct buf *ob, struct buf *text, int flags, void *opaque) {
+ if (flags & MKD_LIST_ORDERED)
+ BUFPUTSL(ob, ".IP \\n+[step]\n");
+ else
+ BUFPUTSL(ob, ".IP \\[bu] 2 \n");
+
+ if (text) {
+ while (text->size && text->data[text->size - 1] == '\n')
+ text->size -= 1;
+ bufput(ob, text->data, text->size); }
+ BUFPUTSL(ob, "\n"); }
+
+static void
+man_normal_text(struct buf *ob, struct buf *text, void *opaque) {
+ if (text) man_text_escape(ob, text->data, text->size); }
+
+
+/* renderer structure */
+struct mkd_renderer to_man = {
+ /* block-level callbacks */
+ man_blockcode,
+ NULL,
+ NULL,
+ man_header,
+ NULL,
+ man_list,
+ man_listitem,
+ man_paragraph,
+
+ /* span-level callbacks */
+ NULL,
+ man_codespan,
+ man_double_emphasis,
+ man_emphasis,
+ NULL,
+ man_linebreak,
+ NULL,
+ NULL,
+ NULL,
+
+ /* low-level callbacks */
+ NULL,
+ man_normal_text,
+
+ /* renderer data */
+ "*_",
+ NULL };
+
+
+
+/*****************
+ * MAIN FUNCTION *
+ *****************/
+
+/* main • main function, interfacing STDIO with the parser */
+int
+main(int argc, char **argv) {
+ struct buf *ib, *ob;
+ size_t ret;
+ FILE *in = stdin;
+
+ /* opening the file if given from the command line */
+ if (argc > 1) {
+ in = fopen(argv[1], "r");
+ if (!in) {
+ fprintf(stderr,"Unable to open input file \"%s\": %s\n",
+ argv[1], strerror(errno));
+ return 1; } }
+
+ /* reading everything */
+ ib = bufnew(READ_UNIT);
+ bufgrow(ib, READ_UNIT);
+ while ((ret = fread(ib->data + ib->size, 1,
+ ib->asize - ib->size, in)) > 0) {
+ ib->size += ret;
+ bufgrow(ib, ib->size + READ_UNIT); }
+ if (in != stdin) fclose(in);
+
+ /* performing markdown to man */
+ ob = bufnew(OUTPUT_UNIT);
+ markdown(ob, ib, &to_man);
+
+ /* writing the result to stdout */
+ fwrite(ob->data, 1, ob->size, stdout);
+
+ /* cleanup */
+ bufrelease(ib);
+ bufrelease(ob);
+ return 0; }
+
+/* vim: set filetype=c: */

0 comments on commit 965b25b

Please sign in to comment.