Initial implementation

This commit is contained in:
Konstantin Nazarov 2021-06-27 18:06:41 +00:00
commit 9dc13bc2bc
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
2 changed files with 256 additions and 0 deletions

21
README.md Normal file
View file

@ -0,0 +1,21 @@
# A markdown-to-html in pure awk
This awk script reads markdown files and generates html from them.
Compared to other implementations of markdown in awk, it tries to do the right thing most of the time.
You can use `markdown.awk` to generate html pages from your plaintext notes, or send html emails with mutt.
**This is a work in progress**
## Usage
You can try it out by converting this readme to html:
```
awk -f markdown.awk README.md
```
## License
Distributed under the terms of the BSD License

235
markdown.awk Normal file
View file

@ -0,0 +1,235 @@
# markdown implementation in awk
# references:
# - https://gist.github.com/xdanger/116153
# - https://github.com/nuex/zodiac/blob/master/lib/markdown.awk
# - https://dataswamp.org/~solene/2019-08-26-minimal-markdown.html
BEGIN {
si = 0;
stack[si] = "body";
val[si] = 0
res[si] = ""
i = 0;
}
function peek(num) {
return substr($0, i, num);
}
function push(block) {
stack[++si] = block;
res[si] = "";
val[si] = 0;
}
function pop(str) {
res[si-1] = res[si-1] str
res[si] = ""
val[si] = 0
si--
if (stack[si] == "body") {
printf(res[si]);
res[si] = ""
}
}
function handle_code() {
if (peek(1) == "`") {
i = i + 1;
pop("<code>" res[si] "</code>")
return;
}
if ($0 == "") {
pop("`" res[si])
return;
}
if (i > length($0)) {
next;
}
if (i == 1 && length(res[si]) > 0)
res[si] = res[si] " ";
res[si] = res[si] peek(1)
i++;
}
function handle_code_long() {
if (peek(3) == "```") {
i = i + 3;
pop("<code>" res[si] "</code>")
return;
}
if (i > length($0)) {
res[si] = res[si] "\n";
next;
}
res[si] = res[si] peek(1)
i++;
}
function handle_inline_code() {
if (peek(1) == "`") {
i = i + 1;
pop("<code>" res[si] "</code>")
return;
}
if (i > length($0)) {
pop("`" res[si]);
return;
}
res[si] = res[si] peek(1)
i++;
}
function handle_inline_code_long() {
if (peek(3) == "```") {
i = i + 3;
pop("<code>" res[si] "</code>")
return;
}
if (i > length($0)) {
pop("```" res[si]);
return;
}
res[si] = res[si] peek(1)
i++;
}
function handle_inline_strong() {
if (peek(2) == "**") {
i = i + 2;
pop("<strong>" res[si] "</strong>")
return;
}
if (peek(3) == "```") {
i = i + 3;
push("inline_code_long");
return;
}
if (peek(1) == "`") {
i = i + 1;
push("inline_code");
return;
}
if (i > length($0)) {
pop("**" res[si]);
return;
}
res[si] = res[si] peek(1)
i++;
}
function handle_inline() {
if (peek(2) == "**") {
i = i + 2;
push("inline_strong");
return;
}
if (peek(3) == "```") {
i = i + 3;
push("inline_code_long");
return;
}
res[si] = res[si] peek(1);
i++;
}
function handle_block() {
if (peek(3) == "```") {
i = i + 3;
push("code_long");
return;
}
if (peek(1) == "`") {
i = i + 1;
push("code");
return;
}
res[si] = res[si] peek(1);
i++;
}
function handle_paragraph() {
if (i == 1 && ($0 == "" || peek(1) == "#")) {
if (length(res[si]) > 0)
pop("<p>" res[si] "</p>\n");
else
pop("");
if (peek(1) == "#")
return;
next;
}
if (i == 1 && length(res[si]) > 0)
res[si] = res[si] " ";
handle_block();
if (i > length($0))
next;
}
function handle_header() {
if (i == 1) {
match($0, /#+/);
val[si] = RLENGTH;
i = RLENGTH + 1;
return;
}
if (i>length($0)) {
pop("<h" val[si] ">" res[si] "</h" val[si] ">\n");
next;
}
handle_inline();
}
function handle_body() {
if (peek(1) == "#") {
push("header");
return;
}
else {
push("paragraph");
return;
}
}
// {
i = 1;
while (1) {
if (stack[si] == "body")
handle_body();
else if (stack[si] == "paragraph")
handle_paragraph();
else if (stack[si] == "header")
handle_header();
else if (stack[si] == "inline_strong")
handle_inline_strong();
else if (stack[si] == "inline_code_long")
handle_inline_code_long();
else if (stack[si] == "inline_code")
handle_inline_code();
else if (stack[si] == "code_long")
handle_code_long();
else if (stack[si] == "code")
handle_code();
}
}
END {
#print res[si];
#newblock();
}