Summary Files Commits Branches @commit @diff @stats
path: root / single.awk
diff options
context:
space:
mode:
Commit03a882950ead37f74ab4953dbd1199ddbc3d7f6c (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-01-01 15:50:49 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-01-01 15:50:49 +0200
Files3d47af86ba6694ae60867d308368b932d8b29596 /single.awk
csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.tar
csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.tar.gz
csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.zip
Parent7f30e62573396b85eb9558faaf943d76ec4750ab (diff)
chore: Rename and reorganize files
1 files changed, 0 insertions, 491 deletions
-rw-r--r--single.awk491
diff --git a/single.awk b/single.awk
deleted file mode 100644
index 50e7f60..0000000
--- a/single.awk
+++ /dev/null
@@ -1,491 +0,0 @@
-# Almost the entire canonical Markdown specification is supported
-# https://daringfireball.net/projects/markdown/syntax
-# Notable behavioural exceptions are:
-# - Block-level HTML elements needn't be separated with blank lines
-# - Lists are identation-aware. List items begin and continue after the same
-# identation with which the list beginning (e.g. "* " or "5. ") was written.
-# The benefit is that all Markdown is parsed as normal inside an item.
-#
-# [.] Non-standard features
-# [x] Strikethrough ~~...~~
-# [x] Superscript ^...^
-# [x] Subscript ~...~
-# [ ] Footnote [^...] (with user customizations)
-# [x] Task list - [ ] (readonly)
-# [ ] Definition lists
-# [ ] Single line
-# [ ] Multi-line
-# [x] Fenced code blocks ```lang ```
-# [ ] Tables
-# [x] Links
-# [x] Link destination (<link> inside anchors)
-# [x] Nested links
-#
-# No character classes have been used, since they aren't supported on every system
-
-function empty(value) {
- return value == ""
-}
-
-function PNappnd(value) {
- if (emptyP1) P2 = P2 ORS value
- else P1 = P1 ORS value
-}
-
-function _next() {
- __buffered_print()
- not_paragraph = 1
- next
-}
-
-function sub_match(replacement) {
- $0 = substr($0, 1, RSTART - 1) replacement substr($0, RSTART + RLENGTH)
-}
-
-function char(string, ind) {
- if (1 > ind || ind > length(string)) {
- return "";
- }
- return substr(string, ind, 1)
-}
-
-function backup_match() {
- backup_rstart = RSTART
- backup_rlength = RLENGTH
-}
-function restore_match() {
- RSTART = backup_rstart
- RLENGTH = backup_rlength
-}
-
-BEGIN {
- ## This is used to convert email autolinks into a series of hex values
- ## Escaped output of: awk 'BEGIN {for (i = 32; i <= 126; ++i){ printf("%c", i) } }'
- ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
- for (i = 1; i < 97; ++i) {
- char_to_dec[char(ascii, i)] = 31 + i
- }
-
- ## We do character escaping by substituting the escape with some
- ## "useless" characters, which we're confident won't appear in actual text.
- ## These are from decimal value 14 to 28 inclusive. They're blank characters,
- ## related to shifting, device control and data transmission.
- escapable = "\\`*_{}[]()#+-.!"
- for (i = 1; i < 16; ++i) {
- escapes[char(escapable, i)] = sprintf("%c", 13 + i)
- }
-}
-
-{
- not_paragraph_p1 = not_paragraph
- not_paragraph = 0
- empty0 = empty($0)
- emptyP1 = empty(P1)
- list_started = 0
-}
-
-# Output is buffered on multiple lines, held in these variables:
-# P2 = last non-empty line before the previous line
-# P1 = previous line
-# $0 = current line
-# N1 = next new line (N1 is always set by the user)
-
-# Inline HTML
-/^[ \t]*<\/?[0-9A-Za-z]+/ {
- match($0, /^[ \t]*/)
- if (last_html || RLENGTH - 2 * list_level < 4) {
- last_html = 1
- _next()
- }
-}
-{
- last_html = 0
-}
-
-# Fenced code blocks
-fenced_codeblock {
- $0 = " " $0
-}
-
-# Code blocks (ending)
-inside_codeblock && (/ ```/ || ! /^( |\t|[ \t]*$)/) {
- PNappnd("</code></pre>")
- inside_codeblock = 0
- emptyP1 = 1
- not_paragraph = 1
- if (fenced_codeblock) {
- fenced_codeblock = 0
- fenced_class = ""
- next
- }
-}
-
-# Link definition
-!inside_codeblock && /^\[[^\]]+\]:[ \t]+.*/ {
- next
-}
-
-# Escapes
-!inside_codeblock && /\\[-\\`*_{}\[\]()#+.!]/ {
- while (match($0, /\\[-\\`*_{}\[\]()#+.!]/)) {
- sub_match(escapes[char($0, RSTART + 1)])
- }
-}
-
-# Horizontal rule
-/^(---+|- - -( -)*|\*\*\*+|\* \* \*( \*)*|___+|_ _ _( _)*)$/ {
- $0 = "<hr/>"
- not_paragraph = 1
-}
-
-# Blockquotes
-blockquote_level > 0 && empty0 {
- if (inside_codeblock) {
- P1 = P1 ORS "</code></pre>"
- inside_codeblock = 0
- }
- for (P1 = P1 ORS; blockquote_level > 0; --blockquote_level) {
- P1 = P1 "</blockquote>"
- }
- not_paragraph_p1 = 1
-}
-/^>[ \t]/ {
- match($0, /^[> \t]*> /)
- level = substr($0, RSTART, RLENGTH)
- $0 = substr($0, RSTART + RLENGTH)
- gsub(/[ \t]/, "", level)
- level = length(level)
-
- for (;blockquote_level < level; ++blockquote_level) {
- P1 = P1 "<blockquote>"
- }
- if (blockquote_level > level) {
- if (inside_codeblock) {
- P2 = P2 ORS "</code></pre>"
- inside_codeblock = 0
- }
- P2 = P2 ORS
- }
- for (;blockquote_level > level; --blockquote_level) {
- P2 = P2 "</blockquote>"
- }
- not_paragraph = 1
-}
-/^>$/ { $0 = ""; not_paragraph = 1 }
-
-# Lists
-function end_list() {
- if (list_level == 0) return
- PNappnd("</li></" (lists[list_level] == "." ? "o" : "u") "l>")
- --list_level
-}
-function start_list(level, type, shift) {
- ## 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
- lists_shift[level] = shift
- 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)
- match($0, /^[^*+-]*[*+-] /)
- shift = RLENGTH
- sub_match("")
-
- start_list(level, type, shift)
-}
-!inside_codeblock && /^[ \t]*[0-9]+\. / { ## Ordered list
- match($0, /^[ \t]*/)
- level = RLENGTH
- type = "."
- match($0, /^[^.]+\. /)
- shift = RLENGTH
- sub_match("")
-
- start_list(level, type, shift)
-}
-list_level > 0 && !list_started && /[^ \t]/ { ## Non-list line
- match($0, /^[ \t]*/)
- level = int((RLENGTH + 2) / 2)
- not_paragraph = 1
- sub("^[ \t]{1," lists_shift[list_level] "}", "")
-
- while (list_level >= level && emptyP1) {
- end_list()
- not_paragraph = 0
- }
-}
-
-# Checklists
-list_started && /^\[[x ]\][ \t]/ {
- checked = (char($0, 2) == "x") ? " checked=\"checked\"" : "";
- $0 = "<input type=\"checkbox\" disabled=\"disabled\"" checked \
- "><label>" substr($0, 5) "</label>"
-}
-
-# Fenced code blocks
-!inside_codeblock && /^[ \t]*```/ {
- fenced_codeblock = 1
-
- match(P1, /```[^ \t]*/)
- if (RLENGTH > 3) {
- fenced_class = " class=\"language-" tolower(substr(P1, RSTART + 3, RLENGTH - 3)) "\""
- }
-
- next
-}
-
-# Code blocks
-/^( |\t)/ {
- ## Autoescape & and <
- for (i = 1; match(substr($0, i), /&/); i += RSTART) {
- RSTART += i - 1
- sub_match("&amp;")
- }
- gsub(/</, "\\&lt;")
- gsub(/>/, "\\&gt;")
-
- if (fenced_codeblock) {
- $0 = substr($0, 5)
- }
- if (!inside_codeblock) {
- $0 = "<pre><code" fenced_class ">" $0
- inside_codeblock = 1
- }
-
- _next()
-}
-
-# Automatic links
-/<[^ \t<>]+>/ {
- ## URL: <uri_scheme:...>
- while (match($0, /<[A-Za-z][-A-Za-z0-9+.]*:[^ \t<>]+>/)) {
- href = substr($0, RSTART + 1, RLENGTH - 2)
- sub_match("<a href=\"" href "\">" href "</a>")
- }
-
- ## Email addresses, with support for quoted local part "..."@...
- ## and ip address literal ...@[...]
- while (match($0, /<([^ \t<>]+|".+")@([-A-Za-z0-9]+\.[^ \t<>]+|\[[0-9A-Fa-f.:]+\])>/)) {
- href = substr($0, RSTART + 1, RLENGTH - 2)
- href_masked = ""
- ## The original markdown blogpost calls for convertions of all
- ## email characters into their hex values. Allegedly, this fools
- ## many autoharvesting spam bots.
- for (i = length(href); i > 0; --i) {
- href_masked = sprintf("&#x%X;", char_to_dec[char(href, i)]) href_masked
- }
- ## href="mailto:..."
- sub_match("<a href=\"&#x6D;&#x61;&#x69;&#x6C;&#x74;&#x6F;&#x3A;" href_masked "\">" href_masked "</a>")
- }
-}
-
-# Autoescape &
-/&/ {
- for (i = 1; match(substr($0, i), /&/); i += RSTART) {
- RSTART += i - 1
- if (substr($0, RSTART) ~ /&[A-Za-z0-9#]+;/) { continue }
- sub_match("&amp;")
- }
-}
-# Autoescape <
-/ < / {
- gsub(/ < /, "\\&lt;")
-}
-
-# Line break
-/ $/ {
- sub(/[ \t]* $/, "</br>")
-}
-
-# atx-style headers
-/^[ \t]*#+/ {
- match($0, /#+/)
- if (RLENGTH <= 6) {
- ## Remove prefix/suffix
- gsub(/^[ \t]*#+[ \t]*/, "")
- gsub(/[ \t]*#+[ \t]*$/, "")
-
- $0 = "<h" RLENGTH ">" $0 "</h" RLENGTH ">"
- not_paragraph = 1
- }
-}
-
-# setex-style headers
-!emptyP1 && /^[ \t]*(=|-)+[ \t]*$/ {
- hlevel = 1 + ($0 ~ /-/)
- P1 = "<h" hlevel ">" substr(P1, 4) "</h" hlevel ">"
- $0 = ""
- not_paragraph = 1
-}
-
-# Emphasis
-function surround(brace, left, right, blen) {
- if (blen == "") { blen = length(brace) }
- if (match($0, brace (brace == "``" ? "." : "[^" brace "]") "+" brace)) {
- elem = left substr($0, RSTART + blen, RLENGTH - 2*blen) right
- if (brace == "``") { gsub("`", "\\&#96;", elem) }
- sub_match(elem)
- return 1;
- }
- return 0
-}
-function gsurround(brace, left, right, blen) {
- while (surround(brace, left, right, blen)) {}
-
- if (blen == 1) {
- gsub("\\\\", "", brace)
- ## Surrounding a single character span with spaces should make it a
- ## literal char. This is inelegant but functional.
- gsub(" " left " ", " " brace " ")
- gsub(" " right " ", " " brace " ")
- }
-}
-
-{
- ## Make sure <em> is on the inside for long chains
- ## E.g. *****a***** will be the same as ****_a_****
- surround("___" , "<strong><em>", "</em></strong>")
- surround("\\*\\*\\*", "<strong><em>", "</em></strong>", 3)
-
- gsurround("__" , "<strong>", "</strong>")
- gsurround("_" , "<em>" , "</em>")
- gsurround("\\*\\*", "<strong>", "</strong>", 2)
- gsurround("\\*" , "<em>" , "</em>", 1)
- gsurround("``" , "<code>" , "</code>")
- gsurround("`" , "<code>" , "</code>")
-
- gsurround("~~" , "<s>" , "</s>")
- gsurround("~" , "<sub>" , "</sub>")
- gsurround("\\^", "<sup>" , "</sup>", 1)
-}
-
-# Links
-/!?\[[^\]]*\] ?[(\[][^)\]]*[\])]/ {
- while (match($0, /!?\[[^\]]*\] ?[(\[][^)\]]*[\])]/)) {
- link = substr($0, RSTART, RLENGTH)
- backup_match()
-
- ## ](xxxxx)
- match(link, /\] ?[(\[][^)\]]*[\])]$/)
- has_space = char(link, RSTART + 1) == " "
- is_img = char(link, 1) == "!"
-
- ## ...[xxxxx](...)...
- text = substr(link, 2 + is_img, RSTART - 2 - is_img)
- ## ...[...](xxxxx)...
- href = substr(link, RSTART + has_space + 2, RLENGTH - has_space - 3)
-
- title = "\"\""
- if (char(link, RSTART + RLENGTH - 1) == "]") { ## is reference link
- if (href == "") href = text # [...][]
- ## [...]: ... "xxxxx"
- title = reference[href, "title"]
- ## [...]: xxxxx "..."
- href = reference[href, "href"]
- }
- else if (match(href, /[ \t]"[^"]*"[ \t]*$/)) { ## has title
- ## ...[...](... "xxxxx")...
- title = substr(href, RSTART + 1, RLENGTH - 1)
- ## ...[...](xxxxx "...")...
- href = substr(href, 1, RSTART - 1)
- }
-
- if (is_img) elem = "<img src=\"" href "\" alt=\"" text "\" title=" title ">"
- else elem = "<a href=\"" href "\" title=" title ">" text "</a>"
-
- restore_match()
- sub_match(elem)
- }
-}
-
-# Paragraph
-emptyP1 && !empty0 && !not_paragraph { $0 = "<p>" $0 }
-!emptyP1 && empty0 && !not_paragraph_p1 { P1 = P1 "</p>" }
-
-# After all $0 parsing
-{
- __buffered_print()
-}
-function __buffered_print() {
- empty0 = empty($0)
- emptyP1 = empty(P1)
-
- if (empty0 && emptyP1) {
- ++P1_repeats
- }
- else if (!empty0 && emptyP1) {
- P1 = $0
- }
- else {
- print P2
- while (P1_repeats > 0) {
- print ""
- --P1_repeats
- }
- P2 = P1
- P1 = $0
- if (empty0) {
- P1_repeats = 1
- }
- }
-
- if (!empty(N1)) {
- if (emptyP1) {
- P1 = N1
- }
- else {
- print P2
- while (P1_repeats > 0) {
- print ""
- --P1_repeats
- }
- P2 = P1
- P1 = N1
- N1 = ""
- }
- }
-
- ## Fix escaped characters
- for (i = 1; i < 16; ++i) {
- esc = char(escapable, i)
- gsub(escapes[esc], esc, P2)
- }
-}
-
-END {
- print P2
- while (P1_repeats > 0) {
- print ""
- --P1_repeats
- }
- if (!empty(P1)) { print P1 }
- print
- if (!empty(N1)) { print N1 }
-}