Compare commits

..

No commits in common. "master" and "3.0.2" have entirely different histories.

4 changed files with 37 additions and 89 deletions

View File

@ -117,11 +117,9 @@ There are more scripts available in the [demos directory](demo/) that could help
There are additional features that the program supports. Try using `mo --help` to see what is available. There are additional features that the program supports. Try using `mo --help` to see what is available.
Please note that this command is written in Bash and pulls data from either the environment or (when using `--source`) from a text file that will be sourced and loaded into the environment, which means you will need to have Bash-style variables defined. Please see the examples in `demo/` for different ways you can use `mo`.
Enhancements Enhancements
------------ -----------
In addition to many of the features built-in to Mustache, `mo` includes a number of unique features that make it a bit more powerful. In addition to many of the features built-in to Mustache, `mo` includes a number of unique features that make it a bit more powerful.
@ -265,7 +263,6 @@ Pull requests to solve the following issues would be helpful.
* Dotted names are supported but only for associative arrays (Bash 4). See [`demo/associative-arrays`](demo/associative-arrays) for an example. * Dotted names are supported but only for associative arrays (Bash 4). See [`demo/associative-arrays`](demo/associative-arrays) for an example.
* There's no "top level" object, so `echo '{{.}}' | ./mo` does not do anything useful. In other languages you can say the data for the template is a string and in `mo` the data is always the environment. Luckily this type of usage is rare and `{{.}}` works great when iterating over an array. * There's no "top level" object, so `echo '{{.}}' | ./mo` does not do anything useful. In other languages you can say the data for the template is a string and in `mo` the data is always the environment. Luckily this type of usage is rare and `{{.}}` works great when iterating over an array.
* [Parents](https://mustache.github.io/mustache.5.html#Parents), where a template can override chunks of a partial, are not supported.
* HTML encoding is not built into `mo`. `{{{var}}}`, `{{&var}}` and `{{var}}` all do the same thing. `echo '{{TEST}}' | TEST='<b>' mo` will give you "`<b>`" instead of "`&gt;b&lt;`". * HTML encoding is not built into `mo`. `{{{var}}}`, `{{&var}}` and `{{var}}` all do the same thing. `echo '{{TEST}}' | TEST='<b>' mo` will give you "`<b>`" instead of "`&gt;b&lt;`".

107
mo
View File

@ -38,8 +38,7 @@
#/ This message. #/ This message.
#/ -s=FILE, --source=FILE #/ -s=FILE, --source=FILE
#/ Load FILE into the environment before processing templates. #/ Load FILE into the environment before processing templates.
#/ Can be used multiple times. The file must be a valid shell script #/ Can be used multiple times.
#/ and should only contain variable assignments.
#/ -o=DELIM, --open=DELIM #/ -o=DELIM, --open=DELIM
#/ Set the opening delimiter. Default is "{{". #/ Set the opening delimiter. Default is "{{".
#/ -c=DELIM, --close=DELIM #/ -c=DELIM, --close=DELIM
@ -115,8 +114,6 @@ mo() (
moDoubleHyphens=false moDoubleHyphens=false
MO_OPEN_DELIMITER_DEFAULT="{{" MO_OPEN_DELIMITER_DEFAULT="{{"
MO_CLOSE_DELIMITER_DEFAULT="}}" MO_CLOSE_DELIMITER_DEFAULT="}}"
MO_FUNCTION_CACHE_HIT=()
MO_FUNCTION_CACHE_MISS=()
if [[ $# -gt 0 ]]; then if [[ $# -gt 0 ]]; then
for arg in "$@"; do for arg in "$@"; do
@ -158,7 +155,7 @@ mo() (
moSource="${arg#-s=}" moSource="${arg#-s=}"
fi fi
if [[ -e "$moSource" ]]; then if [[ -f "$moSource" ]]; then
# shellcheck disable=SC1090 # shellcheck disable=SC1090
. "$moSource" . "$moSource"
else else
@ -432,19 +429,20 @@ mo::indirectArray() {
# #
# Returns nothing. # Returns nothing.
mo::trimUnparsed() { mo::trimUnparsed() {
local moI moC local moLast moR moN moT
moI=0 moLast=""
moC=${MO_UNPARSED:0:1} moR=$'\r'
moN=$'\n'
moT=$'\t'
while [[ "$moC" == " " || "$moC" == $'\r' || "$moC" == $'\n' || "$moC" == $'\t' ]]; do while [[ "$MO_UNPARSED" != "$moLast" ]]; do
moI=$((moI + 1)) moLast=$MO_UNPARSED
moC=${MO_UNPARSED:$moI:1} MO_UNPARSED=${MO_UNPARSED# }
MO_UNPARSED=${MO_UNPARSED#"$moR"}
MO_UNPARSED=${MO_UNPARSED#"$moN"}
MO_UNPARSED=${MO_UNPARSED#"$moT"}
done done
if [[ "$moI" != 0 ]]; then
MO_UNPARSED=${MO_UNPARSED:$moI}
fi
} }
@ -902,28 +900,10 @@ mo::parseValue() {
# #
# Returns 0 if the name is a function, 1 otherwise. # Returns 0 if the name is a function, 1 otherwise.
mo::isFunction() { mo::isFunction() {
local moFunctionName
for moFunctionName in "${MO_FUNCTION_CACHE_HIT[@]}"; do
if [[ "$moFunctionName" == "$1" ]]; then
return 0
fi
done
for moFunctionName in "${MO_FUNCTION_CACHE_MISS[@]}"; do
if [[ "$moFunctionName" == "$1" ]]; then
return 1
fi
done
if declare -F "$1" &> /dev/null; then if declare -F "$1" &> /dev/null; then
MO_FUNCTION_CACHE_HIT=( ${MO_FUNCTION_CACHE_HIT[@]+"${MO_FUNCTION_CACHE_HIT[@]}"} "$1" )
return 0 return 0
fi fi
MO_FUNCTION_CACHE_MISS=( ${MO_FUNCTION_CACHE_MISS[@]+"${MO_FUNCTION_CACHE_MISS[@]}"} "$1" )
return 1 return 1
} }
@ -1002,24 +982,13 @@ mo::isArrayIndexValid() {
# Can not use logic like this in case invalid variable names are passed. # Can not use logic like this in case invalid variable names are passed.
# [[ "${!1-a}" == "${!1-b}" ]] # [[ "${!1-a}" == "${!1-b}" ]]
# #
# Using logic like this gives false positives.
# [[ -v "$a" ]]
#
# Declaring a variable is not the same as assigning the variable.
# export x
# declare -p x # Output: declare -x x
# export y=""
# declare -p y # Output: declare -x y=""
# unset z
# declare -p z # Error code 1 and output: bash: declare: z: not found
#
# Returns true (0) if the variable is set, 1 if the variable is unset. # Returns true (0) if the variable is set, 1 if the variable is unset.
mo::isVarSet() { mo::isVarSet() {
if declare -p "$1" &> /dev/null && [[ -v "$1" ]]; then if ! declare -p "$1" &> /dev/null; then
return 0 return 1
fi fi
return 1 return 0
} }
@ -1430,39 +1399,31 @@ mo::standaloneCheck() {
# #
# Returns nothing. # Returns nothing.
mo::standaloneProcess() { mo::standaloneProcess() {
local moI moTemp local moContent moLast moT moR moN
moT=$'\t'
moR=$'\r'
moN=$'\n'
moLast=
mo::debug "Standalone tag - processing content before and after tag" mo::debug "Standalone tag - processing content before and after tag"
moI=$((${#MO_PARSED} - 1))
mo::debug "zero done ${#MO_PARSED}"
mo::escape moTemp "$MO_PARSED"
mo::debug "$moTemp"
while [[ "${MO_PARSED:$moI:1}" == " " || "${MO_PARSED:$moI:1}" == $'\t' ]]; do while [[ "$moLast" != "$MO_PARSED" ]]; do
moI=$((moI - 1)) moLast=$MO_PARSED
MO_PARSED=${MO_PARSED% }
MO_PARSED=${MO_PARSED%"$moT"}
done done
if [[ $((moI + 1)) != "${#MO_PARSED}" ]]; then moLast=
MO_PARSED="${MO_PARSED:0:${moI}+1}"
fi
moI=0 while [[ "$moLast" != "$MO_UNPARSED" ]]; do
moLast=$MO_UNPARSED
while [[ "${MO_UNPARSED:${moI}:1}" == " " || "${MO_UNPARSED:${moI}:1}" == $'\t' ]]; do MO_UNPARSED=${MO_UNPARSED# }
moI=$((moI + 1)) MO_UNPARSED=${MO_UNPARSED#"$moT"}
done done
if [[ "${MO_UNPARSED:${moI}:1}" == $'\r' ]]; then MO_UNPARSED=${MO_UNPARSED#"$moR"}
moI=$((moI + 1)) MO_UNPARSED=${MO_UNPARSED#"$moN"}
fi
if [[ "${MO_UNPARSED:${moI}:1}" == $'\n' ]]; then
moI=$((moI + 1))
fi
if [[ "$moI" != 0 ]]; then
MO_UNPARSED=${MO_UNPARSED:${moI}}
fi
} }
@ -1988,7 +1949,7 @@ mo::tokenizeTagContentsSingleQuote() {
# Save the original command's path for usage later # Save the original command's path for usage later
MO_ORIGINAL_COMMAND="$(cd "${BASH_SOURCE[0]%/*}" || exit 1; pwd)/${BASH_SOURCE[0]##*/}" MO_ORIGINAL_COMMAND="$(cd "${BASH_SOURCE[0]%/*}" || exit 1; pwd)/${BASH_SOURCE[0]##*/}"
MO_VERSION="3.0.7" MO_VERSION="3.0.2"
# If sourced, load all functions. # If sourced, load all functions.
# If executed, perform the actions as expected. # If executed, perform the actions as expected.

View File

@ -43,8 +43,7 @@ Options:
This message. This message.
-s=FILE, --source=FILE -s=FILE, --source=FILE
Load FILE into the environment before processing templates. Load FILE into the environment before processing templates.
Can be used multiple times. The file must be a valid shell script Can be used multiple times.
and should only contain variable assignments.
-o=DELIM, --open=DELIM -o=DELIM, --open=DELIM
Set the opening delimiter. Default is "{{". Set the opening delimiter. Default is "{{".
-c=DELIM, --close=DELIM -c=DELIM, --close=DELIM
@ -94,7 +93,7 @@ This is open source! Please feel free to contribute.
https://github.com/tests-always-included/mo https://github.com/tests-always-included/mo
MO_VERSION=3.0.7 MO_VERSION=3.0.2
EOF EOF
} }

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
cd "${0%/*}" || exit 1
. ../run-tests
export uv
export template='{{^uv}}OK{{/uv}}{{#uv}}FAIL{{/uv}}'
export expected='OK'
runTest