compatibility changes: no gensub function
authorPaul Hänsch <paul@plutz.net>
Thu, 29 Aug 2024 22:54:16 +0000 (00:54 +0200)
committerPaul Hänsch <paul@plutz.net>
Thu, 29 Aug 2024 22:54:16 +0000 (00:54 +0200)
markdown.awk

index 7e20ebb0d92c5d2987122f8cab14be55f22d3eff..fcd42cf79247ea7a63e7aa299aae3c0b8c67fce5 100755 (executable)
@@ -154,9 +154,9 @@ function inline( line, LOCAL, len, text, code, href, guard ) {
 
   # Wiki style links
   } else if ( match( line, /^\[\[([^]|]+)(\|[^]]+)?\]\]/) ) {
-    len = RLENGTH;
-    href = gensub(/^\[\[([^]|]+)(\|([^]]+))?\]\]/, "\\1", 1, substr(line, 1, len) );
-    text = gensub(/^\[\[([^]|]+)(\|([^]]+))?\]\]/, "\\3", 1, substr(line, 1, len) );
+    len = RLENGTH; href = text = substr(line, 1, len);
+    sub(/^\[\[([^]|]+)(\|([^]]+))?\]\]/, "\\1", href );
+    sub(/^\[\[([^]|]+)(\|([^]]+))?\]\]/, "\\3", text );
     if ( ! text ) text = href;
     return "<a href=\"" HTML(href) "\">" HTML(text) "</a>" inline( substr( line, len + 1) );
 
