commit eb4048f4d179f2329d77827831af06da52947de9 (patch)
Author: Alex Karle <alex@alexkarle.com>
Date: Tue, 14 Dec 2021 00:35:12 -0500
Add initial version of blag, a simpler markup
This is most definitely buggy, but a repo's gotta start somewhere!
Diffstat:
A | blag.c | | | 227 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 227 insertions(+), 0 deletions(-)
diff --git a/blag.c b/blag.c
@@ -0,0 +1,227 @@
+/*
+ * blag.c -- generate the blog!
+ * ~akarle, MIT License
+ *
+ * "because markdown isn't in base!"
+ *
+ * Support:
+ * --------
+ * #|##|### headers
+ *
+ * <p> tags around paragraphs
+ *
+ * * bullets (non-nested)
+ *
+ * 1. numerical lists (non-nested)
+ *
+ * > quotes
+ *
+ * TAB code blocks
+ *
+ * Inline `code`
+ *
+ * TODO:
+ * [[url|Links]]
+ * -> if we see [[
+ * -> print out <a href="
+ * -> while in link
+ * -> push into buf
+ * -> putchar
+ * -> if we see |
+ * -> printf ">
+ * -> just putchar
+ * -> else
+ * -> printf ">url
+ * -> once we hit ]]
+ * -> </a>
+ *
+ * --> error reporting for unclosed links??
+ * -> errx in closeblock() if in link parser
+ */
+#include <stdio.h>
+#include <err.h>
+#include <unistd.h>
+
+enum Block {
+ NONE,
+ HEADER_PARSE,
+ HEADER,
+ PARAGRAPH,
+ PARAGRAPH_BREAK,
+ CODE,
+ CODE_BREAK,
+ QUOTE,
+ QUOTE_BREAK,
+ ULIST,
+ ULIST_START,
+ ULIST_PARSE,
+ ULIST_BREAK,
+ OLIST,
+ OLIST_START,
+ OLIST_PARSE,
+ OLIST_BREAK,
+};
+
+int closeblock(int in, int hlvl) {
+ if (in == HEADER) {
+ in = NONE;
+ printf("</h%d>", hlvl);
+ } else if (in == PARAGRAPH) {
+ in = PARAGRAPH_BREAK;
+ } else if (in == PARAGRAPH_BREAK) {
+ in = NONE;
+ printf("</p>\n");
+ } else if (in == CODE) {
+ in = CODE_BREAK;
+ } else if (in == CODE_BREAK) {
+ in = NONE;
+ printf("</pre></code>\n");
+ } else if (in == QUOTE) {
+ in = QUOTE_BREAK;
+ } else if (in == QUOTE_BREAK) {
+ in = NONE;
+ printf("</blockquote>\n");
+ } else if (in == ULIST) {
+ in = ULIST_BREAK;
+ printf("</li>");
+ } else if (in == ULIST_BREAK) {
+ in = NONE;
+ printf("</ul>\n");
+ } else if (in == OLIST) {
+ in = OLIST_BREAK;
+ printf("</li>");
+ } else if (in == OLIST_BREAK) {
+ in = NONE;
+ printf("</ol>\n");
+ } else {
+ /* keep in as is */
+ }
+ return in;
+}
+
+int parse() {
+ /* Mini state machine */
+ int c;
+ enum Block in = NONE;
+ int hlvl = 0;
+ int in_code;
+ while ((c = getchar()) != EOF) {
+ switch (c) {
+ case '#':
+ if (in == NONE) {
+ in = HEADER_PARSE;
+ hlvl = 1;
+ } else if (in == HEADER_PARSE) {
+ hlvl++;
+ } else {
+ /* not a special # */
+ putchar(c);
+ }
+ break;
+ case ' ':
+ if (in == HEADER_PARSE) {
+ printf("</h%d>", hlvl);
+ in = HEADER;
+ } else if (in == ULIST_START) {
+ printf("<ul>\n <li>");
+ in = ULIST;
+ } else if (in == ULIST_PARSE) {
+ printf(" <li>");
+ in = ULIST;
+ } else if (in == OLIST_START) {
+ printf("<ol>\n <li>");
+ in = OLIST;
+ } else if (in == OLIST_PARSE) {
+ printf(" <li>");
+ in = OLIST;
+ } else if (in == NONE || in == OLIST_BREAK || in == ULIST_BREAK) {
+ /* no op */
+ } else {
+ putchar(c);
+ }
+ break;
+ case '`':
+ if (in_code) {
+ printf("</code>");
+ in_code = 0;
+ } else {
+ printf("<code>");
+ in_code = 1;
+ }
+ break;
+ case '\t':
+ if (in == NONE) {
+ in = CODE;
+ printf("<code><pre>\n");
+ } else if (in == CODE_BREAK) {
+ in = CODE;
+ }
+ break;
+ case '>':
+ if (in == NONE) {
+ in = QUOTE;
+ printf("<blockquote>\n");
+ } else if (in == QUOTE_BREAK) {
+ in = QUOTE;
+ }
+ break;
+ case '*':
+ if (in == NONE) {
+ in = ULIST_START;
+ } else if (in == ULIST_START || in == ULIST_PARSE) {
+ /* no op */
+ } else if (in == ULIST_BREAK) {
+ /* next list item */
+ in = ULIST_PARSE;
+ } else {
+ putchar(c);
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ if (in == NONE) {
+ in = OLIST_START;
+ } else if (in == OLIST_START || in == OLIST_PARSE) {
+ /* no op */
+ } else if (in == OLIST_BREAK) {
+ /* next list item */
+ in = OLIST_PARSE;
+ } else {
+ putchar(c);
+ }
+ break;
+ case '\n':
+ in = closeblock(in, hlvl);
+ putchar(c);
+ break;
+ default:
+ if (in == NONE) {
+ /* nothing else was matched -> assume new <p> */
+ in = PARAGRAPH;
+ printf("<p>\n");
+ } else if (in == PARAGRAPH_BREAK) {
+ /* We thought it might be the end, but it aint! */
+ in = PARAGRAPH;
+ }
+ putchar(c);
+ break;
+ }
+ }
+ closeblock(in, hlvl);
+ return 0;
+}
+
+int main(void) {
+#ifdef __OpenBSD__
+ pledge("stdio", "stdio");
+#endif
+ return parse();
+}