nihdoc

WIP markup parser (txt -> html)
git clone git://git.alexkarle.com.com/blag
Log | Files | Refs | README | LICENSE

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:
Ablag.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(); +}