Skip to content

Commit 81fdec0

Browse files
committed
Update deps (jqmd+mdsh)
1 parent a380272 commit 81fdec0

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

bin/doco

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,34 @@ mdsh-compile() ( # <-- force subshell to prevent escape of compile-time state
4848
)
4949
__COMPILE__() {
5050
[[ $1 == fenced && $fence == $'```' && ! $indent ]] || return 0 # only unindented ``` code
51-
local lang="${2//[^_[:alnum:]]/_}"; # convert language to safe variable/function name
52-
local tag_words; mdsh-splitwords "$2" tag_words; # check for command blocks first
53-
if [[ ${tag_words[1]-} == '!'* ]]; then
54-
set -- "$3" "$2" "$block_start"; eval "${2#*!}"; return
55-
elif [[ ${tag_words[1]-} == '+'* ]]; then
56-
printf '%s %q\n' "${2#"${tag_words[0]}"*+}" "$3"
57-
elif [[ ${tag_words[1]-} == '|'* ]]; then
58-
echo "${2#"${tag_words[0]}"*|} <<'\`\`\`'"; printf $'%s```\n' "$3"; return
59-
elif fn-exists "mdsh-lang-$lang"; then
60-
mdsh-rewrite "mdsh-lang-$lang" "{" "} <<'\`\`\`'"; printf $'%s```\n' "$3"
61-
elif fn-exists "mdsh-compile-$lang"; then
62-
"mdsh-compile-$lang" "$3" "$2" "$block_start"
51+
local mdsh_lang tag_words; mdsh-splitwords "$2" tag_words; # check for command blocks first
52+
case ${tag_words[1]-} in
53+
'') mdsh_lang=${tag_words[0]-} ;; # fast exit for common case
54+
'@'*)
55+
mdsh_lang=${tag_words[1]#@} ;; # language alias: fall through to function lookup
56+
'!'*)
57+
mdsh_lang=${tag_words[0]}; set -- "$3" "$2" "$block_start"; eval "${2#*!}"; return
58+
;;
59+
'+'*)
60+
printf 'mdsh_lang=%q; %s %q\n' "${tag_words[0]}" "${2#"${tag_words[0]}"*+}" "$3"
61+
return
62+
;;
63+
'|'*)
64+
printf 'mdsh_lang=%q; ' "${tag_words[0]}"
65+
echo "${2#"${tag_words[0]}"*|} <<'\`\`\`'"; printf $'%s```\n' "$3"
66+
return
67+
;;
68+
*) mdsh_lang=${2//[^_[:alnum:]]/_} # convert entire line to safe variable name
69+
esac
70+
if fn-exists "mdsh-lang-$mdsh_lang"; then
71+
mdsh-rewrite "mdsh-lang-$mdsh_lang" "{" "} <<'\`\`\`'"; printf $'%s```\n' "$3"
72+
elif fn-exists "mdsh-compile-$mdsh_lang"; then
73+
"mdsh-compile-$mdsh_lang" "$3" "$2" "$block_start"
6374
else
6475
mdsh-misc "$2" "$3"
6576
fi
66-
67-
if fn-exists "mdsh-after-$lang"; then
68-
mdsh-rewrite "mdsh-after-$lang"
77+
if fn-exists "mdsh-after-$mdsh_lang"; then
78+
mdsh-rewrite "mdsh-after-$mdsh_lang"
6979
fi
7080
}
7181
# split words in $1 into the array named by $2 (REPLY by default), without wildcard expansion
@@ -234,9 +244,9 @@ run-markdown() {
234244
fi
235245
}
236246
mdsh_raw_bash_runtime+=($'#!/usr/bin/env bash\n\n# --- BEGIN jqmd runtime ---\n')
237-
mdsh_raw_bash_runtime+=($'jqmd_imports=\njqmd_filters=\njqmd_defines=\n\nHAVE_FILTERS() { [[ ${jqmd_filters-} ]]; }\nCLEAR_FILTERS() { unset jqmd_filters; JQ_OPTS=(jq); }\n\nIMPORTS() { jqmd_imports+="${jqmd_imports:+$\'\\n\'}$1"; }\nDEFINE() { jqmd_defines+="${jqmd_defines:+$\'\\n\'}$1"; }\nFILTER() {\n\tcase $# in\n\t1) jqmd_filters+="${jqmd_filters:+|}$1"; return ;;\n\t0) return ;;\n\tesac\n\tlocal REPLY ARGS=(printf -v REPLY "$1"); shift\n\tJSON-QUOTE "$@"; ARGS+=("${REPLY[@]}"); "${ARGS[@]}"; FILTER "$REPLY"\n}\n\nJSON-QUOTE() {\n\tset -- "${@//\\\\/\\\\\\\\}"; set -- "${@//\\"/\\\\\\"}" # \\ and "\n\tset -- "${@//$\'\\n\'/\\\\n}"; set -- "${@//$\'\\r\'/\\\\r}"; set -- "${@//$\'\\t\'/\\\\t}" # \\n\\r\\t\n\tset -- "${@/#/\\"}"; set -- "${@/%/\\"}" # leading and trailing \'"\'\n\tREPLY=(); local s r\n\twhile (($#)); do\n\t\ts=${1//[^$\'\\x01\'-$\'\\x1F\']/};\n\t\twhile [[ $s ]]; do\n\t\t\tprintf -v r \\\\\\\\u%04x "\'${s:0:1}"\n\t\t\tset -- "${@//"${s:0:1}"/"$r"}"\n\t\t\ts=${s//"${s:0:1}"/}\n\t\tdone\n\t\tREPLY+=("$1"); shift\n\tdone\n}\n')
238-
mdsh_raw_bash_runtime+=($'JQ_OPTS=(jq)\nJQ_OPTS() { JQ_OPTS+=("$@"); }\nARG() { JQ_OPTS --arg "$1" "$2"; }\nARGJSON() { JQ_OPTS --argjson "$1" "$2"; }\nARGQUOTE() { REPLY=JQMD_QA_${#JQ_OPTS[@]}; ARG "$REPLY" "$1"; REPLY=\'$\'$REPLY; }\n')
239-
mdsh_raw_bash_runtime+=($'JQ_CMD() {\n\tlocal f= opt nargs cmd=(jq); set -- "${JQ_OPTS[@]:1}" "$@"\n\n\twhile (($#)); do\n\t\tcase "$1" in\n\t\t-f|--fromfile)\n\t\t\topt=$(<"$2") || return 69\n\t\t\tFILTER "$opt"; shift 2; continue\n\t\t\t;;\n\t\t-L|--indent) nargs=2 ;;\n\t\t--arg|--arjgson|--slurpfile|--argfile) nargs=3 ;;\n\t\t--) break ;; # rest of args are data files\n\t\t-*) nargs=1 ;;\n\t\t*) FILTER "$1"; break ;;\t# jq program: data files follow\n\t\tesac\n\t\tcmd+=("${@:1:$nargs}")\t# add $nargs args to cmd\n\t\tshift $nargs\n\tdone\n\n\tHAVE_FILTERS || FILTER . # jq needs at least one filter expression\n\tfor REPLY in "${jqmd_imports-}" "${jqmd_defines-}" "${jqmd_filters-}"; do\n\t\t[[ $REPLY ]] && f+=${f:+$\'\\n\'}$REPLY\n\tdone\n\n\tREPLY=("${cmd[@]}" "$f" "${@:2}")\n\tCLEAR_FILTERS # cleanup for any re-runs\n}\n\nRUN_JQ() { JQ_CMD "$@" && "${REPLY[@]}"; }\nCALL_JQ() { JQ_CMD "$@" && REPLY=("$("${REPLY[@]}")"); }\n')
247+
mdsh_raw_bash_runtime+=($'jqmd_imports=\njqmd_filters=\njqmd_defines=\n\nHAVE_FILTERS() { [[ ${jqmd_filters-} ]]; }\nCLEAR_FILTERS() { unset jqmd_filters; JQ_OPTS=(jq); }\n\nIMPORTS() { jqmd_imports+="${jqmd_imports:+$\'\\n\'}$1"; }\nDEFINE() { jqmd_defines+="${jqmd_defines:+$\'\\n\'}$1"; }\nFILTER() {\n\tcase $# in\n\t1) jqmd_filters+="${jqmd_filters:+$\'\\n\'| }$1"; return ;;\n\t0) return ;;\n\tesac\n\tlocal REPLY ARGS=(printf -v REPLY "$1"); shift\n\tJSON-QUOTE "$@"; ARGS+=("${REPLY[@]}"); "${ARGS[@]}"; FILTER "$REPLY"\n}\n\nAPPLY() {\n\tlocal name filter=\'\' REPLY expr=${1-} lf=$\'\\n\'; shift\n\twhile (($#)); do\n\t\tname=${1#@}; REPLY=${name#*=}\n\t\t[[ $name == *=* ]] || REPLY=${!name}\n\t\tif ((${#REPLY} > 32)); then\n\t\t\tif [[ $1 == @* ]]; then ARGVAL "$REPLY"; else ARGSTR "$REPLY"; fi\n\t\telse\n\t\t\tJSON-QUOTE "$REPLY"; [[ $1 != @* ]] || REPLY="($REPLY|fromjson)"\n\t\tfi\n\t\tfilter+=" | $REPLY as \\$${name%%=*}"; shift\n\tdone\n\tfilter=${filter:3}; [[ ! $expr || $expr == . ]] || filter="( ${filter:+$filter | }$expr )"\n\t${filter:+FILTER "$filter"}\n}\n\nJSON-QUOTE() {\n\tlocal LC_ALL=C\n\tset -- "${@//\\\\/\\\\\\\\}"; set -- "${@//\\"/\\\\\\"}" # \\ and "\n\tset -- "${@//$\'\\n\'/\\\\n}"; set -- "${@//$\'\\r\'/\\\\r}"; set -- "${@//$\'\\t\'/\\\\t}" # \\n\\r\\t\n\tset -- "${@/#/\\"}"; set -- "${@/%/\\"}" # leading and trailing \'"\'\n\tREPLY=(); local s r\n\twhile (($#)); do\n\t\ts=${1//[^$\'\\x01\'-$\'\\x1F\']/};\n\t\twhile [[ $s ]]; do\n\t\t\tprintf -v r \\\\\\\\u%04x "\'${s:0:1}"\n\t\t\tset -- "${@//"${s:0:1}"/"$r"}"\n\t\t\ts=${s//"${s:0:1}"/}\n\t\tdone\n\t\tREPLY+=("$1"); shift\n\tdone\n}\n')
248+
mdsh_raw_bash_runtime+=($'JQ_OPTS=(jq)\nJQ_OPTS() { JQ_OPTS+=("$@"); }\nARG() { JQ_OPTS --arg "$1" "$2"; }\nARGJSON() { JQ_OPTS --argjson "$1" "$2"; }\nARGQUOTE() { ARGSTR "$1"; } # deprecated\nARGSTR() { REPLY=JQMD_QA_${#JQ_OPTS[@]}; ARG "$REPLY" "$1"; REPLY=\'$\'$REPLY; }\nARGVAL() { REPLY=JQMD_JA_${#JQ_OPTS[@]}; ARGJSON "$REPLY" "$1"; REPLY=\'$\'$REPLY; }\n')
249+
mdsh_raw_bash_runtime+=($'JQ_CMD() {\n\tlocal f= opt nargs cmd=(jq); set -- "${JQ_OPTS[@]:1}" "$@"\n\n\twhile (($#)); do\n\t\tcase "$1" in\n\t\t-f|--fromfile)\n\t\t\topt=$(<"$2") || return 69\n\t\t\tFILTER "$opt"; shift 2; continue\n\t\t\t;;\n\t\t-L|--indent) nargs=2 ;;\n\t\t--arg|--argjson|--slurpfile|--argfile) nargs=3 ;;\n\t\t--) break ;; # rest of args are data files\n\t\t-*) nargs=1 ;;\n\t\t*) FILTER "$1"; break ;;\t# jq program: data files follow\n\t\tesac\n\t\tcmd+=("${@:1:$nargs}")\t# add $nargs args to cmd\n\t\tshift $nargs\n\tdone\n\n\tHAVE_FILTERS || FILTER . # jq needs at least one filter expression\n\tfor REPLY in "${jqmd_imports-}" "${jqmd_defines-}" "${jqmd_filters-}"; do\n\t\t[[ $REPLY ]] && f+=${f:+$\'\\n\'}$REPLY\n\tdone\n\n\tREPLY=("${cmd[@]}" "$f" "${@:2}")\n\tCLEAR_FILTERS # cleanup for any re-runs\n}\n\nRUN_JQ() { JQ_CMD "$@" && "${REPLY[@]}"; }\nCALL_JQ() { JQ_CMD "$@" && REPLY=("$("${REPLY[@]}")"); }\n')
240250
mdsh_raw_bash_runtime+=($'YAML() { y2j "$1"; JSON "$REPLY"; }\nJSON() { FILTER "jqmd_data($1)" "${@:2}"; }\n')
241251
mdsh_raw_bash_runtime+=($'DEFINE \'\ndef jqmd::blend($other; combine): . as $this | . * $other | . as $combined | with_entries(\n if (.key | in($this)) and (.key | in($other)) then\n .this = $this[.key] | .other = $other[.key] | combine\n else . end\n);\n\ndef jqmd::combine: (.this|type) as $this | (.other|type) as $other | .value =\n if $this == "array" then\n if $other == "array" then .this + .other else .this + [.other] end\n elif $this == "object" then\n if $other == "object" then\n .other as $o | (.this | jqmd::blend($o; jqmd::combine))\n else .other end\n else .other end; # everything else just overrides\n\ndef jqmd::data($data): {this: ., other:$data} | jqmd::combine | .value ;\ndef jqmd_data($data): jqmd::data($data) ;\n\'\n')
242252
mdsh_raw_bash_runtime+=($'y2j() {\n\tlocal p j="$(echo "$1" | yaml2json)" || return $?; REPLY=\n\twhile [[ $j == *\'\\\\(\'* ]]; do\n\t\tp=${j%%\'\\\\(\'*}; j=${j#"$p"\'\\\\(\'}\n\t\tif [[ $p =~ (^|[^\\\\])(\'\\\\\\\\\')*$ ]]; then\n\t\t\tp="${p}"\'\\(\' # odd, unbalance the backslash\n\t\telse\n\t\t\tp="${p}(" # even, remove one actual backslash\n\t\tfi\n\t\tREPLY+=$p\n\tdone\n\tREPLY+=$j\n}\n')
@@ -250,6 +260,17 @@ mdsh-compile-yml() { y2j "$1"; mdsh-compile-json "$REPLY"; }
250260
mdsh-compile-yaml() { y2j "$1"; mdsh-compile-json "$REPLY"; }
251261
mdsh-compile-json() { mdsh-compile-jq "jqmd_data($1)"; }
252262

263+
mdsh-compile-func() {
264+
case ${tag_words-} in
265+
yml|yaml) y2j "$1"; REPLY="jqmd_data($REPLY)"$'\n' ;;
266+
json*) REPLY="jqmd_data($1)"$'\n' ;;
267+
jq|javascript|js) REPLY=$1 ;;
268+
*) mdsh-error "Invalid language for function: '%s'" "${tag_words-}"; return
269+
esac
270+
printf 'function %s() {\n\tAPPLY %q \\\n\t\t%s\n}\n' "${tag_words[2]}" "$REPLY" \
271+
"${2#*${tag_words}*${tag_words[1]}*${tag_words[2]}}"
272+
}
273+
253274
const() {
254275
case "${tag_words-}" in
255276
yaml|yml) y2j "$block"; printf 'DEFINE %q\n' "def $1: $REPLY ;"$'\n' ;;

0 commit comments

Comments
 (0)