X-Git-Url: https://git.plutz.net/?a=blobdiff_plain;f=markdown.awk;h=e652be1d7a992cd4c129251c41ad1d917102069a;hb=987f4ef7db8df774e437d36f199be7c2e1396584;hp=c4e1a72e3e023102f5a60a9ec8046065315114cc;hpb=4f6c3febe9c001b53be4949cccc7e92a20a16433;p=cgilite diff --git a/markdown.awk b/markdown.awk index c4e1a72..e652be1 100755 --- a/markdown.awk +++ b/markdown.awk @@ -11,19 +11,20 @@ # Supported Features / TODO: # ========================== -# [x] done [ ] todo [-] not planned [?] unsure +# [x] done [ ] todo [-] not planned ? unsure # # Basic Markdown - Block elements: # ------------------------------- # - [x] Paragraphs -# - [ ] Double space line breaks +# - [x] Double space line breaks # - [x] Proper block element nesting # - [x] Headings # - [x] ATX-Style Headings # - [x] Blockquotes # - [x] Lists (ordered, unordered) # - [x] Code blocks (using indention) -# - [ ] Horizontal rules +# - [x] Horizontal rules +# - [x] Verbatim HTML block (gfm) # # Basic Markdown - Inline elements: # --------------------------------- @@ -31,40 +32,41 @@ # - [x] Reference style links # - [x] Emphasis *em*/**strong** (*Asterisk*, _Underscore_) # - [x] `code`, also ``code containing `backticks` `` -# - [ ] Images / reference style images +# - [x] Images / reference style images # - [x] # - [x] backslash escapes +# - [ ] Verbatim HTML inline # # Extensions - Block elements: # ---------------------------- -# - [?] Heading identifiers (phpmarkdown, pandoc) -# - [x] Fenced code blocks (phpmarkdown, pandoc) +# - ? Heading identifiers (php md, pandoc) +# - [x] Fenced code blocks (php md, pandoc) # - [-] Fenced code attributes # - [ ] Tables -# - [?] Simple table (pandoc) -# - [?] Multiline table (pandoc) -# - [?] Grid table (pandoc) -# - [?] Pipe table (phpmarkdown, pandoc) +# - ? Simple table (pandoc) +# - ? Multiline table (pandoc) +# - ? Grid table (pandoc) +# - ? Pipe table (php md pandoc) # - [x] Line blocks (pandoc) # - [ ] Task lists (pandoc) -# - [ ] Definition lists (phpmarkdown, pandoc) +# - [ ] Definition lists (php md, pandoc) # - [-] Numbered example lists (pandoc) # - [-] Metadata blocks (pandoc) # - [-] Fenced Divs (pandoc) # # Extensions - Inline elements: # ---------------------------- -# - [ ] Ignore embedded_underscores (phpmarkdown, pandoc) +# - [x] Ignore embedded_underscores (php md, pandoc) # - [x] ~~strikeout~~ (pandoc) # - [x] ^Superscript^ ~Subscript~ (pandoc) # - [-] Bracketed spans (pandoc) # - [-] Inline attributes (pandoc) # - [-] TEX-Math (pandoc) -# - [?] Footnotes (phpmarkdown) -# - [?] Abbreviations (phpmarkdown) -# - [?] "Curly quotes" (smartypants) +# - ? Footnotes (php md) +# - ? Abbreviations (php md) +# - ? "Curly quotes" (smartypants) # - [ ] em-dashes (--) (smartypants old) -# - [?] ... three-dot ellipsis (smartypants) +# - ? ... three-dot ellipsis (smartypants) # - [-] en-dash (smartypants) # - [ ] Automatic em-dash / en-dash # - [ ] Automatic -> Arrows <- @@ -82,7 +84,7 @@ function HTML ( text ) { } function inline( line, LOCAL, len, code, href, guard ) { - nu = "(\\\\\\\\|\\\\[^\\\\]|[^\\\\_])*" # not underline (except when escaped) + nu = "(\\\\\\\\|\\\\[^\\\\]|[^\\\\_]|_[[:alnum:]])*" # not underline (except when escaped) na = "(\\\\\\\\|\\\\[^\\\\]|[^\\\\\\*])*" # not asterisk (except when escaped) ieu = "_([^_[:space:]]|[^_[:space:]]" nu "[^_[:space:]])_" # inner (underline) isu = "__([^_[:space:]]|[^_[:space:]]" nu "[^_[:space:]])__" # inner (underline) @@ -96,6 +98,10 @@ function inline( line, LOCAL, len, code, href, guard ) { } else if ( line ~ /^\\[]\\`\*_\{\}\(\)#\+-\.![]/) { return substr(line, 2, 1) inline( substr(line, 3) ); + # hard brakes + } else if ( match(line, /^ \n/) ) { + return "
\n" inline( substr(line, RLENGTH + 1) ); + # ``code spans`` } else if ( match( line, /^`+/) ) { len = RLENGTH @@ -142,6 +148,32 @@ function inline( line, LOCAL, len, code, href, guard ) { return "" substr(line, 1, len) inline( substr(line, len + 1) ); } + # inline images + } else if ( match(line, /^!\[([^]]+)\]\(([^"\)]+)([ \t]+"([^"]+)")?\)/) ) { + len = RLENGTH; + text = gensub(/^!\[([^]]+)\]\(([^"\)]+)([ \t]+"([^"]+)")?\)/, "\\1", "g", line); + href = gensub(/^!\[([^]]+)\]\(([^"\)]+)([ \t]+"([^"]+)")?\)/, "\\2", "g", line); + title = gensub(/^!\[([^]]+)\]\(([^"\)]+)([ \t]+"([^"]+)")?\)/, "\\4", "g", line); + if ( title ) { + return "\""" inline( substr( line, len + 1) ); + } else { + return "\""" inline( substr( line, len + 1) ); + } + + # reference style images + } else if ( match(line, /^!\[([^]]+)\] ?\[([^]]*)\]/ ) ) { + len = RLENGTH; + text = gensub(/^!\[([^\n]+)\] ?\[([^\n]*)\].*/, "\\1", 1, line); + id = gensub(/^!\[([^\n]+)\] ?\[([^\n]*)\].*/, "\\2", 1, line); + if ( ! id ) id = text; + if ( rl_href[id] && rl_title[id] ) { + return "\""" inline( substr( line, len + 1) ); + } else if ( rl_href[id] ) { + return "\""" inline( substr( line, len + 1) ); + } else { + return "" substr(line, 1, len) inline( substr(line, len + 1) ); + } + # ~~strikeout~~ (pandoc) } else if ( match(line, /^~~([[:graph:]]|[[:graph:]]([^~]|~[^~])*[[:graph:]])~~/) ) { len = RLENGTH; @@ -157,21 +189,35 @@ function inline( line, LOCAL, len, code, href, guard ) { len = RLENGTH; return "" inline( substr( line, 2, len - 2 ) ) "" inline( substr( line, len + 1 ) ); - # __strong__ - } else if ( match(line, "^__(([^_[:space:]]|" ieu ")|([^_[:space:]]|" ieu ")(" nu "|" ieu ")*([^_[:space:]]|" ieu "))__") ) { + # ignore embedded underscores (pandoc, php md) + } else if ( match(line, "^[[:alnum:]](__|_)") ) { + return substr( line, 1, RLENGTH) inline( substr(line, RLENGTH + 1) ); + + # __strong__$ + } else if ( match(line, "^__(([^_[:space:]]|" ieu ")|([^_[:space:]]|" ieu ")(" nu "|" ieu ")*([^_[:space:]]|" ieu "))__$") ) { len = RLENGTH; return "" inline( substr( line, 3, len - 4 ) ) "" inline( substr( line, len + 1 ) ); + # __strong__ + } else if ( match(line, "^__(([^_[:space:]]|" ieu ")|([^_[:space:]]|" ieu ")(" nu "|" ieu ")*([^_[:space:]]|" ieu "))__[[:space:][:punct:]]") ) { + len = RLENGTH; + return "" inline( substr( line, 3, len - 5 ) ) "" inline( substr( line, len) ); + # **strong** } else if ( match(line, "^\\*\\*(([^\\*[:space:]]|" iea ")|([^\\*[:space:]]|" iea ")(" na "|" iea ")*([^\\*[:space:]]|" iea "))\\*\\*") ) { len = RLENGTH; return "" inline( substr( line, 3, len - 4 ) ) "" inline( substr( line, len + 1 ) ); - # _em_ - } else if ( match(line, "^_(([^_[:space:]]|" isu ")|([^_[:space:]]|" isu ")(" nu "|" isu ")*([^_[:space:]]|" isu "))_") ) { + # _em_$ + } else if ( match(line, "^_(([^_[:space:]]|" isu ")|([^_[:space:]]|" isu ")(" nu "|" isu ")*([^_[:space:]]|" isu "))_$") ) { len = RLENGTH; return "" inline( substr( line, 2, len - 2 ) ) "" inline( substr( line, len + 1 ) ); + # _em_ + } else if ( match(line, "^_(([^_[:space:]]|" isu ")|([^_[:space:]]|" isu ")(" nu "|" isu ")*([^_[:space:]]|" isu "))_[[:space:][:punct:]]") ) { + len = RLENGTH; + return "" inline( substr( line, 2, len - 3 ) ) "" inline( substr( line, len ) ); + # *em* } else if ( match(line, "^\\*(([^\\*[:space:]]|" isa ")|([^\\*[:space:]]|" isa ")(" na "|" isa ")*([^\\*[:space:]]|" isa "))\\*") ) { len = RLENGTH; @@ -188,6 +234,46 @@ function _block( block, LOCAL, st, len, hlvl, htxt, guard, code, indent ) { if ( block == "" ) { return ""; + + # HTML #2 + } else if ( match( block, /(^|\n) ? ? ?|$)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) substr(block, st, len) _block(substr(block, st + len)); + + # HTML #3 + } else if ( match( block, /(^|\n) ? ? ?<\?([^\?]|\?[^>])*(\?>|$)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) substr(block, st, len) _block(substr(block, st + len)); + + # HTML #4 + } else if ( match( block, /(^|\n) ? ? ?]*(>|$)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) substr(block, st, len) _block(substr(block, st + len)); + + # HTML #5 + } else if ( match( block, /(^|\n) ? ? ?])*(\]\]>|$)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) substr(block, st, len) _block(substr(block, st + len)); + + # HTML #6 + } else if ( match( tolower(block), /(^|\n) ? ? ?<\/?(address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[123456]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)([[:space:]\n>]|\/>)([^\n]|\n[ \t]*[^\n])*(\n[[:space:]]*\n|$)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) substr(block, st, len) _block(substr(block, st + len)); + + # HTML #1 + } else if ( match( tolower(block), /(^|\n) ? ? ?<(script|pre|style)([[:space:]\n>]).*(<\/script>|<\/pre>|<\/style>|$)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) substr(block, st, len) _block(substr(block, st + len)); + + # HTML #7 + } else if ( match( block, /^ ? ? ?(<\/[A-Za-z][A-Za-z0-9-]* \t]*>|<[A-Za-z][A-Za-z0-9-]*([ \t]+[A-Za-z_:][A-Za-z0-9_\.:-]*[ \t]*=[ \t]*([[:space:]"'=<>`]+|"[^"]*"|'[^']*'))*[ \t]*\/?>)([[:space:]]*\n).*(\n[[:space:]]*\n|$)/) ) { + len = RLENGTH; st = RSTART; + return substr(block, st, len) _block(substr(block, st + len)); + + # Horizontal rule + } else if ( match( block, /(^|\n) ? ? ?((\* *){3,}|(- *){3,}|(_ *){3,})($|\n)/) ) { + len = RLENGTH; st = RSTART; + return _block(substr(block, 1, st - 1)) "
\n" _block(substr(block, st + len)); # Blockquote (leading >) } else if ( match( block, /^> /) ) {