feat(package): hemar: interpolation
This commit is contained in:
@@ -227,9 +227,10 @@ parse_tag() {
|
|||||||
|
|
||||||
# shellcheck disable=SC1003
|
# shellcheck disable=SC1003
|
||||||
case "$char" in
|
case "$char" in
|
||||||
'['|']'|'{'|'}'|'"'|'\')
|
']'|'}'|'"'|'\')
|
||||||
log error "not allowed character $WHITE$char$NC on $WHITE$LINE_N$NC:$WHITE$CHAR_N"
|
log error "not allowed character $WHITE$char$NC on $WHITE$LINE_N$NC:$WHITE$CHAR_N"
|
||||||
log error "try to use quoted string"
|
log error "try to use quoted string"
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
'.')
|
'.')
|
||||||
TAG_dote=1
|
TAG_dote=1
|
||||||
@@ -247,6 +248,7 @@ parse_tag() {
|
|||||||
[ ${TAG_in_ws_run+x} ] && {
|
[ ${TAG_in_ws_run+x} ] && {
|
||||||
unset TAG_in_ws_run
|
unset TAG_in_ws_run
|
||||||
if [ "${TAG_seen_first_ws+x}" ]; then
|
if [ "${TAG_seen_first_ws+x}" ]; then
|
||||||
|
log trace "tag in ws -> type: \`${TAG_type:-}\`"
|
||||||
case "${TAG_type:-unknown}" in
|
case "${TAG_type:-unknown}" in
|
||||||
unknown) finalize_first_arg ;;
|
unknown) finalize_first_arg ;;
|
||||||
for)
|
for)
|
||||||
@@ -276,6 +278,7 @@ parse_tag() {
|
|||||||
printf '%s' "$1" >> "$CURRENT_STAGE_BUFFER"
|
printf '%s' "$1" >> "$CURRENT_STAGE_BUFFER"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ! [ "${TAG_in_quoted_string+x}" ]; then
|
||||||
if [ ! "${TAG_pending_close+x}" ] && [ "$char" = ']' ]; then
|
if [ ! "${TAG_pending_close+x}" ] && [ "$char" = ']' ]; then
|
||||||
TAG_pending_close=1
|
TAG_pending_close=1
|
||||||
# NOTE: skip ']' but remember to check next char for a possible '}'
|
# NOTE: skip ']' but remember to check next char for a possible '}'
|
||||||
@@ -283,6 +286,8 @@ parse_tag() {
|
|||||||
elif [ "${TAG_pending_close+x}" ]; then
|
elif [ "${TAG_pending_close+x}" ]; then
|
||||||
unset TAG_pending_close
|
unset TAG_pending_close
|
||||||
if [ "$char" = '}' ]; then
|
if [ "$char" = '}' ]; then
|
||||||
|
finish
|
||||||
|
|
||||||
# NOTE: found `]}` — finish bracket parsing
|
# NOTE: found `]}` — finish bracket parsing
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@@ -292,6 +297,7 @@ parse_tag() {
|
|||||||
else
|
else
|
||||||
is_ws "$char" && { TAG_in_ws_run=1; return 1; }
|
is_ws "$char" && { TAG_in_ws_run=1; return 1; }
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
case "${TAG_grammar_mode:-unknown}" in
|
case "${TAG_grammar_mode:-unknown}" in
|
||||||
unknown)
|
unknown)
|
||||||
@@ -350,7 +356,25 @@ parse_tag() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finish() {
|
||||||
|
case "${TAG_type:-unknown}" in
|
||||||
|
unknown)
|
||||||
|
finish_interpolation_tag
|
||||||
|
;;
|
||||||
|
done)
|
||||||
|
finish_done_tag
|
||||||
|
;;
|
||||||
|
'{[')
|
||||||
|
finish_bracket_tag
|
||||||
|
;;
|
||||||
|
for) ;;
|
||||||
|
*) log panic 'unexpected TAG_type on finish'; exit 13; ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
finalize_first_arg() {
|
finalize_first_arg() {
|
||||||
|
log trace "finalize first arg"
|
||||||
|
log trace "buffer: $(cat "$CURRENT_STAGE_BUFFER")"
|
||||||
case "$(cat "$CURRENT_STAGE_BUFFER")" in
|
case "$(cat "$CURRENT_STAGE_BUFFER")" in
|
||||||
for)
|
for)
|
||||||
TAG_type='for'
|
TAG_type='for'
|
||||||
@@ -360,11 +384,24 @@ finalize_first_arg() {
|
|||||||
exit 13
|
exit 13
|
||||||
;;
|
;;
|
||||||
done)
|
done)
|
||||||
|
finish_done_tag
|
||||||
|
;;
|
||||||
|
'{[')
|
||||||
|
finish_bracket_tag
|
||||||
|
;;
|
||||||
|
*) # interpolation tag
|
||||||
|
finish_interpolation_tag
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_done_tag() {
|
||||||
TAG_type='done'
|
TAG_type='done'
|
||||||
TAG_next_argument_redgect=1
|
TAG_next_argument_redgect=1
|
||||||
# NOTE: Do not save {[ done ]} to the AST becouse it is useless there
|
# NOTE: Do not save {[ done ]} to the AST becouse it is useless there
|
||||||
;;
|
}
|
||||||
'{[')
|
|
||||||
|
finish_bracket_tag() {
|
||||||
TAG_type='actual bracket'
|
TAG_type='actual bracket'
|
||||||
TAG_next_argument_redgect=1
|
TAG_next_argument_redgect=1
|
||||||
if yq -e "${AST_key}[-1].type == \"text\"" "$AST" > /dev/null; then
|
if yq -e "${AST_key}[-1].type == \"text\"" "$AST" > /dev/null; then
|
||||||
@@ -375,8 +412,10 @@ finalize_first_arg() {
|
|||||||
\"value\": \"{[\"
|
\"value\": \"{[\"
|
||||||
}]" "$AST"
|
}]" "$AST"
|
||||||
fi
|
fi
|
||||||
;;
|
}
|
||||||
*) # interpolation tag
|
|
||||||
|
finish_interpolation_tag() {
|
||||||
|
log trace 'finish interpolation tag'
|
||||||
TAG_type='interpolation'
|
TAG_type='interpolation'
|
||||||
TAG_next_argument_redgect=1
|
TAG_next_argument_redgect=1
|
||||||
buf=$(cat "$STAGE_BUFFER_1")
|
buf=$(cat "$STAGE_BUFFER_1")
|
||||||
@@ -384,8 +423,6 @@ finalize_first_arg() {
|
|||||||
\"type\": \"interpolation\",
|
\"type\": \"interpolation\",
|
||||||
\"path\": \"$(json_escape "$buf")\"
|
\"path\": \"$(json_escape "$buf")\"
|
||||||
}]" "$AST"
|
}]" "$AST"
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# finds open pattern and stores the char to the STAGE_BUFFER_1
|
# finds open pattern and stores the char to the STAGE_BUFFER_1
|
||||||
@@ -414,7 +451,7 @@ parse() {
|
|||||||
# Text Stage - save char in STAGE_BUFFER_1 until next tag opens
|
# Text Stage - save char in STAGE_BUFFER_1 until next tag opens
|
||||||
0)
|
0)
|
||||||
if find_open_pattern "$char"; then
|
if find_open_pattern "$char"; then
|
||||||
log debug "open pattern founded"
|
log trace "open pattern founded"
|
||||||
buf=$(cat "$CURRENT_STAGE_BUFFER")
|
buf=$(cat "$CURRENT_STAGE_BUFFER")
|
||||||
yq -o j -i "$AST_key += [{
|
yq -o j -i "$AST_key += [{
|
||||||
\"type\": \"text\",
|
\"type\": \"text\",
|
||||||
@@ -430,9 +467,10 @@ parse() {
|
|||||||
log_buffers
|
log_buffers
|
||||||
|
|
||||||
# zero-initialization
|
# zero-initialization
|
||||||
|
unset TAG_seen_first_ws TAG_in_ws_run TAG_pending_close TAG_type TAG_next_argument_redgect TAG_grammar_mode TAG_in_quoted_string TAG_dote
|
||||||
|
|
||||||
buf_reset
|
buf_reset
|
||||||
STAGE=1
|
STAGE=0
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
@@ -470,12 +508,16 @@ done
|
|||||||
|
|
||||||
CHAR_N=1
|
CHAR_N=1
|
||||||
LINE_N=1
|
LINE_N=1
|
||||||
#LINE_NUMBER=1
|
|
||||||
while :; do
|
while :; do
|
||||||
# read exactly 1 byte; preserve newlines
|
hex="$(dd bs=1 count=1 2>/dev/null | od -An -t u1)"
|
||||||
if ! char="$(dd bs=1 count=1 2>/dev/null)"; then
|
|
||||||
|
[ -z "$hex" ] && {
|
||||||
break
|
break
|
||||||
fi
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2059
|
||||||
|
char="$(printf "\\$(printf '%03o' "$hex")")"
|
||||||
|
|
||||||
# NOTE: if $char is empty, it because `dd` returned '\n' but `$(...)`
|
# NOTE: if $char is empty, it because `dd` returned '\n' but `$(...)`
|
||||||
# removed it as trailing '\n', so I set $char as '\n' here
|
# removed it as trailing '\n', so I set $char as '\n' here
|
||||||
@@ -485,11 +527,15 @@ while :; do
|
|||||||
'
|
'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log trace "char: $WHITE$char"
|
||||||
|
|
||||||
parse "${char:?}"
|
parse "${char:?}"
|
||||||
|
|
||||||
CHAR_N=$((CHAR_N+1))
|
CHAR_N=$((CHAR_N+1))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
log debug 'finishing'
|
||||||
|
|
||||||
# finish TEXT tag if file ends on it
|
# finish TEXT tag if file ends on it
|
||||||
if [ "$STAGE" -eq 0 ]; then
|
if [ "$STAGE" -eq 0 ]; then
|
||||||
if [ "${open_tag_flag+x}" ]; then
|
if [ "${open_tag_flag+x}" ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user