@@ -197,9 +197,11 @@ function inline( line, LOCAL, len, text, code, href, guard ) {
 
   # reference style links
   } else if ( match(line, /^\[([^]]+)\] ?\[([^]]*)\]/ ) ) {
-    len = RLENGTH;
-    text = gensub(/^\[([^\n]+)\] ?\[([^\n]*)\].*/, "\\1", 1, substr(line, 1, len) );
-      id = gensub(/^\[([^\n]+)\] ?\[([^\n]*)\].*/, "\\2", 1, substr(line, 1, len) );
+    len = RLENGTH; text = id = substr(line, 1, len);
+    sub(/\n.*$/, "", text); sub(/^\[/, "", text); sub(/\] ?\[([^\n]*)\].*$/, "", text);
+    sub(/\n.*$/, "",   id); sub(/^\[([^]]+)\] ?\[/, "",   id); sub(/\].*$/, "",   id);
+    # text = gensub(/^\[([^\n]+)\] ?\[([^\n]*)\].*/, "\\1", 1, text );
+    # id = gensub(/^\[([^\n]+)\] ?\[([^\n]*)\].*/, "\\2", 1,   id );
     if ( ! id ) id = text;
     if ( rl_href[id] && rl_title[id] ) {
       return "<a href=\"" HTML(rl_href[id]) "\" title=\"" HTML(rl_title[id]) "\">" inline(text) "</a>" inline( substr( line, len + 1) );
@@ -240,9 +242,11 @@ function inline( line, LOCAL, len, text, code, href, guard ) {
 
   # reference style images
   } else if ( match(line, /^!\[([^]]*)\] ?\[([^]]*)\]/ ) ) {
-    len = RLENGTH;
-    text = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\].*/, "\\1", 1, substr(line, 1, len) );
-      id = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\].*/, "\\2", 1, substr(line, 1, len) );
+    len = RLENGTH; text = id = substr(line, 1, len);
+    sub(/\n.*$/, "", text); sub(/^!\[/, "", text); sub(/\] ?\[([^\n]*)\].*$/, "", text);
+    sub(/\n.*$/, "",   id); sub(/^!\[([^]]+)\] ?\[/, "",   id); sub(/\].*$/, "",   id);
+    # text = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\].*/, "\\1", 1, substr(line, 1, len) );
+    #   id = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\].*/, "\\2", 1, substr(line, 1, len) );
     if ( ! id ) id = text;
     if ( rl_href[id] && rl_title[id] ) {
       return "<img src=\"" HTML(rl_href[id]) "\" alt=\"" HTML(text) "\" title=\"" HTML(rl_title[id]) "\">" \
@@ -304,7 +308,9 @@ function inline( line, LOCAL, len, text, code, href, guard ) {
     return "<em>" inline( substr( line, 2, len - 2 ) ) "</em>" inline( substr( line, len + 1 ) );
 
   # Literal HTML entities
-  } else if ( match( line, /^&([a-zA-Z]{2,32}|#[0-9]{1,7}|#[xX][0-9a-fA-F]{1,6});/) ) {
+  # } else if ( match( line, /^&([a-zA-Z]{2,32}|#[0-9]{1,7}|#[xX][0-9a-fA-F]{1,6});/) ) {
+  # mawk does not support repitition ranges
+  } else if ( match( line, /^&([a-zA-Z][a-zA-Z][a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?|#[0-9][0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?|#[xX][0-9a-fA-F][0-9a-fA-F]?[0-9a-fA-F]?[0-9a-fA-F]?[0-9a-fA-F]?[0-9a-fA-F]?);/) ) {
     len = RLENGTH;
     return substr( line, 1, len ) inline(substr(line, len + 1));
 
@@ -327,7 +333,8 @@ function inline( line, LOCAL, len, text, code, href, guard ) {
 }
 
 function headline( hlvl, htxt, attrib, LOCAL, sec, n, HL) {
-  match(hstack, /([0-9]+( [0-9]+){5})$/); split( substr(hstack, RSTART),  HL);
+  # match(hstack, /([0-9]+( [0-9]+){5})$/); split( substr(hstack, RSTART),  HL);
+  match(hstack, /([0-9]+( [0-9]+)( [0-9]+)( [0-9]+)( [0-9]+)( [0-9]+))$/); split( substr(hstack, RSTART),  HL);
 
   for ( n = hlvl; n <= 6; n++ ) { sec = sec (HL[n]?"</section>":""); }
   HL[hlvl]++; for ( n = hlvl + 1; n <= 6; n++) { HL[n] = 0;}
@@ -336,7 +343,8 @@ function headline( hlvl, htxt, attrib, LOCAL, sec, n, HL) {
   hid = hid HL[1]; for ( n = 2; n <= hlvl; n++) { hid = hid "." HL[n] ; }
   hid = hid ":" URL(htxt, 1);
 
-  sub(/([0-9]+( [0-9]+){5})$/, "", hstack);
+  # sub(/([0-9]+( [0-9]+){5})$/, "", hstack);
+  sub(/([0-9]+( [0-9]+)( [0-9]+)( [0-9]+)( [0-9]+)( [0-9]+))$/, "", hstack);
   hstack = hstack HL[1] " " HL[2] " " HL[3] " " HL[4] " " HL[5] " " HL[6];
 
   return sec "<section class=\"" (attrib ? "h" hlvl " " attrib : "h" hlvl)  "\" id=\"" hid "\">" \
@@ -413,15 +421,14 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
     cols = 0; cnt=0; ttext = "";
 
     # table header and alignment
-    split( gensub( /(^\||\|$)/, "", "g", \
-           gensub( /(^|[^\\])\\\|/, "\\1\\&#x7C;", "g", \
-           substr(block, 1, match(block, /(\n|$)/)) \
-    )), tarray, /\|/);
+    tmp = substr(block, 1, match(block, /(\n|$)/));
+    gsub( /(^|[^\\])\\\|/, "\\1\\&#x7C;", tmp );
+    gsub( /(^\||\|$)/, "", tmp)
+    split( tmp, tarray, /\|/);
     block = substr(block, match(block, /(\n|$)/) + 1 );
-    cols = split( \
-           gensub( /(^\||\|$)/, "", "g", \
-           substr(block, 1, match(block, /(\n|$)/)) \
-    ), talign, /[+\|]/);
+    tmp = substr(block, 1, match(block, /(\n|$)/));
+    gsub( /(^\||\|$)/, "", tmp );
+    cols = split( tmp , talign, /[+\|]/);
     block = substr(block, match(block, /(\n|$)/) + 1 );
 
     for( cnt = 1; cnt < cols; cnt++ ) {
@@ -437,10 +444,10 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
     ttext = ttext "</tr>\n</thead><tbody>\n"
 
     while ( match(block, "^((\\|)?([^\n]+\\|)+[^\n]+(\\|)?(\n|$))+" ) ){
-      split( gensub( /(^\||\|$)/, "", "g", \
-             gensub( /(^|[^\\])\\\|/, "\\1\\&#x7C;", "g", \
-             substr(block, 1, match(block, /(\n|$)/)) \
-      )), tarray, /\|/);
+      tmp = substr(block, 1, match(block, /(\n|$)/));
+      gsub( /(^|[^\\])\\\|/, "\\1\\&#x7C;", tmp );
+      gsub( /(^\||\|$)/, "", tmp );
+      split( tmp, tarray, /\|/);
       block = substr(block, match(block, /(\n|$)/) + 1 );
 
       ttext = ttext "<tr>"
@@ -469,11 +476,14 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
     cols = 0; cnt=0; ttext = "";
 
     # Column Count
-    cols = split(   gensub( "^(\\+(:?-+:?\\+)+)(\n.*)*$", "\\1", 1, block), tread, /\+/) - 2;
+    tmp = block; sub( "(\n.*)*$", "", tmp);
+    cols = split( tmp, tread, /\+/) - 2;
     # debug(" Cols: " gensub( "^(\\+(:?-+:?\\+)+)(\n.*)*$", "\\1", 1, block ));
 
     # table alignment
-    split( gensub( "^(.*\n)?\\+((:?=+:?\\+|(:-+|-+:|:-+:)\\+)+)(\n.*)$", "\\2", "g", block ), talign, /\+/ );
+    match(block, "((:?=+:?\\+|(:-+|-+:|:-+:)\\+)+)");
+    split( substr(block, RSTART, RLENGTH) , talign, /\+/ );
+    # split( gensub( "^(.*\n)?\\+((:?=+:?\\+|(:-+|-+:|:-+:)\\+)+)(\n.*)$", "\\2", "g", block ), talign, /\+/ );
     # debug("Align: " gensub( "^(.*\n)?\\+((:?=+:?\\+|(:-+|-+:|:-+:)\\+)+)(\n.*)$", "\\2", "g", block ));
 
     for (cnt = 1; cnt <= cols; cnt++) {
@@ -492,10 +502,10 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
       # table header
       block = substr(block, match(block, /(\n|$)/) + 1 );
       while ( match(block, "^\\|([^\n]+\\|)+\n") ) {
-        split( gensub( /(^\||\|$)/, "", "g", \
-                 gensub( /(^|[^\\])\\\|/, "\\1\\&#x7C;", "g", \
-                   substr(block, 1, match(block, /(\n|$)/)) \
-        )), tread, /\|/);
+        tmp = substr(block, 1, match(block, /(\n|$)/));
+        gsub( /\\\\/, "\\&#x5C;", tmp); gsub(/\\\|/, "\\&#x7C;", tmp);
+        gsub( /(^\||\|$)/, "", tmp );
+        split(tmp, tread, /\|/);
         block = substr(block, match(block, /(\n|$)/) + 1 );
         for (cnt = 1; cnt <= cols; cnt++)
           tarray[cnt] = tarray[cnt] "\n" tread[cnt];
@@ -514,10 +524,10 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
     while ( match(block, /^((\|([^\n]+\|)+\n)+\+(-+\+)+(\n|$))+/ ) ){
       split("", tarray);
       while ( match(block, /^\|([^\n]+\|)+\n/) ) {
-        split( gensub( /(^\||\|$)/, "", "g", \
-               gensub( /(^|[^\\])\\\|/, "\\1\\&#x7C;", "g", \
-               substr(block, 1, match(block, /(\n|$)/)) \
-        )), tread, /\|/);
+        tmp = substr(block, 1, match(block, /(\n|$)/));
+        gsub( /\\\\/, "\\&#x5C;", tmp); gsub(/\\\|/, "\\&#x7C;", tmp);
+        gsub( /(^\||\|$)/, "", tmp);
+        split( tmp, tread, /\|/);
         block = substr(block, match(block, /(\n|$)/) + 1 );
         for (cnt = 1; cnt <= cols; cnt++)
           tarray[cnt] = tarray[cnt] "\n" tread[cnt];
@@ -542,8 +552,9 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
     return "<div class=\"line-block\">" text "</div>\n" _block( substr( block, len + 1) );
 
   # Indented Code Block
-  } else if ( match(block, /^(    |\t)( *\t*[^ \t\n]+ *\t*)+(\n|$)((    |\t)[^\n]+(\n|$)|[ \t]*(\n|$))*/) ) {
+  } else if ( match(block, /^((    |\t)[^\n]*[^\n\t ][^\n]*(\n|$))((    |\t)[^\n]*(\n|$)|[\t ]*(\n|$))*/) ) {
     len = RLENGTH; st = RSTART;
+
     code = substr(block, 1, len);
     gsub(/(^|\n)(    |\t)/, "\n", code);
     gsub(/^\n|\n+$/, "", code);
@@ -552,9 +563,10 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
 
   # Fenced Divs (pandoc, custom)
   } else if ( match( block, /^(:::+)/ ) ) {
-    guard = substr( block, 1, RLENGTH );
-    code = block; sub(/^[^\n]+\n/, "", code);
-    attrib = gensub(/^:::+[ \t]*\{?[ \t]*([^\}\n]*)\}?[ \t]*\n.*$/, "\\1", 1, block);
+    guard = substr( block, 1, RLENGTH ); attrib = code = block;
+    sub(/^[^\n]+\n/, "", code);
+    sub(/^:::+[ \t]*\{?[ \t]*/, "", attrib); sub(/\}?[ \t]*\n.*$/, "", attrib);
+    # attrib = gensub(/^:::+[ \t]*\{?[ \t]*([^\}\n]*)\}?[ \t]*\n.*$/, "\\1", 1, attrib);
     gsub(/[^a-zA-Z0-9_-]+/, " ", attrib);
     gsub(/(^ | $)/, "", attrib);
     if ( match(code, "(^|\n)" guard "+(\n|$)" ) && attrib ) {
@@ -574,9 +586,10 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
 
   # Fenced Code Block (pandoc)
   } else if ( match( block, /^(~~~+|```+)/ ) ) {
-    guard = substr( block, 1, RLENGTH );
-    code = gensub(/^[^\n]+\n/, "", 1, block);
-    attrib = gensub(/^(~~~+|```+)[ \t]*\{?[ \t]*([^\}\n]*)\}?[ \t]*\n.*$/, "\\2", 1, block);
+    guard = substr( block, 1, RLENGTH ); attrib = code = block;
+    sub(/^[^\n]+\n/, "", code);
+    sub(/^(~~~+|```+)[ \t]*\{?[ \t]*/, "", attrib); sub(/\}?[ \t]*\n.*$/, "", attrib);
+    # attrib = gensub(/^(~~~+|```+)[ \t]*\{?[ \t]*([^\}\n]*)\}?[ \t]*\n.*$/, "\\2", 1, attrib);
     gsub(/[^a-zA-Z0-9_-]+/, " ", attrib);
     gsub(/(^ | $)/, "", attrib);
     if ( match(code, "(^|\n)" guard "+(\n|$)" ) && attrib ) {
@@ -627,22 +640,26 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
     return headline(2, text, 0) _block( substr( block, len + 1) );
 
   # Nth Order Heading H1 H2 H3 H4 H5 H6 + Attrib
-  } else if ( match( block, /^(#{1,6})[ \t]*(([^ \t\n]+|[ \t]+[^ \t\n#]|[ \t]+#+[ \t]*[^ \t\n#])+)[ \t]*#*([ \t]*\{([a-zA-Z \t-]*)\})(\n|$)/ ) ) {
+  } else if ( match( block, /^(##?#?#?#?#?)[ \t]*(([^ \t\n]+|[ \t]+[^ \t\n#]|[ \t]+#+[ \t]*[^ \t\n#])+)[ \t]*#*([ \t]*\{([a-zA-Z \t-]*)\})(\n|$)/ ) ) {
     len = RLENGTH; text = attrib = substr(block, 1, len);
-    match(block, /^#{1,6}/); n = RLENGTH;
+    match(block, /^##?#?#?#?#?[^#]/); n = RLENGTH - 1;
 
-    sub(/^(#{1,6})[ \t]*/, "", text);   sub(/[ \t]*#*([ \t]*\{([a-zA-Z \t-]*)\})(\n.*)?$/, "", text);
-    sub(/^(#{1,6})[ \t]*(([^ \t\n]+|[ \t]+[^ \t\n#]|[ \t]+#+[ \t]*[^ \t\n#])+)[ \t]*#*[ \t]*\{/, "", attrib);
+    # sub(/^(##?#?#?#?#?)[ \t]*/, "", text);  # not working in mawk
+    text = substr(text, n + 1); sub(/^[ \t]*/, "", text);
+    sub(/[ \t]*#*([ \t]*\{([a-zA-Z \t-]*)\})(\n.*)?$/, "", text);
+    sub(/^(##?#?#?#?#?)[ \t]*(([^ \t\n]+|[ \t]+[^ \t\n#]|[ \t]+#+[ \t]*[^ \t\n#])+)[ \t]*#*[ \t]*\{/, "", attrib);
     sub(/\})(\n.*)?$/, "", attrib);
     gsub(/[^a-zA-Z0-9_-]+/, " ", attrib); gsub(/(^ | $)/, "", attrib);
 
     return headline( n, text, attrib ) _block( substr( block, len + 1) );
 
   # Nth Order Heading H1 H2 H3 H4 H5 H6
-  } else if ( match( block, /^(#{1,6})[ \t]*(([^ \t\n]+|[ \t]+[^ \t\n#]|[ \t]+#+[ \t]*[^ \t\n#])+)[ \t]*#*(\n|$)/ ) ) {
+  } else if ( match( block, /^(##?#?#?#?#?)[ \t]*(([^ \t\n]+|[ \t]+[^ \t\n#]|[ \t]+#+[ \t]*[^ \t\n#])+)[ \t]*#*(\n|$)/ ) ) {
     len = RLENGTH; text = substr(block, 1, len);
-    match(block, /^#{1,6}/); n = RLENGTH;
-    sub(/^(#{1,6})[ \t]*/, "", text); sub(/[ \t]*#*(\n.*)?$/, "", text);
+    match(block, /^##?#?#?#?#?[^#]/); n = RLENGTH - 1;
+    # sub(/^(##?#?#?#?#?)[ \t]+/, "", text);  # not working in mawk
+    text = substr(text, n + 1); sub(/^[ \t]*/, "", text);
+    sub(/[ \t]*#*(\n.*)?$/, "", text);
 
     return headline( n, text, 0 ) _block( substr( block, len + 1) );
 
@@ -678,11 +695,12 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
            "</figure>\n\n" \
            _block( substr( block, len + 1) );
 
-  # reference style images (block)
-  } else if ( match(line, /^!\[([^]]*)\] ?\[([^]]*)\](\n|$)/ ) ) {
-    len = RLENGTH;
-    text = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\](\n.*)?$/, "\\1", 1, block);
-      id = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\](\n.*)?$/, "\\2", 1, block);
+  } else if ( match(block, /^!\[([^]]*)\] ?\[([^]]*)\](\n|$)/ ) ) {
+    len = RLENGTH; text = id = block;
+    sub(/(\n.*)?$/, "", text); sub( /^!\[/, "", text); sub(/\] ?\[([^\n]*)\]$/, "", text);
+    sub(/(\n.*)?$/, "",   id); sub( /^!\[([^\n]*)\] ?\[/, "",   id); sub(/\]$/, "",   id);
+    # text = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\](\n.*)?$/, "\\1", 1, block);
+    #   id = gensub(/^!\[([^\n]*)\] ?\[([^\n]*)\](\n.*)?$/, "\\2", 1, block);
     if ( ! id ) id = text;
     if ( rl_href[id] && rl_title[id] ) {
       return "<figure data-src=\"" HTML(rl_href[id]) "\">" \
@@ -701,8 +719,9 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
 
   # Macros (standalone <<macro>> calls handled as block, so they are not wrapped in paragraph)
   } else if ( match( block, /^<<(([^>]|>[^>])+)>>(\n|$)/ ) ) {
-    len = RLENGTH;
-    text = gensub(/^<<(([^>]|>[^>])+)>>(\n.*)?$/, "\\1", 1, block);
+    len = RLENGTH; text = block;
+    sub(/^<</, "", text); sub(/>>(\n.*)?$/, "", text);
+    # text = gensub(/^<<(([^>]|>[^>])+)>>(\n.*)?$/, "\\1", 1, block);
     return "<code class=\"macro\">" HTML(text) "</code>" _block(substr(block, len + 1) );
 
   # Definition list
@@ -743,7 +762,8 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
            _block( substr(block, st + len) );
 
   # Horizontal rule
-  } else if ( match( block, /(^|\n) ? ? ?((\* *){3,}|(- *){3,}|(_ *){3,})($|\n)/) ) {
+  # } else if ( match( block, /(^|\n) ? ? ?((\* *){3,}|(- *){3,}|(_ *){3,})($|\n)/) ) {
+  } else if ( match( block, /(^|\n) ? ? ?((\* *)(\* *)(\* *)(\* *)*|(- *)(- *)(- *)(- *)*|(_ *)(_ *)(_ *)(_ *)*)($|\n)/) ) {
     len = RLENGTH; st = RSTART;
     return _block(substr(block, 1, st - 1)) "<hr>\n" _block(substr(block, st + len));
 
@@ -753,7 +773,7 @@ function _block( block, LOCAL, st, len, text, title, attrib, href, guard, code,
   }
 }
 
-function _startlist(block, type, mark, exclude, LOCAL, st, len, list, indent, text) {
+function _startlist(block, type, mark, exclude, LOCAL, st, len, list, indent, it, text) {
   if (match( block, "(^|\n) ? ? ?" mark "[ \t][^\n]+(\n|$)" \
                                    "(([ \t]*\n)* ? ? ?" mark "[ \t][^\n]+(\n|$)" \
                                    "|([ \t]*\n)*( ? ? ?\t|  +)[^\n]+(\n|$)" \
@@ -761,7 +781,9 @@ function _startlist(block, type, mark, exclude, LOCAL, st, len, list, indent, te
     st = RSTART; len = RLENGTH; list = substr( block, st, len);
 
     sub("^\n", "", list); match(list, "^ ? ? ?"); indent = RLENGTH;
-    gsub( "(^|\n) {0," indent "}", "\n", list); sub("^\n", "", list);
+    it = ""; while ( indent > 0 ) { it = it " ?"; indent--; }
+    # gsub( "(^|\n) {0," indent "}", "\n", list); sub("^\n", "", list);
+    gsub( "(^|\n)" it, "\n", list); sub("^\n", "", list);
 
     text = substr(block, 1, st - 1); block = substr(block, st + len);
     if (match(text, /\n[[:space:]]*\n/)) return 0;
@@ -775,10 +797,12 @@ function _startlist(block, type, mark, exclude, LOCAL, st, len, list, indent, te
   } else return 0;
 }
 
-function _list (block, mark, p, LOCAL, len, st, text, indent, task) {
+function _list (block, mark, p, LOCAL, len, st, text, indent, it, task) {
   if ( match(block, "^([ \t]*\n)*$")) return;
 
   match(block, "^" mark "[ \t]"); indent = RLENGTH;
+  it = ""; while ( indent > 0 ) { it = it " ?"; indent--; }
+
   sub("^" mark "[ \t]", "", block);
 
   if (match(block, /\n[ \t]*\n/)) p = 1;
@@ -787,7 +811,8 @@ function _list (block, mark, p, LOCAL, len, st, text, indent, task) {
   st = (RLENGTH == -1) ? length(block) + 1 : RSTART;
   text = substr(block, 1, st); block = substr(block, st + 1);
 
-  gsub("\n {0," indent "}", "\n", text);
+  # gsub("\n {0," indent "}", "\n", text);
+  gsub("\n" it, "\n", text);
 
   task = match( text, /^\[ \]/   ) ? "<li class=\"task pending\"><input type=checkbox disabled>"      : \
          match( text, /^\[-\]/   ) ? "<li class=\"task negative\"><input type=checkbox disabled>"     : \
@@ -803,7 +828,7 @@ function _list (block, mark, p, LOCAL, len, st, text, indent, task) {
   return task text "</li>\n" _list(block, mark, p);
 }
 
-function _dlist (block, LOCAL, len, st, text, indent, p) {
+function _dlist (block, LOCAL, len, st, text, indent, it, p) {
   if (match( block, "^([ \t]*\n)*[^:\n \t][^\n]+\n" )) {
     len = RLENGTH; text = substr(block, 1, len);
     gsub( "(^\n*|\n*$)", "", text );
@@ -816,8 +841,10 @@ function _dlist (block, LOCAL, len, st, text, indent, p) {
     len = RLENGTH; text = substr(block, 1, len);
     sub( "^([ \t]*\n)*", "", text);
     match(text, "^ ? ? ?:(\t| +)"); indent = RLENGTH;
+    it = ""; while ( indent > 0 ) { it = it " ?"; indent--; }
     sub( "^ ? ? ?:(\t| +)", "", text);
-    gsub( "(^|\n) {0," indent "}", "\n", text );
+    # gsub( "(^|\n) {0," indent "}", "\n", text );
+    gsub( "(^|\n)" it, "\n", text );
 
     text = _nblock(text);
     if (match( text, "^<p>(</p[^>]|</[^p]|<[^/]|[^<])*</p>\n$" ))
@@ -858,10 +885,17 @@ BEGIN {
   re_reflink = "(^|\n) ? ? ?\\[([^]\n]+)\\]: ([^ \t\n]+)(\n?[ \t]+(\"([^\"]+)\"|'([^']+)'|\\(([^)]+)\\)))?(\n|$)";
   # /(^|\n) ? ? ?\[([^]\n]+)\]: ([^ \t\n]+)(\n?[ \t]+("([^"]+)"|'([^']+)'|\(([^)]+)\)))?(\n|$)/
   while ( match(f, re_reflink ) ) {
-    rl_id           = gensub( re_reflink, "\\2", 1, substr(f, RSTART, RLENGTH) );
-    rl_href[rl_id]  = gensub( re_reflink, "\\3", 1, substr(f, RSTART, RLENGTH) );
-    rl_title[rl_id] = gensub( re_reflink, "\\5", 1, substr(f, RSTART, RLENGTH) );
-    f = substr(f, RSTART + RLENGTH);
+    tt = th = ti = substr(f, RSTART, RLENGTH); f = substr(f, RSTART + RLENGTH);
+    sub("(^|\n) ? ? ?\\[", "", ti); sub("\\]: ([^ \t\n]+)(\n?[ \t]+(\"([^\"]+)\"|'([^']+)'|\\(([^)]+)\\)))?(\n.*)?$", "", ti);
+    sub("(^|\n) ? ? ?\\[([^]\n]+)\\]: ", "", th); sub("(\n?[ \t]+(\"([^\"]+)\"|'([^']+)'|\\(([^)]+)\\)))?(\n.*)?$", "", th);
+    if (match(tt, "(^|\n) ? ? ?\\[([^]\n]+)\\]: ([^ \t\n]+)(\n?[ \t]+(\"([^\"]+)\"|'([^']+)'|\\(([^)]+)\\)))(\n|$)")) {
+      sub("(^|\n) ? ? ?\\[([^]\n]+)\\]: ([^ \t\n]+)", "", tt); sub("^\n?[ \t]+", "", tt); sub("(\n.*)?$", "", tt);
+    } else { tt = ""; }
+    rl_id = ti; rl_href[rl_id] = th; rl_title[rl_id] = tt;
+    # rl_id           = gensub( re_reflink, "\\2", 1, substr(f, RSTART, RLENGTH) );
+    # rl_href[rl_id]  = gensub( re_reflink, "\\3", 1, substr(f, RSTART, RLENGTH) );
+    # rl_title[rl_id] = gensub( re_reflink, "\\5", 1, substr(f, RSTART, RLENGTH) );
+    # f = substr(f, RSTART + RLENGTH);
     rl_title[rl_id] = substr( rl_title[rl_id], 2, length(rl_title[rl_id]) - 2 );
     if ( rl_href[rl_id] ~ /<.*>/ ) rl_href[rl_id] = substr( rl_href[rl_id], 2, length(rl_href[rl_id]) - 2 );
   }