Add codeblock and escaping

This commit is contained in:
davidovki 2023-03-05 03:23:57 +00:00
parent 1eac038e14
commit 58141a0764
2 changed files with 110 additions and 43 deletions

View file

@ -1,9 +1,12 @@
#!/bin/sh #!/bin/sh
ESC_SEQ="ESCAPED!"
# replace all * with _ for easier processing # replace all * with _ for easier processing
# #
_pre_emph () { _pre_emph () {
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n"" $line" && continue;; esac
while [ "$line" != "${line%%\**}" ]; do while [ "$line" != "${line%%\**}" ]; do
printf "%s_" "${line%%\**}" printf "%s_" "${line%%\**}"
line="${line#*\*}" line="${line#*\*}"
@ -17,6 +20,7 @@ _pre_emph () {
# #
_post_emph () { _post_emph () {
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
# TODO: avoid this problem entirely? # TODO: avoid this problem entirely?
local wrong="</strong></em>" right="</em></strong>" local wrong="</strong></em>" right="</em></strong>"
@ -38,6 +42,7 @@ _emph () {
local lefttag="$2" righttag="$3" local lefttag="$2" righttag="$3"
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
next="${line}" next="${line}"
line= line=
rightofbold= rightofbold=
@ -60,6 +65,7 @@ _emph () {
_h () { _h () {
local num=$1 local num=$1
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
s= s=
n=$num n=$num
@ -82,9 +88,10 @@ _h () {
# parse paragraphs # parse paragraphs
# #
_p () { _p () {
empty=true local empty=true
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in case "$line" in
"$ESC_SEQ"*) printf "%s\n" "$line" && continue;;
"#"*|">"*|'``'*|'<'*'>'*) "#"*|">"*|'``'*|'<'*'>'*)
$empty || { $empty || {
printf "</p>\n" printf "</p>\n"
@ -123,6 +130,7 @@ _p () {
_a_img () { _a_img () {
local open="[" mid="](" close=")" local open="[" mid="](" close=")"
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
next="$line" next="$line"
while [ "$next" != "${next#*$close}" ]; do while [ "$next" != "${next#*$close}" ]; do
before="${next%%$open*}" before="${next%%$open*}"
@ -168,89 +176,128 @@ _get_indent () {
printf "$indent" printf "$indent"
} }
# print a string x times
#
# print_x x "string"
print_x () {
x=$1; shift
until [ "$((x=x-1))" -lt "0" ]; do
printf "$*"
done
}
# parse unordered lists # parse unordered lists
# #
_ul () { _ul () {
local list=false local indent_level=-1
local indent_level=0 local to_close=0
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
set -- $line set -- $line
case "$1" in case "$1" in
"-"|"_"|"+") "-"|"_"|"+")
indent=$(_get_indent "$line") indent=$(_get_indent "$line")
$list || { [ "$indent_level" -lt "$indent" ] && {
list=true
printf "<ul>\n" printf "<ul>\n"
to_close=$((to_close+1))
}
[ "$indent_level" -gt "$indent" ] && {
printf "</ul>\n"
to_close=$((to_close-1))
} }
[ "$indent_level" -lt "$indent" ] \
&& printf "<ul>\n"
[ "$indent_level" -gt "$indent" ] \
&& printf "</ul>\n"
indent_level=$indent indent_level=$indent
printf "<li>%s</li>\n" "${line#*$1 }" printf "<li>%s</li>\n" "${line#*$1 }"
;; ;;
*) *)
$list && { [ $to_close -gt 0 ] && {
printf "</ul>" print_x $to_close "</ul>\n"
list=false to_close=0
indent_level=-1
} }
printf "%s\n" "$line" printf "%s\n" "$line"
;; ;;
esac esac
done done
$list && printf "</ul>\n" print_x $to_close "</ul>\n"
} }
# parse ordered lists # parse ordered lists
# #
_ol () { _ol () {
local list=false local indent_level=-1
local indent_level=0 local to_close=0
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
set -- $line set -- $line
case "$1" in case "$1" in
*.|*\)) *.|*\))
indent=$(_get_indent "$line") indent=$(_get_indent "$line")
$list || { [ "$indent_level" -lt "$indent" ] && {
list=true
printf "<ol>\n" printf "<ol>\n"
to_close=$((to_close+1))
}
[ "$indent_level" -gt "$indent" ] && {
printf "</ol>\n"
to_close=$((to_close-1))
} }
[ "$indent_level" -lt "$indent" ] \
&& printf "<ol>\n"
[ "$indent_level" -gt "$indent" ] \
&& printf "</ol>\n"
indent_level=$indent indent_level=$indent
printf "<li>%s</li>\n" "${line#*$1 }" printf "<li>%s</li>\n" "${line#*$1 }"
;; ;;
*) *)
$list && { [ $to_close -gt 0 ] && {
printf "</ol>" print_x $to_close "</ol>\n"
list=false to_close=0
indent_level=-1
} }
printf "%s\n" "$line" printf "%s\n" "$line"
;; ;;
esac esac
done done
$list && printf "</ol>\n" print_x $to_close "</ol>\n"
} }
# parse mutliline codeblocks # parse multiline codeblocks
# #
#_code () { _code () {
#} local codeblock=false content=true
while IFS= read -r line; do
case "$line" in
" "*)
$codeblock &&
printf "%s\n" "$ESC_SEQ${line# }" ||
printf "%s\n" "$line"
$codeblock || $content || {
printf "<pre><code>\n"
codeblock=true
printf "%s\n" "$ESC_SEQ${line# }"
}
;;
*)
$codeblock && {
printf "</code></pre>\n"
codeblock=false
}
printf "%s\n" "$line"
;;
esac
case "$line" in
"") content=false ;;
*) content=true ;;
esac
done
}
# parse quotes # parse quotes
# #
_blockquote () { _blockquote () {
local level=0 local indent_level=0
while IFS= read -r line; do while IFS= read -r line; do
case "$line" in "$ESC_SEQ"*) printf "%s\n" "$line" && continue;; esac
set - $line set - $line
case "$1" in case "$1" in
">"*) ">"*)
@ -267,34 +314,43 @@ _blockquote () {
line="${line#?}" line="${line#?}"
done done
[ "$indent" -gt "$level" ] && print_x $((indent-indent_level)) "<blockquote>\n"
printf "<blockquote>\n" print_x $((indent_level-indent)) "</blockquote>\n"
[ "$indent" -lt "$level" ] && indent_level=$indent
printf "</blockquote>\n" ;;
level="$indent" esac
printf "%s\n" "$line" printf "%s\n" "$line"
done
print_x $((indent_level)) "</blockquote>\n"
}
_post_escape () {
while IFS= read -r line; do
case "$line" in
"$ESC_SEQ"*)
printf "%s\n" "${line#$ESC_SEQ}"
;; ;;
*) *)
printf "%s\n" "$line" printf "%s\n" "$line"
;; ;;
esac esac
done done
[ "$indent" -lt "$level" ] &&
printf "</blockquote>\n"
} }
_html () { _html () {
printf "<!DOCTYPE html>\n" printf "<!DOCTYPE html>\n"
cat while IFS= read -r line; do
printf "%s\n" "$line"
done
} }
# convert the markdown from stdin into html # convert the markdown from stdin into html
# #
md2html () { md2html () {
# the order of these somewhat matters # the order of these somewhat matters
_pre_emph \ _pre_emph \
| _code \
| _blockquote \ | _blockquote \
| _ul \ | _ul \
| _ol \ | _ol \
@ -310,6 +366,7 @@ md2html () {
| _h 3 \ | _h 3 \
| _h 2 \ | _h 2 \
| _h 1 \ | _h 1 \
| _post_escape \
| _html | _html
} }

View file

@ -18,7 +18,6 @@ ok that was a quote
> >
> and also there is another quote; > and also there is another quote;
>> Hi i am a quote >> Hi i am a quote
>
haha haha
@ -28,6 +27,17 @@ haha
- please dont - please dont
- break - break
ok
int main() {
printf("hello %s\n", "world");
}
- list
- sublist
- subsublist
- subsubsublist
* star list * star list
* this is a star * this is a star
@ -40,4 +50,4 @@ haha
3. lOL 3. lOL
ok that worked? > ok that worked?