From 94c419801a05f1442182b0752fef0d89489b75b7 Mon Sep 17 00:00:00 2001
From: Alex Karle
Date: Mon, 27 Dec 2021 12:09:25 -0500
Subject: [PATCH] Rebrand blag -> nihdoc
The new name is a play on mdoc(7), jokingly pointing fun at the decision
to "invent here" instead of use markdown.
---
.gitignore | 2 +-
Makefile | 20 ++++++++++----------
README | 20 +++++++++++---------
blag.1 | 44 --------------------------------------------
blag.c | 287 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
nihdoc.1 | 44 ++++++++++++++++++++++++++++++++++++++++++++
nihdoc.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test/big.html | 2 +-
test/big.txt | 2 +-
9 files changed, 355 insertions(+), 353 deletions(-)
delete mode 100644 blag.1
delete mode 100644 blag.c
create mode 100644 nihdoc.1
create mode 100644 nihdoc.c
diff --git a/.gitignore b/.gitignore
index 01ecc2c..e4d67b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-blag
+nihdoc
# test file
input
diff --git a/Makefile b/Makefile
index 5966e2d..cf08a4a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,30 +1,30 @@
-# blag makefile
+# nihdoc makefile
CFLAGS = -g -O2 -Wall -Wpedantic -Wextra
-blag: blag.c
- $(CC) $(CFLAGS) -o $@ blag.c
+nihdoc: nihdoc.c
+ $(CC) $(CFLAGS) -o $@ nihdoc.c
.PHONY: check
-check: blag
+check: nihdoc
@for f in test/*.txt; do \
printf "$$f ... "; \
base=$$(basename $$f txt)html; \
if [ -z $(GENBASE) ]; then \
- ./blag < $$f > /tmp/$$base; \
+ ./nihdoc < $$f > /tmp/$$base; \
diff -u test/$$base /tmp/$$base; \
echo "success!"; \
else \
- ./blag < $$f > test/$$base; \
+ ./nihdoc < $$f > test/$$base; \
echo "generated!"; \
fi; \
done
.PHONY: clean
clean:
- rm -f blag
+ rm -f nihdoc
.PHONY: install
-install: blag
+install: nihdoc
mkdir -p $(HOME)/bin $(HOME)/share/man/man1
- install -m 555 blag $(HOME)/bin
- install -m 444 blag.1 $(HOME)/share/man/man1
+ install -m 555 nihdoc $(HOME)/bin
+ install -m 444 nihdoc.1 $(HOME)/share/man/man1
diff --git a/README b/README
index b10ac0e..26086b0 100644
--- a/README
+++ b/README
@@ -1,11 +1,16 @@
-# blag
+# nihdoc
+
+ Not Invented Here Doc
+ - - - ---
> "because markdown isn't in base!"
-> ~akarle
+>
+> ~akarle
+
## Description
-blag is my take at a light markup language to improve my
+nihdoc is my take at a light markup language to improve my
time-to-publish on blog posts. I concede up front that others
should likely use markdown, which is both prettier and more
well-known, but as a personal challenge I try to keep my blog
@@ -14,11 +19,11 @@ no markdown parser in base, I had to write my own!
## Usage
-`blag` reads from stdin and prints HTML snippets to stdout. No
+`nihdoc` reads from stdin and prints HTML snippets to stdout. No
arguments are read and no files are accessible (on OpenBSD this
is enforced via pledge(2)). Common usage is:
- $ (cat header.html; blag < file.txt; cat footer.html) > file.html
+ $ (cat header.html; nihdoc < file.txt; cat footer.html) > file.html
## Support
@@ -29,12 +34,9 @@ is enforced via pledge(2)). Common usage is:
- > quotes
- TAB code blocks
- Inline `code`, _italics_, and *bold*
-- Escaping via \
+- Escaping via \\
- Links: [https://alexkarle.com my site] or [https://alexkarle.com]
## TODO
- Mixed lists
-- Lots of code cleanup
-- Error reporting on malformed blocks
-- Tests
diff --git a/blag.1 b/blag.1
deleted file mode 100644
index df57406..0000000
--- a/blag.1
+++ /dev/null
@@ -1,44 +0,0 @@
-.Dd December 18, 2021
-.Dt BLAG 1
-.Os
-.Sh NAME
-.Nm blag
-.Nd convert plaintext to HTML
-.Sh SYNOPSIS
-.Nm blag
-<
-.Ar in.txt
->
-.Ar out.html
-.Sh DESCRIPTION
-.Nm
-is a very basic plaintext-to-HTML converter.
-It reads from stdin and writes to stdout so that it can
-.Xr pledge 2
-to only stdio.
-Any arguments given will produce an error.
-.Pp
-Like markdown, wrapped lines are supported,
-and a blank line is needed to start a new paragraph.
-.Pp
-The following markup is supported:
-.Pp
-.Bl -bullet -indent
-.It
-Inline *bold*, _italics_, `code` (bold/italics disabled in code)
-.It
-backslash to escape
-.It
-[alexkarle.com] bare links and [alexkarle.com description]
-.It
-# headers (each # adds a level)
-.It
-Ordered and unordered lists via 1-9. and - respectively.
-Nesting supported only within the same type (no mixing, yet).
-.It
-Code blocks (start line with TAB)
-.It
-Block quotes (start line with >)
-.El
-.Sh SEE ALSO
-.Xr Markdown.pl 1
diff --git a/blag.c b/blag.c
deleted file mode 100644
index c1ace00..0000000
--- a/blag.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * blag.c -- generate the blog!
- * ~akarle, MIT License
- *
- * "because markdown isn't in base!"
- */
-#include
-#include
-#include
-
-
-/* Global Constants and Enums */
-char *FMT_STRS[] = {
- ['_'] = "em",
- ['*'] = "strong",
- ['`'] = "code",
-};
-
-enum Block {
- NONE,
- HEADER,
- HEADER_PARSE,
- PARAGRAPH,
- CODE,
- QUOTE,
- LIST,
- LIST_PARSE,
-};
-
-enum Link {
- NOL,
- URL_PARSE,
- DESC_PARSE,
-};
-
-
-/* Start Global State */
-int c = '0';
-enum Block in = NONE;
-enum Link in_link = NOL;
-int hlvl = 0;
-bool fmts[256] = {false}; /* indexed by _ * ` */
-bool escape = false;
-char lnkbuf[2048] = {0};
-int lnkidx = 0;
-int indent = 0;
-int previndent = 0;
-int listdepth = 0;
-int lastc = '0';
-bool ol = false;
-bool linestarted = false;
-
-
-/* Helper functions */
-void putesc(int c) {
- switch (c) {
- case '<': printf("<"); break;
- case '>': printf(">"); break;
- case '&': printf("&"); break;
- default: putchar(c);
- }
-}
-
-void newlist() {
- in = LIST;
- previndent = indent;
- printf("<%s>\n\n", ol ? "ol" : "ul");
- listdepth++;
-}
-
-int endlist() {
- in = LIST;
- previndent = indent;
- printf("\n%s>\n", ol ? "ol" : "ul");
- return --listdepth;
-}
-
-void maybe_startp() {
- /* All inline types should start the paragraph if no other major type present*/
- if (in == NONE) {
- in = PARAGRAPH;
- printf("\n");
- }
-}
-
-void handle_lf() {
- indent = 0;
- linestarted = false;
-
- /* single line types (one lf to close) */
- if (in == HEADER) {
- in = NONE;
- printf("\n", hlvl);
- }
-
- /* terminate url parsing in links */
- if (in_link == URL_PARSE) {
- in_link = DESC_PARSE;
- printf("\">");
- }
-
- /* multi-line types (two lf to close) */
- if (lastc == '\n') {
- switch (in) {
- case PARAGRAPH: printf("
\n"); break;
- case CODE: printf("\n"); break;
- case QUOTE: printf("\n"); break;
- case LIST:
- previndent = 0;
- while (endlist())
- ;
- break;
- default:
- break; /* no op */
- }
- in = NONE;
- }
-}
-
-bool fmt_disabled() {
- /* `` blocks disable all but the next `, likewise CODE makes all disabled */
- if (in == CODE || in_link == URL_PARSE) {
- return true;
- } else {
- return fmts['`'] && c != '`';
- }
-}
-
-void toggle_format() {
- if (!fmt_disabled()) {
- maybe_startp();
- printf("<%s%s>", fmts[c] ? "/" : "", FMT_STRS[c]);
- fmts[c] ^= true;
- } else {
- putesc(c);
- }
-}
-
-int parse() {
- /* Mini state machine (home grown spaghetti code) */
- while ((c = getchar()) != EOF) {
- /* Handle Escapes before all else */
- if (escape) {
- maybe_startp();
- putesc(c);
- escape = false;
- continue;
- }
-
- /* Store links as we go */
- if (in_link == URL_PARSE && c != ']') {
- lnkbuf[lnkidx++] = c;
- }
-
- /* Store the indentation */
- if (!linestarted && c == ' ') {
- indent++;
- continue; /* don't print leading indents */
- }
-
- /* Handle unique state changes by char */
- switch (c) {
- case '\\':
- escape = true;
- break;
- case '#':
- if (in == NONE) {
- in = HEADER_PARSE;
- hlvl = 1;
- } else if (in == HEADER_PARSE) {
- hlvl++;
- } else {
- /* not a special # */
- putesc(c);
- }
- break;
- case ' ':
- if (in == HEADER_PARSE) {
- printf("", hlvl);
- in = HEADER;
- } else if (in_link == URL_PARSE) {
- in_link = DESC_PARSE;
- printf("\">");
- } else if (in == LIST_PARSE) {
- if (!listdepth) {
- newlist();
- } else {
- if (previndent < indent) {
- newlist();
- } else if (previndent > indent) {
- endlist();
- printf("\n\n");
- } else {
- in = LIST;
- printf("\n\n");
- }
- }
- } else {
- putesc(c);
- }
- break;
- case '*':
- case '`':
- case '_':
- toggle_format();
- break;
- case '\t':
- case '>':
- if (in == NONE) {
- in = c == '>' ? QUOTE : CODE;
- printf("%s", c == '>' ? "" : "");
- } else if (lastc == '\n' && c == (in == CODE ? '\t' : '>')) {
- /* no op */
- } else {
- putesc(c);
- }
- break;
- case '[':
- if (in_link == NOL && !fmt_disabled()) {
- maybe_startp();
- in_link = URL_PARSE;
- lnkidx = 0;
- printf("%s", lnkbuf);
- } else if (in_link == DESC_PARSE) {
- in_link = NOL;
- printf("");
- } else {
- putesc(c);
- }
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '.':
- case '-':
- if (in == NONE || !linestarted) {
- ol = c != '-';
- in = LIST_PARSE;
- } else if (in != LIST_PARSE) {
- putesc(c);
- }
- break;
- case '\n':
- handle_lf();
- if (in != NONE) {
- putesc(c);
- }
- break;
- default:
- maybe_startp();
- putesc(c);
- break;
- }
- lastc = c;
- linestarted = c != '\n';
- }
- /* pretend there's a final LF to close any blocks */
- handle_lf();
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- if (argc > 1) {
- fprintf(stderr, "error: %s takes no arguments\n", argv[0]);
- return 1;
- }
-#ifdef __OpenBSD__
- pledge("stdio", "stdio");
-#endif
- return parse();
-}
diff --git a/nihdoc.1 b/nihdoc.1
new file mode 100644
index 0000000..df57406
--- /dev/null
+++ b/nihdoc.1
@@ -0,0 +1,44 @@
+.Dd December 18, 2021
+.Dt BLAG 1
+.Os
+.Sh NAME
+.Nm blag
+.Nd convert plaintext to HTML
+.Sh SYNOPSIS
+.Nm blag
+<
+.Ar in.txt
+>
+.Ar out.html
+.Sh DESCRIPTION
+.Nm
+is a very basic plaintext-to-HTML converter.
+It reads from stdin and writes to stdout so that it can
+.Xr pledge 2
+to only stdio.
+Any arguments given will produce an error.
+.Pp
+Like markdown, wrapped lines are supported,
+and a blank line is needed to start a new paragraph.
+.Pp
+The following markup is supported:
+.Pp
+.Bl -bullet -indent
+.It
+Inline *bold*, _italics_, `code` (bold/italics disabled in code)
+.It
+backslash to escape
+.It
+[alexkarle.com] bare links and [alexkarle.com description]
+.It
+# headers (each # adds a level)
+.It
+Ordered and unordered lists via 1-9. and - respectively.
+Nesting supported only within the same type (no mixing, yet).
+.It
+Code blocks (start line with TAB)
+.It
+Block quotes (start line with >)
+.El
+.Sh SEE ALSO
+.Xr Markdown.pl 1
diff --git a/nihdoc.c b/nihdoc.c
new file mode 100644
index 0000000..c1ace00
--- /dev/null
+++ b/nihdoc.c
@@ -0,0 +1,287 @@
+/*
+ * blag.c -- generate the blog!
+ * ~akarle, MIT License
+ *
+ * "because markdown isn't in base!"
+ */
+#include
+#include
+#include
+
+
+/* Global Constants and Enums */
+char *FMT_STRS[] = {
+ ['_'] = "em",
+ ['*'] = "strong",
+ ['`'] = "code",
+};
+
+enum Block {
+ NONE,
+ HEADER,
+ HEADER_PARSE,
+ PARAGRAPH,
+ CODE,
+ QUOTE,
+ LIST,
+ LIST_PARSE,
+};
+
+enum Link {
+ NOL,
+ URL_PARSE,
+ DESC_PARSE,
+};
+
+
+/* Start Global State */
+int c = '0';
+enum Block in = NONE;
+enum Link in_link = NOL;
+int hlvl = 0;
+bool fmts[256] = {false}; /* indexed by _ * ` */
+bool escape = false;
+char lnkbuf[2048] = {0};
+int lnkidx = 0;
+int indent = 0;
+int previndent = 0;
+int listdepth = 0;
+int lastc = '0';
+bool ol = false;
+bool linestarted = false;
+
+
+/* Helper functions */
+void putesc(int c) {
+ switch (c) {
+ case '<': printf("<"); break;
+ case '>': printf(">"); break;
+ case '&': printf("&"); break;
+ default: putchar(c);
+ }
+}
+
+void newlist() {
+ in = LIST;
+ previndent = indent;
+ printf("<%s>\n\n", ol ? "ol" : "ul");
+ listdepth++;
+}
+
+int endlist() {
+ in = LIST;
+ previndent = indent;
+ printf("\n%s>\n", ol ? "ol" : "ul");
+ return --listdepth;
+}
+
+void maybe_startp() {
+ /* All inline types should start the paragraph if no other major type present*/
+ if (in == NONE) {
+ in = PARAGRAPH;
+ printf("\n");
+ }
+}
+
+void handle_lf() {
+ indent = 0;
+ linestarted = false;
+
+ /* single line types (one lf to close) */
+ if (in == HEADER) {
+ in = NONE;
+ printf("
\n", hlvl);
+ }
+
+ /* terminate url parsing in links */
+ if (in_link == URL_PARSE) {
+ in_link = DESC_PARSE;
+ printf("\">");
+ }
+
+ /* multi-line types (two lf to close) */
+ if (lastc == '\n') {
+ switch (in) {
+ case PARAGRAPH: printf("
\n"); break;
+ case CODE: printf("\n"); break;
+ case QUOTE: printf("\n"); break;
+ case LIST:
+ previndent = 0;
+ while (endlist())
+ ;
+ break;
+ default:
+ break; /* no op */
+ }
+ in = NONE;
+ }
+}
+
+bool fmt_disabled() {
+ /* `` blocks disable all but the next `, likewise CODE makes all disabled */
+ if (in == CODE || in_link == URL_PARSE) {
+ return true;
+ } else {
+ return fmts['`'] && c != '`';
+ }
+}
+
+void toggle_format() {
+ if (!fmt_disabled()) {
+ maybe_startp();
+ printf("<%s%s>", fmts[c] ? "/" : "", FMT_STRS[c]);
+ fmts[c] ^= true;
+ } else {
+ putesc(c);
+ }
+}
+
+int parse() {
+ /* Mini state machine (home grown spaghetti code) */
+ while ((c = getchar()) != EOF) {
+ /* Handle Escapes before all else */
+ if (escape) {
+ maybe_startp();
+ putesc(c);
+ escape = false;
+ continue;
+ }
+
+ /* Store links as we go */
+ if (in_link == URL_PARSE && c != ']') {
+ lnkbuf[lnkidx++] = c;
+ }
+
+ /* Store the indentation */
+ if (!linestarted && c == ' ') {
+ indent++;
+ continue; /* don't print leading indents */
+ }
+
+ /* Handle unique state changes by char */
+ switch (c) {
+ case '\\':
+ escape = true;
+ break;
+ case '#':
+ if (in == NONE) {
+ in = HEADER_PARSE;
+ hlvl = 1;
+ } else if (in == HEADER_PARSE) {
+ hlvl++;
+ } else {
+ /* not a special # */
+ putesc(c);
+ }
+ break;
+ case ' ':
+ if (in == HEADER_PARSE) {
+ printf("", hlvl);
+ in = HEADER;
+ } else if (in_link == URL_PARSE) {
+ in_link = DESC_PARSE;
+ printf("\">");
+ } else if (in == LIST_PARSE) {
+ if (!listdepth) {
+ newlist();
+ } else {
+ if (previndent < indent) {
+ newlist();
+ } else if (previndent > indent) {
+ endlist();
+ printf("\n\n");
+ } else {
+ in = LIST;
+ printf("\n\n");
+ }
+ }
+ } else {
+ putesc(c);
+ }
+ break;
+ case '*':
+ case '`':
+ case '_':
+ toggle_format();
+ break;
+ case '\t':
+ case '>':
+ if (in == NONE) {
+ in = c == '>' ? QUOTE : CODE;
+ printf("%s", c == '>' ? "" : "");
+ } else if (lastc == '\n' && c == (in == CODE ? '\t' : '>')) {
+ /* no op */
+ } else {
+ putesc(c);
+ }
+ break;
+ case '[':
+ if (in_link == NOL && !fmt_disabled()) {
+ maybe_startp();
+ in_link = URL_PARSE;
+ lnkidx = 0;
+ printf("%s", lnkbuf);
+ } else if (in_link == DESC_PARSE) {
+ in_link = NOL;
+ printf("");
+ } else {
+ putesc(c);
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ case '-':
+ if (in == NONE || !linestarted) {
+ ol = c != '-';
+ in = LIST_PARSE;
+ } else if (in != LIST_PARSE) {
+ putesc(c);
+ }
+ break;
+ case '\n':
+ handle_lf();
+ if (in != NONE) {
+ putesc(c);
+ }
+ break;
+ default:
+ maybe_startp();
+ putesc(c);
+ break;
+ }
+ lastc = c;
+ linestarted = c != '\n';
+ }
+ /* pretend there's a final LF to close any blocks */
+ handle_lf();
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ if (argc > 1) {
+ fprintf(stderr, "error: %s takes no arguments\n", argv[0]);
+ return 1;
+ }
+#ifdef __OpenBSD__
+ pledge("stdio", "stdio");
+#endif
+ return parse();
+}
diff --git a/test/big.html b/test/big.html
index fb172a8..29e7f14 100644
--- a/test/big.html
+++ b/test/big.html
@@ -1,6 +1,6 @@
hello world
-This is an example blag file!
+This is an example nihdoc file!
This should be emphasized within a paragraph
diff --git a/test/big.txt b/test/big.txt
index 41b8591..6693f77 100644
--- a/test/big.txt
+++ b/test/big.txt
@@ -1,6 +1,6 @@
# hello world
-This is an example blag file!
+This is an example nihdoc file!
_This should be emphasized within a paragraph_
--
libgit2 1.1.1