Initial implementation
This commit is contained in:
commit
9dc13bc2bc
2 changed files with 256 additions and 0 deletions
21
README.md
Normal file
21
README.md
Normal 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
235
markdown.awk
Normal 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();
|
||||||
|
}
|
Loading…
Reference in a new issue