Support for paragraph and code block indentation inside list elements
This commit is contained in:
125
catmd.sh
125
catmd.sh
@@ -11,12 +11,12 @@ DEBUG=:
|
|||||||
rex_emptyline='^$'
|
rex_emptyline='^$'
|
||||||
rex_nonemptyline='^([[:blank:]]*)([[:graph:]]+.*)'
|
rex_nonemptyline='^([[:blank:]]*)([[:graph:]]+.*)'
|
||||||
rex_header='^[[:blank:]]*(#+)[[:blank:]]*(.*)'
|
rex_header='^[[:blank:]]*(#+)[[:blank:]]*(.*)'
|
||||||
rex_list_start='^([[:blank:]]{0,1})([*+-]{1} +|[[:digit:]]+\.)(.*)'; flag_list=0
|
rex_list_start='^([[:blank:]]{0,1})([*+-]{1} +|[[:digit:]]+\.)(.*)'; flag_list=0; indent_list=
|
||||||
rex_list_level='^([[:blank:]]{2,})([*+-]{1} +|[[:digit:]]+\.)(.*)'
|
rex_list_level='^([[:blank:]]{2,})([*+-]{1} +|[[:digit:]]+\.)(.*)'
|
||||||
rex_list="$rex_list_start"
|
rex_list="$rex_list_start"
|
||||||
rex_codeblock='^[[:blank:]]*(```)(.*)'
|
rex_codeblock='^[[:blank:]]*(```)(.*)'
|
||||||
rex_codeinline_start='([^`]*)(`{1,2})(.*)'
|
rex_codeinline_start='([^`]*)(`{1,2})(.*)'
|
||||||
rex_codeinline_space='(^[[:blank:]]{4})(.*)'
|
rex_codeinline_space='(^[[:blank:]]{4})([[:blank:]]*)(.*)'
|
||||||
rex_codeinline1='([^`]*)(`)(.*)'
|
rex_codeinline1='([^`]*)(`)(.*)'
|
||||||
rex_codeinline2='(``)(.*)$' # first part of $line: ${line%"${BASH_REMATCH[0]}"}
|
rex_codeinline2='(``)(.*)$' # first part of $line: ${line%"${BASH_REMATCH[0]}"}
|
||||||
rex_codeinline="$rex_codeinline_start"
|
rex_codeinline="$rex_codeinline_start"
|
||||||
@@ -27,8 +27,12 @@ rex_emphasis="$rex_emphasis_start"
|
|||||||
rex_link='([^[]*\[+)([^]]*)(\]+ *[\([])([^]\)]*)([]\)].*)'
|
rex_link='([^[]*\[+)([^]]*)(\]+ *[\([])([^]\)]*)([]\)].*)'
|
||||||
rex_autolink='([^<]*<)([^>]*)(>)(.*)'
|
rex_autolink='([^<]*<)([^>]*)(>)(.*)'
|
||||||
|
|
||||||
|
TEXT_INDENT=0
|
||||||
|
LIST_INDENT_LAST=
|
||||||
LINE_INDENT=
|
LINE_INDENT=
|
||||||
LINE_INDENT_LEVEL=0
|
LINE_INDENT_N=
|
||||||
|
LINE_EMPTY_N=
|
||||||
|
|
||||||
PARSE_STATE=0
|
PARSE_STATE=0
|
||||||
PARSE_FIX=0
|
PARSE_FIX=0
|
||||||
FIX_STATE=0
|
FIX_STATE=0
|
||||||
@@ -84,9 +88,13 @@ parseline() {
|
|||||||
case "$PARSE_STATE" in
|
case "$PARSE_STATE" in
|
||||||
0) ## Empty line ##
|
0) ## Empty line ##
|
||||||
if [[ "$tocheck" =~ $rex_emptyline ]]; then
|
if [[ "$tocheck" =~ $rex_emptyline ]]; then
|
||||||
|
((LINE_EMPTY_N++))
|
||||||
# End quote
|
# End quote
|
||||||
[ $flag_quote -ne 0 ] && flag_quote=0 && unfix
|
[ $flag_quote -ne 0 ] && flag_quote=0 && unfix
|
||||||
|
|
||||||
|
# End text indent
|
||||||
|
[ $TEXT_INDENT -ne 0 ] && TEXT_INDENT=0
|
||||||
|
|
||||||
# TODO? Catch rouge formates with empty lines outside codeblocks
|
# TODO? Catch rouge formates with empty lines outside codeblocks
|
||||||
echo -ne "$FO_RESET"
|
echo -ne "$FO_RESET"
|
||||||
format_prefix=""
|
format_prefix=""
|
||||||
@@ -95,41 +103,68 @@ parseline() {
|
|||||||
fall || break;;
|
fall || break;;
|
||||||
1) ## Non empty line ##
|
1) ## Non empty line ##
|
||||||
if [[ "$tocheck" =~ $rex_nonemptyline ]]; then
|
if [[ "$tocheck" =~ $rex_nonemptyline ]]; then
|
||||||
# Detect indent TODO detect levels of indent
|
LINE_INDENT_N=${#BASH_REMATCH[1]}
|
||||||
local tab=$(printf '\t')
|
|
||||||
case "${BASH_REMATCH[1]}" in
|
|
||||||
"${tab}${tab}")
|
|
||||||
LINE_INDENT="${BASH_REMATCH[1]}"
|
LINE_INDENT="${BASH_REMATCH[1]}"
|
||||||
$DEBUG -n "2t]";;
|
LINE_EMPTY_N=0
|
||||||
' ')
|
|
||||||
LINE_INDENT="${BASH_REMATCH[1]}"
|
|
||||||
$DEBUG -n "4s]";;
|
|
||||||
' ')
|
|
||||||
LINE_INDENT="${BASH_REMATCH[1]}"
|
|
||||||
$DEBUG -n "2s]";;
|
|
||||||
*)
|
|
||||||
LINE_INDENT=
|
|
||||||
esac
|
|
||||||
# List ending
|
# List ending
|
||||||
if [ $flag_list -ne 0 ] && [ -z "$LINE_INDENT" ]; then
|
if [ $flag_list -ne 0 ] && [ $LINE_INDENT_N -le 1 ] && [ $TEXT_INDENT -eq 0 ]; then
|
||||||
rex_list="$rex_list_start"
|
rex_list="$rex_list_start"
|
||||||
flag_list=0
|
flag_list=0
|
||||||
|
indent_list=
|
||||||
|
LIST_INDENT_LAST=
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fall || break;;
|
fall || break;;
|
||||||
2) ## List ##
|
2) ## List ##
|
||||||
if [[ "$tocheck" =~ $rex_list ]]; then
|
if [[ "$tocheck" =~ $rex_list ]]; then
|
||||||
local indent=
|
|
||||||
|
indent_list[$flag_list]="$LINE_INDENT"
|
||||||
|
LIST_INDENT_LAST="$LINE_INDENT"
|
||||||
|
if (($flag_list > 0 )); then
|
||||||
|
local level=$((${#LINE_INDENT} - ${#indent_list[$flag_list - 1]}))
|
||||||
|
#echo -n $level
|
||||||
|
#if (($level > 1 )); then
|
||||||
|
# echo -n ">]"
|
||||||
|
#elif (($level < -1 )); then
|
||||||
|
# echo -n "<]"
|
||||||
|
#else
|
||||||
|
# echo -n "=]"
|
||||||
|
#fi
|
||||||
|
fi
|
||||||
|
# Detect indent TODO detect levels of indent
|
||||||
|
#local tab=$(printf '\t')
|
||||||
|
#case "$LINE_INDENT" in
|
||||||
|
# "${tab}${tab}")
|
||||||
|
# LINE_INDENT="${BASH_REMATCH[1]}"
|
||||||
|
# $DEBUG -n "2t]";;
|
||||||
|
# ' ')
|
||||||
|
# LINE_INDENT="${BASH_REMATCH[1]}"
|
||||||
|
# $DEBUG -n "4s]";;
|
||||||
|
# ' ')
|
||||||
|
# LINE_INDENT="${BASH_REMATCH[1]}"
|
||||||
|
# $DEBUG -n "2s]";;
|
||||||
|
# *)
|
||||||
|
# LINE_INDENT=
|
||||||
|
#esac
|
||||||
|
|
||||||
|
|
||||||
((flag_list++))
|
((flag_list++))
|
||||||
|
|
||||||
rex_list="$rex_list_level"
|
rex_list="$rex_list_level"
|
||||||
|
local indent=
|
||||||
[ $flag_list -gt 1 ] && indent="$LINE_INDENT" #"${BASH_REMATCH[1]}"
|
[ $flag_list -gt 1 ] && indent="$LINE_INDENT" #"${BASH_REMATCH[1]}"
|
||||||
printf "%s%b%s%b" "$indent" "$FO_LISTITEM" "${BASH_REMATCH[2]}" "$FO_RESET"
|
printf "%s%b%s%b" "$indent" "$FO_LISTITEM" "${BASH_REMATCH[2]}" "$FO_RESET"
|
||||||
tocheck="${BASH_REMATCH[3]}"
|
tocheck="${BASH_REMATCH[3]}"
|
||||||
line="$tocheck"
|
line="$tocheck"
|
||||||
elif [[ "$tocheck" =~ $rex_list_start ]]; then
|
elif [[ "$tocheck" =~ $rex_list_start ]]; then
|
||||||
flag_list=1
|
# Start of new list
|
||||||
|
flag_list=0
|
||||||
|
indent_list=
|
||||||
|
LIST_INDENT_LAST=
|
||||||
rex_list="$rex_list_start"
|
rex_list="$rex_list_start"
|
||||||
continue
|
continue
|
||||||
|
elif [ $flag_list -ne 0 ] && [ $LINE_INDENT_N -le 1 ] && [ $TEXT_INDENT -ne 0 ]; then
|
||||||
|
printf "%-${TEXT_INDENT}s" " "
|
||||||
fi
|
fi
|
||||||
fall || break
|
fall || break
|
||||||
;;
|
;;
|
||||||
@@ -163,15 +198,40 @@ parseline() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fall || break;;
|
fall || break;;
|
||||||
6) ## Inline code blocks ##
|
6) ## Code block started with spaces
|
||||||
|
if [[ "$tocheck" =~ $rex_codeinline_space ]]; then
|
||||||
|
if [ $LINE_INDENT_N -eq 4 ] && [ $flag_list -ne 0 ]; then
|
||||||
|
# First line of text paragraph inside a list item
|
||||||
|
# signaling indentation for the following lines
|
||||||
|
TEXT_INDENT=$LINE_INDENT_N
|
||||||
|
else
|
||||||
|
# Code block started with 4 spaces TODO 2 tabs
|
||||||
|
if [ $flag_list -ne 0 ] && [ $LINE_INDENT_N -ge 8 ]; then
|
||||||
|
# Indent code line according to list level
|
||||||
|
printf "%-4s%s" " " "$LIST_INDENT_LAST"
|
||||||
|
# Remove 4 leading spaces
|
||||||
|
printf "%b%s" "$FO_CODEBLOCK" "${BASH_REMATCH[2]#' '}"
|
||||||
|
else
|
||||||
|
# Print code related spaces
|
||||||
|
printf "%b%s" "$FO_CODEBLOCK" "${BASH_REMATCH[2]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
format_suffix="$FO_RESET"
|
||||||
|
printf "%b%s" "$FO_CODEBLOCK" "${BASH_REMATCH[3]}"
|
||||||
|
line=
|
||||||
|
unfix
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fall || break;;
|
||||||
|
7) ## Inline code blocks ##
|
||||||
if [[ "$tocheck" =~ $rex_codeinline ]]; then
|
if [[ "$tocheck" =~ $rex_codeinline ]]; then
|
||||||
if isfix; then
|
if isfix; then
|
||||||
local lazym="${tocheck%"${BASH_REMATCH[0]}"}"
|
local lazym="${tocheck%"${BASH_REMATCH[0]}"}"
|
||||||
if [ -z "$lazym" ]; then
|
if [ -z "$lazym" ]; then
|
||||||
printf "%s%b" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}" "${FO_RESET}"
|
printf "%b%s%b" "$FO_CODEBLOCK" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}" "${FO_RESET}"
|
||||||
tocheck="${BASH_REMATCH[3]}"
|
tocheck="${BASH_REMATCH[3]}"
|
||||||
else
|
else
|
||||||
printf "%s%b" "${lazym}${BASH_REMATCH[1]}" "${FO_RESET}"
|
printf "%b%s%b" "$FO_CODEBLOCK" "${lazym}${BASH_REMATCH[1]}" "${FO_RESET}"
|
||||||
tocheck="${BASH_REMATCH[2]}"
|
tocheck="${BASH_REMATCH[2]}"
|
||||||
fi
|
fi
|
||||||
rex_codeinline="$rex_codeinline_start"
|
rex_codeinline="$rex_codeinline_start"
|
||||||
@@ -187,18 +247,13 @@ parseline() {
|
|||||||
fix
|
fix
|
||||||
fi
|
fi
|
||||||
line="$tocheck"
|
line="$tocheck"
|
||||||
elif [[ "$tocheck" =~ $rex_codeinline_space ]]; then
|
|
||||||
# TODO check for list indentation
|
|
||||||
format_suffix="$FO_RESET"
|
|
||||||
printf "%b%s" "$FO_CODEBLOCK" "${BASH_REMATCH[2]}"
|
|
||||||
line=
|
|
||||||
break
|
|
||||||
elif isfix; then
|
elif isfix; then
|
||||||
# Open inline block at end of line
|
# Open inline block at end of line
|
||||||
|
format_suffix="$FO_RESET"
|
||||||
fall || break
|
fall || break
|
||||||
fi
|
fi
|
||||||
fall;;
|
fall;;
|
||||||
7) ## Inline emphasis start
|
8) ## Inline emphasis start
|
||||||
if [[ "$tocheck" =~ $rex_emphasis ]]; then
|
if [[ "$tocheck" =~ $rex_emphasis ]]; then
|
||||||
local fo_emphasis=$FO_EMPHASIS1
|
local fo_emphasis=$FO_EMPHASIS1
|
||||||
if isfix; then
|
if isfix; then
|
||||||
@@ -220,11 +275,8 @@ parseline() {
|
|||||||
fall || break
|
fall || break
|
||||||
fi
|
fi
|
||||||
fall;;
|
fall;;
|
||||||
8) ## Links within one line ##
|
9) ## Links within one line ##
|
||||||
if [[ "$tocheck" =~ $rex_link ]]; then
|
if [[ "$tocheck" =~ $rex_link ]]; then
|
||||||
#echo -n "m]"
|
|
||||||
#echo "${BASH_REMATCH[0]}"
|
|
||||||
#echo "${BASH_REMATCH[1]} ! ${BASH_REMATCH[2]} ! ${BASH_REMATCH[3]} ! ${BASH_REMATCH[4]} ! ${BASH_REMATCH[5]}"
|
|
||||||
printf "%s%b%s%b%s%b%s%b%s" "${BASH_REMATCH[1]}" "${FO_LINKTEXT}" "${BASH_REMATCH[2]}" "${FO_RESET}" "${BASH_REMATCH[3]}" "${FO_LINKURL}" \
|
printf "%s%b%s%b%s%b%s%b%s" "${BASH_REMATCH[1]}" "${FO_LINKTEXT}" "${BASH_REMATCH[2]}" "${FO_RESET}" "${BASH_REMATCH[3]}" "${FO_LINKURL}" \
|
||||||
"${BASH_REMATCH[4]}" "${FO_RESET}"
|
"${BASH_REMATCH[4]}" "${FO_RESET}"
|
||||||
tocheck="${BASH_REMATCH[5]}"
|
tocheck="${BASH_REMATCH[5]}"
|
||||||
@@ -235,11 +287,8 @@ parseline() {
|
|||||||
fall || break
|
fall || break
|
||||||
fi
|
fi
|
||||||
fall;;
|
fall;;
|
||||||
9) ## Auto-links within one line ##
|
10) ## Auto-links within one line ##
|
||||||
if [[ "$tocheck" =~ $rex_autolink ]]; then
|
if [[ "$tocheck" =~ $rex_autolink ]]; then
|
||||||
#echo -n "m]"
|
|
||||||
#echo "${BASH_REMATCH[0]}"
|
|
||||||
#echo "${BASH_REMATCH[1]} ! ${BASH_REMATCH[2]} ! ${BASH_REMATCH[3]} ! ${BASH_REMATCH[4]} ! ${BASH_REMATCH[5]}"
|
|
||||||
printf "%s%b%s%b%s" "${BASH_REMATCH[1]}" "${FO_LINKURL}" "${BASH_REMATCH[2]}" "${FO_RESET}" "${BASH_REMATCH[3]}"
|
printf "%s%b%s%b%s" "${BASH_REMATCH[1]}" "${FO_LINKURL}" "${BASH_REMATCH[2]}" "${FO_RESET}" "${BASH_REMATCH[3]}"
|
||||||
tocheck="${BASH_REMATCH[4]}"
|
tocheck="${BASH_REMATCH[4]}"
|
||||||
line="$tocheck"
|
line="$tocheck"
|
||||||
|
Reference in New Issue
Block a user