diff --git a/markdown.awk b/markdown.awk index 6e016f4..20adfcb 100644 --- a/markdown.awk +++ b/markdown.awk @@ -160,17 +160,6 @@ function is_token(str, i, tok) { return substr(str, i, length(tok)) == tok; } -function escape_char(char) { - if (char == "<") - return "<"; - if (char == ">") - return ">"; - if (char == "&") - return "&"; - - return char; -} - function extract_html_tag(str, i, sstr) { sstr=substr(str, i, length(str) - i + 1); @@ -190,6 +179,19 @@ function is_html_tag(str, i, sstr) { return 1; } +function is_escape_sequence(str, i, sstr) { + sstr=substr(str, i, length(str) - i + 1); + + return match(sstr, /^\\[`\\*_{}\[\]()>#.!+-]/); +} + +function escape_text(str) { + gsub(/&/, "\\&", str); + gsub(//, "\\>", str); + return str; +} + function parse_line(str, result, end, i) { #print "block '" str "'" result = "" @@ -211,8 +213,8 @@ function parse_line(str, result, end, i) { else if (is_token(str, i, "```")) { end = find(str, "```", i+3); if (end != 0) { - result = result "" substr(str, i+3, end - i - 3) ""; - i = end+1; + result = result "" escape_text(substr(str, i+3, end - i - 3)) ""; + i = end+2; } else { result = result "```"; @@ -221,20 +223,30 @@ function parse_line(str, result, end, i) { } else if (substr(str, i, 1) == "`") { end = find(str, "`", i+1); - + if (end != 0) { + result = result "" escape_text(substr(str, i+1, end - i - 1)) ""; + i = end+1; + } + else { + result = result "`"; + } } else if (is_html_tag(str, i)) { tag = extract_html_tag(str, i); result = result tag; i = i + length(tag) - 1; } + else if (is_escape_sequence(str, i)) { + result = result escape_text(substr(str, i+1, 1)); + i = i + 1; + } else { if (substr(str, i, 1) == "\n") { if (length(result) > 0) result = result " "; } else { - result = result escape_char(substr(str, i, 1)); + result = result escape_text(substr(str, i, 1)); } } } @@ -284,7 +296,7 @@ function parse_code(str, i, lines, result) { if (match(str, /^```.*```$/)) { gsub(/^```/, "", str); gsub(/\n```$/, "", str); - return "
" str "
"; + return "
" escape_text(str) "
"; } if (match(str, /^ /)) { result = ""; @@ -296,7 +308,7 @@ function parse_code(str, i, lines, result) { result = result "\n" line; } gsub(/^\n/, "", result); - return "
" result "
"; + return "
" escape_text(result) "
"; } return ""; diff --git a/test.sh b/test.sh index 056f331..e635597 100755 --- a/test.sh +++ b/test.sh @@ -121,12 +121,16 @@ check <<-"EOF" first line of code second line of code + +> < & ``` ---

 first line of code
 
-second line of code
+second line of code + +> < & EOF check <<-"EOF" @@ -138,6 +142,12 @@ second line of code

``` first line of code second line of code

EOF +check <<-"EOF" +This is `inline code` +--- +

This is inline code

+EOF + check <<-"EOF" code indented by @@ -311,5 +321,71 @@ foo bar

foo bar

EOF +check <<-"EOF" +\\ + +\` + +\* + +\_ + +\{ + +\} + +\[ + +\] + +\( + +\) + +\> + +\# + +\. + +\! + +\+ + +\- +--- +

\

+

`

+

*

+

_

+

{

+

}

+

[

+

]

+

(

+

)

+

>

+

#

+

.

+

!

+

+

+

-

+EOF + +check <<-"EOF" +`This shouldn't be escaped: \*` +--- +

This shouldn't be escaped: \*

+EOF + +check <<-"EOF" +``` +This shouldn't be escaped: \* +``` +--- +

+This shouldn't be escaped: \*
+EOF + echo echo "All tests passed"