Support for paragraph and code block indentation inside list elements
This commit is contained in:
127
catmd.sh
127
catmd.sh
@@ -11,12 +11,12 @@ DEBUG=:
|
||||
rex_emptyline='^$'
|
||||
rex_nonemptyline='^([[:blank:]]*)([[:graph:]]+.*)'
|
||||
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="$rex_list_start"
|
||||
rex_codeblock='^[[:blank:]]*(```)(.*)'
|
||||
rex_codeinline_start='([^`]*)(`{1,2})(.*)'
|
||||
rex_codeinline_space='(^[[:blank:]]{4})(.*)'
|
||||
rex_codeinline_space='(^[[:blank:]]{4})([[:blank:]]*)(.*)'
|
||||
rex_codeinline1='([^`]*)(`)(.*)'
|
||||
rex_codeinline2='(``)(.*)$' # first part of $line: ${line%"${BASH_REMATCH[0]}"}
|
||||
rex_codeinline="$rex_codeinline_start"
|
||||
@@ -27,8 +27,12 @@ rex_emphasis="$rex_emphasis_start"
|
||||
rex_link='([^[]*\[+)([^]]*)(\]+ *[\([])([^]\)]*)([]\)].*)'
|
||||
rex_autolink='([^<]*<)([^>]*)(>)(.*)'
|
||||
|
||||
TEXT_INDENT=0
|
||||
LIST_INDENT_LAST=
|
||||
LINE_INDENT=
|
||||
LINE_INDENT_LEVEL=0
|
||||
LINE_INDENT_N=
|
||||
LINE_EMPTY_N=
|
||||
|
||||
PARSE_STATE=0
|
||||
PARSE_FIX=0
|
||||
FIX_STATE=0
|
||||
@@ -84,9 +88,13 @@ parseline() {
|
||||
case "$PARSE_STATE" in
|
||||
0) ## Empty line ##
|
||||
if [[ "$tocheck" =~ $rex_emptyline ]]; then
|
||||
((LINE_EMPTY_N++))
|
||||
# End quote
|
||||
[ $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
|
||||
echo -ne "$FO_RESET"
|
||||
format_prefix=""
|
||||
@@ -95,41 +103,68 @@ parseline() {
|
||||
fall || break;;
|
||||
1) ## Non empty line ##
|
||||
if [[ "$tocheck" =~ $rex_nonemptyline ]]; then
|
||||
# Detect indent TODO detect levels of indent
|
||||
local tab=$(printf '\t')
|
||||
case "${BASH_REMATCH[1]}" 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
|
||||
LINE_INDENT_N=${#BASH_REMATCH[1]}
|
||||
LINE_INDENT="${BASH_REMATCH[1]}"
|
||||
LINE_EMPTY_N=0
|
||||
# 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"
|
||||
flag_list=0
|
||||
indent_list=
|
||||
LIST_INDENT_LAST=
|
||||
fi
|
||||
fi
|
||||
fall || break;;
|
||||
2) ## List ##
|
||||
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++))
|
||||
|
||||
rex_list="$rex_list_level"
|
||||
local indent=
|
||||
[ $flag_list -gt 1 ] && indent="$LINE_INDENT" #"${BASH_REMATCH[1]}"
|
||||
printf "%s%b%s%b" "$indent" "$FO_LISTITEM" "${BASH_REMATCH[2]}" "$FO_RESET"
|
||||
tocheck="${BASH_REMATCH[3]}"
|
||||
line="$tocheck"
|
||||
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"
|
||||
continue
|
||||
elif [ $flag_list -ne 0 ] && [ $LINE_INDENT_N -le 1 ] && [ $TEXT_INDENT -ne 0 ]; then
|
||||
printf "%-${TEXT_INDENT}s" " "
|
||||
fi
|
||||
fall || break
|
||||
;;
|
||||
@@ -163,15 +198,40 @@ parseline() {
|
||||
fi
|
||||
fi
|
||||
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 isfix; then
|
||||
local lazym="${tocheck%"${BASH_REMATCH[0]}"}"
|
||||
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]}"
|
||||
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]}"
|
||||
fi
|
||||
rex_codeinline="$rex_codeinline_start"
|
||||
@@ -187,18 +247,13 @@ parseline() {
|
||||
fix
|
||||
fi
|
||||
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
|
||||
# Open inline block at end of line
|
||||
format_suffix="$FO_RESET"
|
||||
fall || break
|
||||
fi
|
||||
fall;;
|
||||
7) ## Inline emphasis start
|
||||
8) ## Inline emphasis start
|
||||
if [[ "$tocheck" =~ $rex_emphasis ]]; then
|
||||
local fo_emphasis=$FO_EMPHASIS1
|
||||
if isfix; then
|
||||
@@ -220,11 +275,8 @@ parseline() {
|
||||
fall || break
|
||||
fi
|
||||
fall;;
|
||||
8) ## Links within one line ##
|
||||
9) ## Links within one line ##
|
||||
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}" \
|
||||
"${BASH_REMATCH[4]}" "${FO_RESET}"
|
||||
tocheck="${BASH_REMATCH[5]}"
|
||||
@@ -235,11 +287,8 @@ parseline() {
|
||||
fall || break
|
||||
fi
|
||||
fall;;
|
||||
9) ## Auto-links within one line ##
|
||||
10) ## Auto-links within one line ##
|
||||
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]}"
|
||||
tocheck="${BASH_REMATCH[4]}"
|
||||
line="$tocheck"
|
||||
|
Reference in New Issue
Block a user