--- old/CMakeLists.txt	Mon Sep  7 15:51:38 2020
+++ new/CMakeLists.txt	Mon Sep  7 15:51:38 2020
@@ -81,6 +81,10 @@
 	listing.c
 	mangle.c
 
+	# post - format 4
+	# XXX KEBE ASKS -- any clever way to pin an external library?
+	post_fmt4.c
+
 	# templates
 	${FLEX_tmpl_OUTPUTS} ${BISON_tmpl_OUTPUTS}
 	render.c
--- old/docs/lisp-metadata.txt	Mon Sep  7 15:51:38 2020
+++ new/docs/lisp-metadata.txt	Mon Sep  7 15:51:38 2020
@@ -31,6 +31,7 @@
 
      2: raw HTML
      3: pseudo-LaTeX
+     4: Markdown (MD)
 
  tags: list of tags associated with this post
 
--- old/parse.h	Mon Sep  7 15:51:38 2020
+++ new/parse.h	Mon Sep  7 15:51:38 2020
@@ -100,4 +100,8 @@
 	data->cond_stack_use--;
 }
 
+/*
+ * Format "4" (markdown) entry point:
+ */
+extern struct str *fmt4_md_to_html(struct str *);
 #endif
--- old/post.c	Mon Sep  7 15:51:38 2020
+++ new/post.c	Mon Sep  7 15:51:38 2020
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009-2020 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright 2020, Kebe Software & Services
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -242,6 +243,29 @@
 	return 0;
 }
 
+static int
+__do_load_post_body_fmt4(struct post *post, const struct str *md)
+{
+	/*
+	 * Like HTML, assume the .lisp file contains all of the other post
+	 * metadata.  If that assumption changes, update here.
+	 *
+	 * Unlike HTML, we plan to provide a clean error string if MD
+	 * parsing fails.
+	 */
+	str_putref(post->body);	/* Free the previous text. */
+	post->body = fmt4_md_to_html(md);
+	if (post->body == NULL) {
+		/*
+		 * XXX KEBE SAYS do something clever here with a small HTML
+		 * string.  For now, panic.
+		 */
+		ASSERT(post->body != NULL);
+	}
+
+	return (0);
+}
+
 static int __do_load_post_body_fmt3(struct post *post, const struct str *input)
 {
 	struct parser_output x;
@@ -304,9 +328,10 @@
 
 static int __load_post_body(struct post *post)
 {
-	static const char *exts[4] = {
+	static const char *exts[5] = {
 		[2] = "html",
 		[3] = "tex",
+		[4] = "md",
 	};
 
 	char path[FILENAME_MAX];
@@ -314,7 +339,7 @@
 	int ret;
 
 	ASSERT3U(post->fmt, >=, 2);
-	ASSERT3U(post->fmt, <=, 3);
+	ASSERT3U(post->fmt, <=, 4);
 
 	snprintf(path, FILENAME_MAX, "%s/posts/%d/post.%s",
 		 str_cstr(config.data_dir), post->id, exts[post->fmt]);
@@ -330,6 +355,9 @@
 		case 3:
 			ret = __do_load_post_body_fmt3(post, raw);
 			break;
+		case 4:
+			ret = __do_load_post_body_fmt4(post, raw);
+			break;
 	}
 
 	str_putref(raw);
--- /dev/null	Fri Sep  4 03:10:00 2020
+++ new/post_fmt4.c	Mon Sep  7 15:51:38 2020
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020, Kebe Software & Services
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * "When in doubt, add another level of indirection." - L. Peterson
+ *
+ * This file implements one function:
+ *
+ *	struct str *
+ *	fmt4_md_to_html(struct str *);
+ *
+ * The return value is reference-counted to 1, the reference count of what is
+ * passed-in remains untouched.
+ *
+ * It's a wrapper between blahg, and whatever MD to HTML renderer we pick.
+ * As of this version of the file, it's going to be MD4C.  We can change
+ * that later if need be, but for now, this file depends on MD4C.
+ */
+
+struct str *
+fmt4_md_to_html(struct str *md)
+{
+	int notyet = 0;
+
+	ASSERT(notyet);
+}
