Summary Files Commits Branches @commit @diff @stats
path: root / single.awk
diff options
context:
space:
mode:
Commit6153a4df213dfb8435a1667fcc9a32f56dce22c1 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-01-01 10:42:49 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-01-01 10:42:49 +0200
Files0b02030fc5c6ffe0bd8fadfa8dc78e78e3040f60 /single.awk
csg-6153a4df213dfb8435a1667fcc9a32f56dce22c1.tar
csg-6153a4df213dfb8435a1667fcc9a32f56dce22c1.tar.gz
csg-6153a4df213dfb8435a1667fcc9a32f56dce22c1.zip
Parent3ffac7c2545544f1ebcf668ca559df974ea89e8d (diff)
feat(single): Implement lists
1 files changed, 65 insertions, 2 deletions
-rw-r--r--single.awk67
diff --git a/single.awk b/single.awk
index e7d55e4..34917bc 100644
--- a/single.awk
+++ b/single.awk
@@ -1,12 +1,12 @@
# Status:
# [.] Inline HTML
# [x] Autoescape
-# [.] Block elements
+# [x] Block elements
# [x] Paragraph
# [x] Line break
# [x] Headers (atx and setex)
# [x] Blockquotes
-# [ ] Lists
+# [x] Lists
# [x] Code blocks
# [x] Horizontal rules
# [x] Span elements
@@ -104,6 +104,7 @@ BEGIN {
not_paragraph = 0
empty0 = empty($0)
emptyP1 = empty(P1)
+ list_started = 0
}
# Output is buffered on multiple lines, held in these variables:
@@ -160,6 +161,68 @@ blockquote_level > 0 && empty0 {
}
/^>$/ { $0 = ""; not_paragraph = 1 }
+# Lists
+function end_list() {
+ if (list_level == 0) return
+ P2 = P2 ORS "</li></" (lists[list_level] == "." ? "o" : "u") "l>"
+ --list_level
+}
+function start_list(level, type) {
+ ## Every two columns we define a new level
+ level = int((level + 2) / 2)
+ ## If list definition is the first line inside a code block
+ if (level - list_level >= 3) return
+
+ ## Make list_level = level - 1
+ while (list_level < level - 1) {
+ lists[++list_level] = ""
+ }
+ ## Make list_level = level
+ while (list_level > level) {
+ end_list()
+ }
+
+ if (list_level == level && lists[list_level] != type) {
+ end_list()
+ }
+ if (list_level < level || lists[list_level] != type) {
+ P1 = P1 ORS "<" (type == "." ? "o" : "u") "l><li>"
+ lists[level] = type
+ list_level = level
+ }
+ else {
+ PNappnd("</li>")
+ P1 = P1 ORS "<li>"
+ }
+ not_paragraph = 1
+ list_started = 1
+}
+!inside_codeblock && /^[ \t]*[*+-] / { ## Unordered list
+ match($0, /^[ \t]*[*+-] /)
+ level = RLENGTH - 2
+ type = char($0, RSTART + RLENGTH - 2)
+ sub(/^[^*+-]*[*+-] /, "")
+
+ start_list(level, type)
+}
+!inside_codeblock && /^[ \t]*[0-9]+\. / { ## Ordered list
+ match($0, /^[ \t]*/)
+ level = RLENGTH
+ type = "."
+ sub(/^[^.]+\. /, "")
+
+ start_list(level, type)
+}
+list_level > 0 && !list_started && /[^ \t]/ { ## Non-list line
+ match($0, /^[ \t]*/)
+ level = int((RLENGTH + 2) / 2)
+ while (list_level >= level) {
+ end_list()
+ }
+ $0 = substr($0, 2 * level - 1)
+ not_paragraph = 1
+}
+
# Code blocks
/^ / {
if (!inside_codeblock) {