From 03a882950ead37f74ab4953dbd1199ddbc3d7f6c Mon Sep 17 00:00:00 2001 From: Syndamia Date: Wed, 1 Jan 2025 15:50:49 +0200 Subject: chore: Rename and reorganize files --- single.awk | 491 ------------------------------------------------------------- 1 file changed, 491 deletions(-) delete mode 100644 single.awk (limited to 'single.awk') 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 ( 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("") - 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 = "
" - not_paragraph = 1 -} - -# Blockquotes -blockquote_level > 0 && empty0 { - if (inside_codeblock) { - P1 = P1 ORS "" - inside_codeblock = 0 - } - for (P1 = P1 ORS; blockquote_level > 0; --blockquote_level) { - P1 = P1 "" - } - 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 "
" - } - if (blockquote_level > level) { - if (inside_codeblock) { - P2 = P2 ORS "" - inside_codeblock = 0 - } - P2 = P2 ORS - } - for (;blockquote_level > level; --blockquote_level) { - P2 = P2 "
" - } - not_paragraph = 1 -} -/^>$/ { $0 = ""; not_paragraph = 1 } - -# Lists -function end_list() { - if (list_level == 0) return - PNappnd("") - --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>
  • " - lists[level] = type - lists_shift[level] = shift - list_level = level - } - else { - PNappnd("
  • ") - P1 = P1 ORS "
  • " - } - 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 = "" -} - -# 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("&") - } - gsub(//, "\\>") - - if (fenced_codeblock) { - $0 = substr($0, 5) - } - if (!inside_codeblock) { - $0 = "
    " $0
    -		inside_codeblock = 1
    -	}
    -
    -	_next()
    -}
    -
    -# Automatic links
    -/<[^ \t<>]+>/ {
    -	## URL: 
    -	while (match($0, /<[A-Za-z][-A-Za-z0-9+.]*:[^ \t<>]+>/)) {
    -		href = substr($0, RSTART + 1, RLENGTH - 2)
    -		sub_match("" href "")
    -	}
    -
    -	## 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("" href_masked "")
    -	}
    -}
    -
    -# Autoescape &
    -/&/ {
    -	for (i = 1; match(substr($0, i), /&/); i += RSTART) {
    -		RSTART += i - 1
    -		if (substr($0, RSTART) ~ /&[A-Za-z0-9#]+;/) { continue }
    -		sub_match("&")
    -	}
    -}
    -# Autoescape <
    -/ < / {
    -	gsub(/ < /, "\\<")
    -}
    -
    -# Line break
    -/  $/ {
    -	sub(/[ \t]*  $/, "
    ") -} - -# atx-style headers -/^[ \t]*#+/ { - match($0, /#+/) - if (RLENGTH <= 6) { - ## Remove prefix/suffix - gsub(/^[ \t]*#+[ \t]*/, "") - gsub(/[ \t]*#+[ \t]*$/, "") - - $0 = "" $0 "" - not_paragraph = 1 - } -} - -# setex-style headers -!emptyP1 && /^[ \t]*(=|-)+[ \t]*$/ { - hlevel = 1 + ($0 ~ /-/) - P1 = "" substr(P1, 4) "" - $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("`", "\\`", 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 is on the inside for long chains - ## E.g. *****a***** will be the same as ****_a_**** - surround("___" , "", "") - surround("\\*\\*\\*", "", "", 3) - - gsurround("__" , "", "") - gsurround("_" , "" , "") - gsurround("\\*\\*", "", "", 2) - gsurround("\\*" , "" , "", 1) - gsurround("``" , "" , "") - gsurround("`" , "" , "") - - gsurround("~~" , "" , "") - gsurround("~" , "" , "") - gsurround("\\^", "" , "", 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 = "\""" - else elem = "" text "" - - restore_match() - sub_match(elem) - } -} - -# Paragraph -emptyP1 && !empty0 && !not_paragraph { $0 = "

    " $0 } -!emptyP1 && empty0 && !not_paragraph_p1 { P1 = P1 "

    " } - -# 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 } -} -- cgit v1.3.1-23-gd82d