Summary Files Commits Branches @commit @diff @stats
path: root / single.awk
diff options
context:
space:
mode:
Commitc5de9e6a21c495241249962b87bca0b4b5d39248 (patch)
Author
 Syndamia <kamen@syndamia.com>
2024-07-21 09:22:18 +0300
Committer
 Syndamia <kamen@syndamia.com>
2024-07-21 09:22:18 +0300
Files9b2921bfeb4fa2a9fe6255411912123aaf19590a /single.awk
csg-c5de9e6a21c495241249962b87bca0b4b5d39248.tar
csg-c5de9e6a21c495241249962b87bca0b4b5d39248.tar.gz
csg-c5de9e6a21c495241249962b87bca0b4b5d39248.zip
Parentf8266b610f9787689a4f121c57c039952ca9cec2 (diff)
[single] Started work on Markdown parser
1 files changed, 119 insertions, 0 deletions
-rw-r--r--single.awk119
diff --git a/single.awk b/single.awk
new file mode 100644
index 0000000..37f9d3a
--- /dev/null
+++ b/single.awk
@@ -0,0 +1,119 @@
+# Status:
+# [.] Inline HTML
+# [x] Autoescape
+# [ ] Block elements
+# [x] Paragraph
+# [ ] Line break
+# [.] Headers (atx and setex)
+# [x] Blockquotes
+# [ ] Lists
+# [ ] Code blocks
+# [x] Horizontal rules
+# [ ] Span elements
+# [ ] Links
+# [ ] Emphasis
+# [ ] Code
+# [ ] Images
+# [ ] Other
+# [ ] Autolinks
+# [ ] Escapes
+
+BEGIN {
+ prev_blankline = blankline = 1
+ newStack("bq-level")
+}
+
+{
+ prev_blankline = blankline
+ blankline = 1
+}
+
+/[^[:blank:]]/ {
+ blankline = 0
+}
+
+# Blockquote Part 1/2
+/^>[[:blank:]]*$/ { next }
+/^> / {
+ level = 0
+ while (match($0, /^> [[:blank:]]*/)) {
+ $0 = substr($0, RLENGTH + 1)
+ level += RSTART
+ while (topStack("bq-level") > level) {
+ print "</blockquote>"
+ popStack("bq-level")
+ }
+ if (topStack("bq-level") < level) {
+ print "<blockquote>"
+ pushStack("bq-level", level)
+ }
+ }
+}
+
+# Inline HTML
+/^[[:blank:]]*<\/?[[:alnum:]]+/ {
+ print
+ next
+}
+
+# Horizontal rules
+/^(-|\*|_) ?(-|\*|_) ?(-|\*|_)+$/ {
+ print "<hr>"
+ blankline = 1
+ next
+}
+
+# atx-style headers
+/^[[:blank:]]*#+/ {
+ match($0, /#+/)
+ if (RLENGTH <= 6) {
+ gsub(/^[[:blank:]]*#+[[:blank:]]*/, "")
+ gsub(/[[:blank:]]*#+[[:blank:]]*$/, "")
+ print "<h" RLENGTH ">" $0 "</h" RLENGTH ">"
+ blankline = 1
+ next
+ }
+}
+
+# setex-style headers TODO
+
+# Code blocks
+/^( |\t)[[:blank:]]*/ {
+}
+
+# Paragraphs
+prev_blankline && !blankline && lengthStack("bq-level") == 0 { print "<p>" }
+!prev_blankline && blankline && lengthStack("bq-level") == 0 { print "</p>" }
+
+# Blockquote Part 2/2
+blankline {
+ while (lengthStack("bq-level") > 0) {
+ print "</blockquote>"
+ popStack("bq-level")
+ }
+}
+
+# Auto-escape &
+/&/ {
+ ampstart = 0
+ while (match(substr($0, ampstart + 1), /&/)) {
+ ampstart += RSTART
+ if (match(substr($0, ampstart), /&[[:alnum:]#]+;/)) { continue }
+
+ $0 = substr($0, 1, ampstart - 1) "&amp;" substr($0, ampstart + 1)
+ }
+}
+# Auto-escape <
+/</ {
+ gsub(/</, "\\&lt;")
+}
+
+{ print }
+
+END {
+ if (!blankline && lengthStack("bq-level") == 0) { print "</p>" }
+ while (lengthStack("bq-level") > 0) {
+ print "</blockquote>"
+ popStack("bq-level")
+ }
+}