diff --git a/diagnostic b/diagnostic index fac5cd2..f725ead 100755 --- a/diagnostic +++ b/diagnostic @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Test individual functions in mo and make sure they are performing their # tasks correctly. This can be used to help determine what needs to get @@ -8,13 +8,14 @@ # Functions are tested from the most primitive to the most advanced. # Errors, once found, halt the program. This way we can more easily # diagnose what's not working and fix those low-level functions first. + PARENT_PID=$$ cd "$(dirname "$0")" rm -f diagnostic.test rm -f diagnostic.partial # Load mo's functions -eval "$(sed '/^mustache-get-content /,$d' < mo)" +. ./mo fail() { echo "$1" @@ -24,7 +25,7 @@ fail() { # No dependencies -echo -n "mustache-indirect ... " +echo -n "moIndirect ... " ( a() { local V @@ -41,14 +42,14 @@ echo -n "mustache-indirect ... " } c() { - local "$1" && mustache-indirect "$1" c + local "$1" && moIndirect "$1" c } [[ "$(a)" != "ca" ]] && fail "Did not assign or scope bled '$RESULT'" ) echo "ok" -echo -n "mustache-indirect-array ... " +echo -n "moIndirectArray ... " ( a() { local V @@ -65,98 +66,98 @@ echo -n "mustache-indirect-array ... " } c() { - local "$1" && mustache-indirect-array "$1" c c c + local "$1" && moIndirectArray "$1" c c c } [[ "$(a)" != "31" ]] && fail "Did not assign or scope bled '$RESULT'" ) echo "ok" -echo -n "mustache-is-array ... " +echo -n "moIsArray ... " ( TEST=1 - mustache-is-array TEST && fail "Wrongly said number was an array" + moIsArray TEST && fail "Wrongly said number was an array" ) ( TEST=() - mustache-is-array TEST || fail "Wrongly said array was not an array" + moIsArray TEST || fail "Wrongly said array was not an array" ) ( TEST="" - mustache-is-array TEST && fail "Wrongly said string was an array" + moIsArray TEST && fail "Wrongly said string was an array" ) ( unset TEST - mustache-is-array TEST && fail "Wrongly said undefined was an array" + moIsArray TEST && fail "Wrongly said undefined was an array" ) echo "ok" -echo -n "mustache-is-function ... " +echo -n "moIsFunction ... " ( aa() { echo "hi"; } - mustache-is-function aa || fail "Did not find a function" + moIsFunction aa || fail "Did not find a function" - mustache-is-function dd && fail "Wrongly found a function" + moIsFunction dd && fail "Wrongly found a function" ) echo "ok" -echo -n "mustache-find-string ... " +echo -n "moFindString ... " ( - mustache-find-string POS "abcdefg" "ab" + moFindString POS "abcdefg" "ab" [[ "$POS" == "0" ]] || fail "Did not find at beginning of string" - mustache-find-string POS "abcdefg" "fg" + moFindString POS "abcdefg" "fg" [[ "$POS" == "5" ]] || fail "Did not find at end of string" - mustache-find-string POS "abcdefg" "de" + moFindString POS "abcdefg" "de" [[ "$POS" == "3" ]] || fail "Did not find at middle of string" - mustache-find-string POS "abcdefg" "CD" + moFindString POS "abcdefg" "CD" [[ "$POS" == "-1" ]] || fail "Did not correctly return a miss" ) echo "ok" -echo -n "mustache-full-tag-name ... " +echo -n "moFullTagName ... " ( - mustache-full-tag-name TAG "abc" "def" + moFullTagName TAG "abc" "def" [[ "$TAG" == "abc.def" ]] || fail "Did not work with a context" - mustache-full-tag-name TAG "" "one" + moFullTagName TAG "" "one" [[ "$TAG" == "one" ]] || fail "Did not work without a context" ) echo "ok" -echo -n "mustache-load-file ... " +echo -n "moLoadFile ... " ( # TODO - find a way to test reading from stdin that is not painful. touch diagnostic.test - mustache-load-file RESULT diagnostic.test + moLoadFile RESULT diagnostic.test [[ "${#RESULT}" == "0" ]] || fail "Did not read from empty file '$RESULT'" echo "abc" >> diagnostic.test - mustache-load-file RESULT diagnostic.test + moLoadFile RESULT diagnostic.test [[ "${#RESULT}" == "4" ]] || fail "Did not read from file '$RESULT'" echo "" >> diagnostic.test - mustache-load-file RESULT diagnostic.test + moLoadFile RESULT diagnostic.test [[ "${#RESULT}" == "5" ]] || fail "Trimmed newline from file '$RESULT'" rm diagnostic.test ) echo "ok" -echo -n "mustache-standalone-denied ... " +echo -n "moStandaloneDenied ... " ( - mustache-standalone-denied RESULT before tag after > diagnostic.test + moStandaloneDenied RESULT before tag after > diagnostic.test [[ "$(cat diagnostic.test)" == "before" ]] || fail "Did not output content before tag '$(cat diagnostic.test)'" [[ "$RESULT" == "after" ]] || fail "Did not set the remaining content '$RESULT'" rm diagnostic.test ) echo "ok" -echo -n "mustache-test ... " +echo -n "moTest ... " ( aa() { echo "hi"; } bb="bb" @@ -166,47 +167,48 @@ echo -n "mustache-test ... " unset yy zz="" - mustache-test aa || fail "Did not detect a function" - mustache-test bb || fail "Did not detect a non-empty string" - mustache-test cc || fail "Did not detect a number" - mustache-test dd || fail "Did not detect a populated array" - mustache-test xx && fail "Erroneously flagged an empty array" - mustache-test yy && fail "Erroneously flagged an undefined value" - mustache-test zz && fail "Erroneously flagged an empty string" + moTest aa || fail "Did not detect a function" + moTest bb || fail "Did not detect a non-empty string" + moTest cc || fail "Did not detect a number" + moTest dd || fail "Did not detect a populated array" + moTest xx && fail "Erroneously flagged an empty array" + moTest yy && fail "Erroneously flagged an undefined value" + moTest zz && fail "Erroneously flagged an empty string" ) echo "ok" -echo -n "mustache-trim-chars ... " +echo -n "moTrimChars ... " ( - mustache-trim-chars RESULT "abcdabc" true true a b c + moTrimChars RESULT "abcdabc" true true a b c [[ "$RESULT" == "d" ]] || fail "Did not trim multiple characters '$RESULT'" - mustache-trim-chars RESULT "abc" true false a c + moTrimChars RESULT "abc" true false a c [[ "$RESULT" == "bc" ]] || fail "Did not trim only from the front '$RESULT'" - mustache-trim-chars RESULT "abc" false true a c + moTrimChars RESULT "abc" false true a c [[ "$RESULT" == "ab" ]] || fail "Did not trim only from the end '$RESULT'" ) echo "ok" -echo -n "mustache-get-content ... " +echo -n "moGetContent ... " ( # TODO - find a way to test reading from stdin that is not painful. # Until then, mock it - mustache-load-file() { local "$1" && mustache-indirect "$1" "STDIN"; } - mustache-get-content RESULT a + moLoadFile() { local "$1" && moIndirect "$1" "STDIN"; } + + moGetContent RESULT a [[ "$RESULT" == "{{>a}}" ]] || fail "Did not construct 1 partial correctly '$RESULT'" - mustache-get-content RESULT a b c + moGetContent RESULT a b c [[ "$RESULT" == "{{>a}}{{>b}}{{>c}}" ]] || fail "Did not construct 3 partials correctly '$RESULT'" - mustache-get-content RESULT - [[ "$RESULT" == "STDIN" ]] || fail "Did not call mustache-load-file correctly" + moGetContent RESULT + [[ "$RESULT" == "STDIN" ]] || fail "Did not call moLoadFile correctly" ) echo "ok" -echo -n "mustache-indent-lines ... " +echo -n "moIndentLines ... " ( CR=$'\r' LF=$'\n' @@ -214,52 +216,52 @@ echo -n "mustache-indent-lines ... " # CAUTION # This must have a dot at the end of the input string - # That is part of how mustache-partial calls this function + # That is part of how moPartial calls this function for NEWLINE in "CR" "LF" "CRLF"; do NL="${!NEWLINE}" - mustache-indent-lines RESULT "" "has${NL}${NEWLINE}${NL}." + moIndentLines RESULT "" "has${NL}${NEWLINE}${NL}." printf -v QUOTED '%q' "$RESULT" [[ "$RESULT" == "has${NL}${NEWLINE}${NL}" ]] || fail "Should not have changed string $QUOTED" - mustache-indent-lines RESULT "" "without${NL}trailing${NL}${NEWLINE}." + moIndentLines RESULT "" "without${NL}trailing${NL}${NEWLINE}." printf -v QUOTED '%q' "$RESULT" [[ "$RESULT" == "without${NL}trailing${NL}${NEWLINE}" ]] || fail "Should not have changed string $QUOTED" - mustache-indent-lines RESULT "_-_" "has${NL}${NL}${NEWLINE}${NL}." + moIndentLines RESULT "_-_" "has${NL}${NL}${NEWLINE}${NL}." printf -v QUOTED '%q' "$RESULT" [[ "$RESULT" == "_-_has${NL}${NL}_-_${NEWLINE}${NL}" ]] || fail "Should have indented $QUOTED" - mustache-indent-lines RESULT "_-_" "without${NL}${NL}trailing${NL}${NEWLINE}." + moIndentLines RESULT "_-_" "without${NL}${NL}trailing${NL}${NEWLINE}." printf -v QUOTED '%q' "$RESULT" [[ "$RESULT" == "_-_without${NL}${NL}_-_trailing${NL}_-_${NEWLINE}" ]] || fail "Should have indented $QUOTED" done ) echo "ok" -echo -n "mustache-is-standalone ... " +echo -n "moIsStandalone ... " ( CR=$'\r' LF=$'\n' TAB=$'\t' - mustache-is-standalone RESULT "" "" false && fail "Needs newline before or beginning of content flag" - mustache-is-standalone RESULT "" "" true || fail "Has beginning of content flag and no other content" + moIsStandalone RESULT "" "" false && fail "Needs newline before or beginning of content flag" + moIsStandalone RESULT "" "" true || fail "Has beginning of content flag and no other content" [[ "$RESULT" == "0 0" ]] || fail "Wrong returned value for no content '$RESULT'" - mustache-is-standalone RESULT "moo" "cow" false && fail "Needs newlines when there is content" - mustache-is-standalone RESULT "moo$CR$LF$TAB $TAB " " $TAB $TAB$CR${LF}pasture" false || fail "Has newlines and content but did not flag" + moIsStandalone RESULT "moo" "cow" false && fail "Needs newlines when there is content" + moIsStandalone RESULT "moo$CR$LF$TAB $TAB " " $TAB $TAB$CR${LF}pasture" false || fail "Has newlines and content but did not flag" [[ "$RESULT" == "5 6" ]] || fail "Wrong returned value when there was whitespace '$RESULT'" ) echo "ok" -echo -n "mustache-split ... " +echo -n "moSplit ... " ( - mustache-split RESULT "abc-def-ghi" "-" + moSplit RESULT "abc-def-ghi" "-" [[ "${#RESULT[@]}" == "2" ]] || fail "Returned wrong number of elements with one delimiter ${#RESULT[@]}" [[ "${RESULT[0]}" == "abc" ]] || fail "Returned wrong left hand string with one delimiter '${RESULT[0]}'" [[ "${RESULT[1]}" == "def-ghi" ]] || fail "Returned wrong right hand string with one delimiter '${RESULT[1]}'" - mustache-split RESULT "abc-def-ghi" "-" "g" + moSplit RESULT "abc-def-ghi" "-" "g" [[ "${#RESULT[@]}" == "3" ]] || fail "Returned wrong number of elements with two delimiters ${#RESULT[@]}" [[ "${RESULT[0]}" == "abc" ]] || fail "Returned wrong left hand string with two delimiters '${RESULT[0]}'" [[ "${RESULT[1]}" == "def-" ]] || fail "Returned wrong middle string with two delimiters '${RESULT[1]}'" @@ -267,34 +269,35 @@ echo -n "mustache-split ... " ) echo "ok" -echo -n "mustache-trim-whitespace ... " +echo -n "moTrimWhitespace ... " ( CR=$'\r' LF=$'\n' TAB=$'\t' - mustache-trim-whitespace RESULT "ab cd" + moTrimWhitespace RESULT "ab cd" printf -v QUOTED '%q' "$RESULT" [[ "${RESULT}" == "ab cd" ]] || fail "Trimmed a string that did not need trimming $QUOTED" - mustache-trim-whitespace RESULT "$CR$LF$TAB ab $CR$LF$TAB cd $CR$LF$TAB $CR$LF$TAB" + moTrimWhitespace RESULT "$CR$LF$TAB ab $CR$LF$TAB cd $CR$LF$TAB $CR$LF$TAB" printf -v QUOTED '%q' "$RESULT" [[ "${RESULT}" == "ab $CR$LF$TAB cd" ]] || fail "Did not fully trim a string $QUOTED" ) echo "ok" -echo -n "mustache-standalone-allowed ... " +echo -n "moStandaloneAllowed ... " ( - # Mock mustache-is-standalone to make things simpler - mustache-is-standalone() { return 1; } + # Mock moIsStandalone to make things simpler + + moIsStandalone() { return 1; } - mustache-standalone-allowed RESULT before tag after > diagnostic.test + moStandaloneAllowed RESULT before tag after > diagnostic.test [[ "$(cat diagnostic.test)" == "before" ]] || fail "Did not output content before tag when not standalone '$(cat diagnostic.test)'" [[ "$RESULT" == "after" ]] || fail "Did not set the remaining content when not standalone '$RESULT'" - mustache-is-standalone() { local "$1" && mustache-indirect "$1" "3 5"; return 0; } + moIsStandalone() { local "$1" && moIndirect "$1" "3 5"; return 0; } - mustache-standalone-allowed RESULT before tag afterwards > diagnostic.test + moStandaloneAllowed RESULT before tag afterwards > diagnostic.test [[ "$(cat diagnostic.test)" == "bef" ]] || fail "Did not output content before tag when standalone '$(cat diagnostic.test)'" [[ "$RESULT" == "wards" ]] || fail "Did not set the remaining content when standalone '$RESULT'" @@ -302,29 +305,29 @@ echo -n "mustache-standalone-allowed ... " ) echo "ok" -echo -n "mustache-find-end-tag ... " +echo -n "moFindEndTag ... " ( LF=$'\n' - mustache-find-end-tag RESULT "moo{{ / cow }}pasture" "cow" + moFindEndTag RESULT "moo{{ / cow }}pasture" "cow" [[ "${#RESULT[@]}" == "3" ]] || fail "(simple) Wrong number of elements in the array ${#RESULT[@]}" [[ "${RESULT[0]}" == "moo" ]] || fail "(simple) Wrong left-hand '${RESULT[0]}'" [[ "${RESULT[1]}" == "{{ / cow }}" ]] || fail "(simple) Wrong middle '${RESULT[1]}'" [[ "${RESULT[2]}" == "pasture" ]] || fail "(simple) Wrong right-hand '${RESULT[2]}'" - mustache-find-end-tag RESULT "moo$LF {{/cow}} $LF pasture" "cow" + moFindEndTag RESULT "moo$LF {{/cow}} $LF pasture" "cow" [[ "${#RESULT[@]}" == "3" ]] || fail "(standalone) Wrong number of elements in the array ${#RESULT[@]}" [[ "${RESULT[0]}" == "moo$LF" ]] || fail "(standalone) Wrong left-hand '${RESULT[0]}'" [[ "${RESULT[1]}" == " {{/cow}} $LF" ]] || fail "(standalone) Wrong middle '${RESULT[1]}'" [[ "${RESULT[2]}" == " pasture" ]] || fail "(standalone) Wrong right-hand '${RESULT[2]}'" - mustache-find-end-tag RESULT "aa{{#bb}}cc{{/bb}}dd{{^bb}}ee{{/bb}}ff{{/bb}}gg" "bb" + moFindEndTag RESULT "aa{{#bb}}cc{{/bb}}dd{{^bb}}ee{{/bb}}ff{{/bb}}gg" "bb" [[ "${#RESULT[@]}" == "3" ]] || fail "(recursive) Wrong number of elements in the array ${#RESULT[@]}" [[ "${RESULT[0]}" == "aa{{#bb}}cc{{/bb}}dd{{^bb}}ee{{/bb}}ff" ]] || fail "(recursive) Wrong left-hand '${RESULT[0]}'" [[ "${RESULT[1]}" == "{{/bb}}" ]] || fail "(recursive) Wrong middle '${RESULT[1]}'" [[ "${RESULT[2]}" == "gg" ]] || fail "(recursive) Wrong right-hand '${RESULT[2]}'" - mustache-find-end-tag RESULT "aa{{#bb}}cc{{/dd}}ee" "dd" + moFindEndTag RESULT "aa{{#bb}}cc{{/dd}}ee" "dd" [[ "${#RESULT[@]}" == "3" ]] || fail "(unbalanced) Wrong number of elements in the array ${#RESULT[@]}" [[ "${RESULT[0]}" == "aa{{#bb}}cc{{/dd}}ee" ]] || fail "(unbalanced) Wrong left-hand '${RESULT[0]}'" [[ "${RESULT[1]}" == "" ]] || fail "(unbalanced) Wrong middle '${RESULT[1]}'" @@ -332,11 +335,11 @@ echo -n "mustache-find-end-tag ... " ) echo "ok" -echo -n "mustache-loop ... " +echo -n "moLoop ... " ( - mustache-parse() { echo "parse[$1] context[$2] flag[$3]"; } + moParse() { echo "parse[$1] context[$2] flag[$3]"; } - mustache-loop "content" "prefix" a b c > diagnostic.test + moLoop "content" "prefix" a b c > diagnostic.test ( echo "parse[content] context[prefix.a] flag[false]" echo "parse[content] context[prefix.b] flag[false]" @@ -347,18 +350,18 @@ echo -n "mustache-loop ... " ) echo "ok" -echo -n "mustache-partial ... " +echo -n "moPartial ... " ( NL=$'\n' - mustache-parse() { echo "parse[$1] context[$2] flag[$3]"; } + moParse() { echo "parse[$1] context[$2] flag[$3]"; } echo "partial" > diagnostic.partial - mustache-partial RESULT "line$NL" ">diagnostic.partial" " ${NL}line2" false "moo" > diagnostic.test + moPartial RESULT "line$NL" ">diagnostic.partial" " ${NL}line2" false "moo" > diagnostic.test [[ "$RESULT" == "line2" ]] || fail "Did not consume newline for standalone '$RESULT'" printf -v QUOTED '%q' "$(cat diagnostic.test)" [[ "$(cat diagnostic.test)" == "line${NL}parse[partial${NL}] context[moo] flag[true]" ]] || fail "Did not parse right standalone content $QUOTED" - mustache-partial RESULT "line" ">diagnostic.partial" "line2" false "moo" > diagnostic.test + moPartial RESULT "line" ">diagnostic.partial" "line2" false "moo" > diagnostic.test [[ "$RESULT" == "line2" ]] || fail "Did not preserve content for non-standalone '$RESULT'" printf -v QUOTED '%q' "$(cat diagnostic.test)" [[ "$(cat diagnostic.test)" == "lineparse[partial${NL}] context[moo] flag[true]" ]] || fail "Did not parse right non-standalone content $QUOTED" @@ -367,19 +370,19 @@ echo -n "mustache-partial ... " ) echo "ok" -echo -n "mustache-show ... " +echo -n "moShow ... " ( aa() { echo "this is aa"; } bb="BB" cc=( zero one two ) - [[ "$(mustache-show aa)" == "this is aa" ]] || fail "Did not load function" - [[ "$(mustache-show bb)" == "BB" ]] || fail "Did not show variable" - [[ "$(mustache-show cc.1)" == "one" ]] || fail "Did not show value from indexed array" + [[ "$(moShow aa)" == "this is aa" ]] || fail "Did not load function" + [[ "$(moShow bb)" == "BB" ]] || fail "Did not show variable" + [[ "$(moShow cc.1)" == "one" ]] || fail "Did not show value from indexed array" ) echo "ok" -echo -n "mustache-parse ... skipped (tested by specs)" +echo -n "moParse ... skipped (tested by specs)" echo "" echo "All diagnostic tests pass" diff --git a/mo b/mo index 3e8b7bf..8868a59 100755 --- a/mo +++ b/mo @@ -1,9 +1,13 @@ -#!/bin/bash +#!/usr/bin/env bash # -# Mo is a mustache template rendering software written in bash. It inserts -# environment variables into templates. -# -# Learn more about mustache templates at https://mustache.github.io/ +#/ Mo is a mustache template rendering software written in bash. It inserts +#/ environment variables into templates. +#/ +#/ Simply put, mo will change {{VARIABLE}} into the value of that +#/ environment variable. You can use {{#VARIABLE}}content{{/VARIABLE}} to +#/ conditionally display content or iterate over the values of an array. +#/ +#/ Learn more about mustache templates at https://mustache.github.io/ # # Mo is under a MIT style licence with an additional non-advertising clause. # See LICENSE.md for the full text. @@ -26,15 +30,15 @@ # $2: Content # $3: Name of end tag # $4: If -z, do standalone tag processing before finishing -mustache-find-end-tag() { +moFindEndTag() { local CONTENT SCANNED # Find open tags SCANNED="" - mustache-split CONTENT "$2" '{{' '}}' + moSplit CONTENT "$2" '{{' '}}' while [[ "${#CONTENT[@]}" -gt 1 ]]; do - mustache-trim-whitespace TAG "${CONTENT[1]}" + moTrimWhitespace TAG "${CONTENT[1]}" # Restore CONTENT[1] before we start using it CONTENT[1]='{{'"${CONTENT[1]}"'}}' @@ -43,20 +47,20 @@ mustache-find-end-tag() { '#'* | '^'*) # Start another block SCANNED="${SCANNED}${CONTENT[0]}${CONTENT[1]}" - mustache-trim-whitespace TAG "${TAG:1}" - mustache-find-end-tag CONTENT "${CONTENT[2]}" "$TAG" "loop" + moTrimWhitespace TAG "${TAG:1}" + moFindEndTag CONTENT "${CONTENT[2]}" "$TAG" "loop" SCANNED="${SCANNED}${CONTENT[0]}${CONTENT[1]}" CONTENT=${CONTENT[2]} ;; '/'*) # End a block - could be ours - mustache-trim-whitespace TAG "${TAG:1}" + moTrimWhitespace TAG "${TAG:1}" SCANNED="$SCANNED${CONTENT[0]}" if [[ "$TAG" == "$3" ]]; then # Found our end tag - if [[ -z "$4" ]] && mustache-is-standalone STANDALONE_BYTES "$SCANNED" "${CONTENT[2]}" true; then + if [[ -z "$4" ]] && moIsStandalone STANDALONE_BYTES "$SCANNED" "${CONTENT[2]}" true; then # This is also a standalone tag - clean up whitespace # and move those whitespace bytes to the "tag" element STANDALONE_BYTES=( $STANDALONE_BYTES ) @@ -65,7 +69,7 @@ mustache-find-end-tag() { CONTENT[2]="${CONTENT[2]:${STANDALONE_BYTES[1]}}" fi - local "$1" && mustache-indirect-array "$1" "$SCANNED" "${CONTENT[1]}" "${CONTENT[2]}" + local "$1" && moIndirectArray "$1" "$SCANNED" "${CONTENT[1]}" "${CONTENT[2]}" return 0 fi @@ -80,12 +84,12 @@ mustache-find-end-tag() { ;; esac - mustache-split CONTENT "$CONTENT" '{{' '}}' + moSplit CONTENT "$CONTENT" '{{' '}}' done # Did not find our closing tag SCANNED="$SCANNED${CONTENT[0]}" - local "$1" && mustache-indirect-array "$1" "${SCANNED}" "" "" + local "$1" && moIndirectArray "$1" "${SCANNED}" "" "" } @@ -95,12 +99,12 @@ mustache-find-end-tag() { # $1: Destination variable # $2: Haystack # $3: Needle -mustache-find-string() { +moFindString() { local POS STRING STRING=${2%%$3*} [[ "$STRING" == "$2" ]] && POS=-1 || POS=${#STRING} - local "$1" && mustache-indirect "$1" $POS + local "$1" && moIndirect "$1" $POS } @@ -110,11 +114,11 @@ mustache-find-string() { # $1: Target variable to store results # $2: Context name # $3: Desired variable name -mustache-full-tag-name() { +moFullTagName() { if [[ -z "$2" ]] || [[ "$2" == *.* ]]; then - local "$1" && mustache-indirect "$1" "$3" + local "$1" && moIndirect "$1" "$3" else - local "$1" && mustache-indirect "$1" "${2}.${3}" + local "$1" && moIndirect "$1" "${2}.${3}" fi } @@ -125,7 +129,7 @@ mustache-full-tag-name() { # Parameters: # $1: Variable name to assign this content back as # $2-*: File names (optional) -mustache-get-content() { +moGetContent() { local CONTENT FILENAME TARGET TARGET=$1 @@ -138,10 +142,10 @@ mustache-get-content() { CONTENT="$CONTENT"'{{>'"$FILENAME"'}}' done else - mustache-load-file CONTENT /dev/stdin + moLoadFile CONTENT /dev/stdin fi - local "$TARGET" && mustache-indirect "$TARGET" "$CONTENT" + local "$TARGET" && moIndirect "$TARGET" "$CONTENT" } @@ -152,20 +156,20 @@ mustache-get-content() { # $1: Name of destination variable to get an array of lines # $2: The indent string # $3: The string to reindent -mustache-indent-lines() { +moIndentLines() { local CONTENT FRAGMENT LEN POS_N POS_R RESULT TRIMMED RESULT="" LEN=$((${#3} - 1)) - CONTENT="${3:0:$LEN}" # Remove newline and dot from workaround - in mustache-partial + CONTENT="${3:0:$LEN}" # Remove newline and dot from workaround - in moPartial if [ -z "$2" ]; then - local "$1" && mustache-indirect "$1" "$CONTENT" + local "$1" && moIndirect "$1" "$CONTENT" return 0 fi - mustache-find-string POS_N "$CONTENT" $'\n' - mustache-find-string POS_R "$CONTENT" $'\r' + moFindString POS_N "$CONTENT" $'\n' + moFindString POS_R "$CONTENT" $'\r' while [[ "$POS_N" -gt -1 ]] || [[ "$POS_R" -gt -1 ]]; do if [[ "$POS_N" -gt -1 ]]; then @@ -176,18 +180,18 @@ mustache-indent-lines() { CONTENT=${CONTENT:$POS_R + 1} fi - mustache-trim-chars TRIMMED "$FRAGMENT" false true " " $'\t' $'\n' $'\r' + moTrimChars TRIMMED "$FRAGMENT" false true " " $'\t' $'\n' $'\r' if [ ! -z "$TRIMMED" ]; then FRAGMENT="$2$FRAGMENT" fi RESULT="$RESULT$FRAGMENT" - mustache-find-string POS_N "$CONTENT" $'\n' - mustache-find-string POS_R "$CONTENT" $'\r' + moFindString POS_N "$CONTENT" $'\n' + moFindString POS_R "$CONTENT" $'\r' done - mustache-trim-chars TRIMMED "$CONTENT" false true " " $'\t' + moTrimChars TRIMMED "$CONTENT" false true " " $'\t' if [ ! -z "$TRIMMED" ]; then CONTENT="$2$CONTENT" @@ -195,7 +199,7 @@ mustache-indent-lines() { RESULT="$RESULT$CONTENT" - local "$1" && mustache-indirect "$1" "$RESULT" + local "$1" && moIndirect "$1" "$RESULT" } @@ -204,7 +208,7 @@ mustache-indent-lines() { # Parameters: # $1: Variable name # $2: Value -mustache-indirect() { +moIndirect() { unset -v "$1" printf -v "$1" '%s' "$2" } @@ -215,7 +219,7 @@ mustache-indirect() { # Parameters: # $1: Variable name # $2-*: Array elements -mustache-indirect-array() { +moIndirectArray() { unset -v "$1" eval $1=\(\"\${@:2}\"\) } @@ -228,7 +232,7 @@ mustache-indirect-array() { # # Return code: # 0 if the name is not empty, 1 otherwise -mustache-is-array() { +moIsArray() { local MUSTACHE_TEST MUSTACHE_TEST=$(declare -p "$1" 2>/dev/null) || return 1 @@ -246,7 +250,7 @@ mustache-is-array() { # # Return code: # 0 if the name is a function, 1 otherwise -mustache-is-function() { +moIsFunction() { local FUNCTIONS NAME FUNCTIONS=$(declare -F) @@ -270,7 +274,7 @@ mustache-is-function() { # string (27) and the number of bytes to trim in the "after" string (10). # Useful for string manipulation: # -# mustache-is-standalone RESULT "$before" "$after" false || return 0 +# moIsStandalone RESULT "$before" "$after" false || return 0 # RESULT_ARRAY=( $RESULT ) # echo "${before:0:${RESULT_ARRAY[0]}}...${after:${RESULT_ARRAY[1]}}" # @@ -279,11 +283,11 @@ mustache-is-function() { # $2: Content before the tag # $3: Content after the tag # $4: true/false: is this the beginning of the content? -mustache-is-standalone() { +moIsStandalone() { local AFTER_TRIMMED BEFORE_TRIMMED CHAR - mustache-trim-chars BEFORE_TRIMMED "$2" false true " " $'\t' - mustache-trim-chars AFTER_TRIMMED "$3" true false " " $'\t' + moTrimChars BEFORE_TRIMMED "$2" false true " " $'\t' + moTrimChars AFTER_TRIMMED "$3" true false " " $'\t' CHAR=$((${#BEFORE_TRIMMED} - 1)) CHAR=${BEFORE_TRIMMED:$CHAR} @@ -303,7 +307,7 @@ mustache-is-standalone() { CHAR="$CHAR"$'\n' fi - local "$1" && mustache-indirect "$1" "$((${#BEFORE_TRIMMED})) $((${#3} + ${#CHAR} - ${#AFTER_TRIMMED}))" + local "$1" && moIndirect "$1" "$((${#BEFORE_TRIMMED})) $((${#3} + ${#CHAR} - ${#AFTER_TRIMMED}))" } @@ -313,7 +317,7 @@ mustache-is-standalone() { # $1: Variable name to receive the joined content # $2: Joiner # $3-$*: Elements to join -mustache-join() { +moJoin() { local JOINER PART RESULT TARGET TARGET=$1 @@ -325,7 +329,7 @@ mustache-join() { RESULT="$RESULT$JOINER$PART" done - local "$TARGET" && mustache-indirect "$TARGET" "$RESULT" + local "$TARGET" && moIndirect "$TARGET" "$RESULT" } # Read a file @@ -333,7 +337,7 @@ mustache-join() { # Parameters: # $1: Variable name to receive the file's content # $2: Filename to load -mustache-load-file() { +moLoadFile() { local CONTENT LEN # The subshell removes any trailing newlines. We forcibly add @@ -343,7 +347,7 @@ mustache-load-file() { LEN=$((${#CONTENT} - 1)) CONTENT=${CONTENT:0:$LEN} # Remove last dot - local "$1" && mustache-indirect "$1" "$CONTENT" + local "$1" && moIndirect "$1" "$CONTENT" } @@ -353,7 +357,7 @@ mustache-load-file() { # $1: Content to parse and reparse and reparse # $2: Tag prefix (context name) # $3-*: Names to insert into the parsed content -mustache-loop() { +moLoop() { local CONTENT CONTEXT CONTEXT_BASE IGNORE CONTENT=$1 @@ -361,8 +365,8 @@ mustache-loop() { shift 2 while [[ "${#@}" -gt 0 ]]; do - mustache-full-tag-name CONTEXT "$CONTEXT_BASE" "$1" - mustache-parse "$CONTENT" "$CONTEXT" false + moFullTagName CONTEXT "$CONTEXT_BASE" "$1" + moParse "$CONTENT" "$CONTEXT" false shift done } @@ -374,7 +378,7 @@ mustache-loop() { # $1: Block of text to change # $2: Current name (the variable NAME for what {{.}} means) # $3: true when no content before this, false otherwise -mustache-parse() { +moParse() { # Keep naming variables MUSTACHE_* here to not overwrite needed variables # used in the string replacements local MUSTACHE_BLOCK MUSTACHE_CONTENT MUSTACHE_CURRENT MUSTACHE_IS_BEGINNING MUSTACHE_TAG @@ -383,33 +387,33 @@ mustache-parse() { MUSTACHE_IS_BEGINNING=$3 # Find open tags - mustache-split MUSTACHE_CONTENT "$1" '{{' '}}' + moSplit MUSTACHE_CONTENT "$1" '{{' '}}' while [[ "${#MUSTACHE_CONTENT[@]}" -gt 1 ]]; do - mustache-trim-whitespace MUSTACHE_TAG "${MUSTACHE_CONTENT[1]}" + moTrimWhitespace MUSTACHE_TAG "${MUSTACHE_CONTENT[1]}" case $MUSTACHE_TAG in '#'*) # Loop, if/then, or pass content through function # Sets context - mustache-standalone-allowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING - mustache-trim-whitespace MUSTACHE_TAG "${MUSTACHE_TAG:1}" - mustache-find-end-tag MUSTACHE_BLOCK "$MUSTACHE_CONTENT" "$MUSTACHE_TAG" - mustache-full-tag-name MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" + moStandaloneAllowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING + moTrimWhitespace MUSTACHE_TAG "${MUSTACHE_TAG:1}" + moFindEndTag MUSTACHE_BLOCK "$MUSTACHE_CONTENT" "$MUSTACHE_TAG" + moFullTagName MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" - if mustache-test "$MUSTACHE_TAG"; then + if moTest "$MUSTACHE_TAG"; then # Show / loop / pass through function - if mustache-is-function "$MUSTACHE_TAG"; then + if moIsFunction "$MUSTACHE_TAG"; then # TODO: Consider piping the output to - # mustache-get-content so the lambda does not + # moGetContent so the lambda does not # execute in a subshell? MUSTACHE_CONTENT=$($MUSTACHE_TAG "${MUSTACHE_BLOCK[0]}") - mustache-parse "$MUSTACHE_CONTENT" "$MUSTACHE_CURRENT" false + moParse "$MUSTACHE_CONTENT" "$MUSTACHE_CURRENT" false MUSTACHE_CONTENT="${MUSTACHE_BLOCK[2]}" - elif mustache-is-array "$MUSTACHE_TAG"; then - eval 'mustache-loop "${MUSTACHE_BLOCK[0]}" "$MUSTACHE_TAG" "${!'"$MUSTACHE_TAG"'[@]}"' + elif moIsArray "$MUSTACHE_TAG"; then + eval 'moLoop "${MUSTACHE_BLOCK[0]}" "$MUSTACHE_TAG" "${!'"$MUSTACHE_TAG"'[@]}"' else - mustache-parse "${MUSTACHE_BLOCK[0]}" "$MUSTACHE_CURRENT" false + moParse "${MUSTACHE_BLOCK[0]}" "$MUSTACHE_CURRENT" false fi fi @@ -418,24 +422,24 @@ mustache-parse() { '>'*) # Load partial - get name of file relative to cwd - mustache-partial MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING "$MUSTACHE_CURRENT" + moPartial MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING "$MUSTACHE_CURRENT" ;; '/'*) # Closing tag - If hit in this loop, we simply ignore - # Matching tags are found in mustache-find-end-tag - mustache-standalone-allowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING + # Matching tags are found in moFindEndTag + moStandaloneAllowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING ;; '^'*) # Display section if named thing does not exist - mustache-standalone-allowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING - mustache-trim-whitespace MUSTACHE_TAG "${MUSTACHE_TAG:1}" - mustache-find-end-tag MUSTACHE_BLOCK "$MUSTACHE_CONTENT" "$MUSTACHE_TAG" - mustache-full-tag-name MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" + moStandaloneAllowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING + moTrimWhitespace MUSTACHE_TAG "${MUSTACHE_TAG:1}" + moFindEndTag MUSTACHE_BLOCK "$MUSTACHE_CONTENT" "$MUSTACHE_TAG" + moFullTagName MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" - if ! mustache-test "$MUSTACHE_TAG"; then - mustache-parse "${MUSTACHE_BLOCK[0]}" "$MUSTACHE_CURRENT" false "$MUSTACHE_CURRENT" + if ! moTest "$MUSTACHE_TAG"; then + moParse "${MUSTACHE_BLOCK[0]}" "$MUSTACHE_CURRENT" false "$MUSTACHE_CURRENT" fi MUSTACHE_CONTENT="${MUSTACHE_BLOCK[2]}" @@ -444,53 +448,53 @@ mustache-parse() { '!'*) # Comment - ignore the tag content entirely # Trim spaces/tabs before the comment - mustache-standalone-allowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING + moStandaloneAllowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING ;; .) # Current content (environment variable or function) - mustache-standalone-denied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" - mustache-show "$MUSTACHE_CURRENT" "$MUSTACHE_CURRENT" + moStandaloneDenied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" + moShow "$MUSTACHE_CURRENT" "$MUSTACHE_CURRENT" ;; '=') # Change delimiters # Any two non-whitespace sequences separated by whitespace. # TODO - mustache-standalone-allowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING + moStandaloneAllowed MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" $MUSTACHE_IS_BEGINNING ;; '{'*) # Unescaped - split on }}} not }} - mustache-standalone-denied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" + moStandaloneDenied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" MUSTACHE_CONTENT="${MUSTACHE_TAG:1}"'}}'"$MUSTACHE_CONTENT" - mustache-split MUSTACHE_CONTENT "$MUSTACHE_CONTENT" '}}}' - mustache-trim-whitespace MUSTACHE_TAG "${MUSTACHE_CONTENT[0]}" - mustache-full-tag-name MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" + moSplit MUSTACHE_CONTENT "$MUSTACHE_CONTENT" '}}}' + moTrimWhitespace MUSTACHE_TAG "${MUSTACHE_CONTENT[0]}" + moFullTagName MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" MUSTACHE_CONTENT=${MUSTACHE_CONTENT[1]} # Now show the value - mustache-show "$MUSTACHE_TAG" "$MUSTACHE_CURRENT" + moShow "$MUSTACHE_TAG" "$MUSTACHE_CURRENT" ;; '&'*) # Unescaped - mustache-standalone-denied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" - mustache-trim-whitespace MUSTACHE_TAG "${MUSTACHE_TAG:1}" - mustache-full-tag-name MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" - mustache-show "$MUSTACHE_TAG" "$MUSTACHE_CURRENT" + moStandaloneDenied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" + moTrimWhitespace MUSTACHE_TAG "${MUSTACHE_TAG:1}" + moFullTagName MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" + moShow "$MUSTACHE_TAG" "$MUSTACHE_CURRENT" ;; *) # Normal environment variable or function call - mustache-standalone-denied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" - mustache-full-tag-name MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" - mustache-show "$MUSTACHE_TAG" "$MUSTACHE_CURRENT" + moStandaloneDenied MUSTACHE_CONTENT "${MUSTACHE_CONTENT[@]}" + moFullTagName MUSTACHE_TAG "$MUSTACHE_CURRENT" "$MUSTACHE_TAG" + moShow "$MUSTACHE_TAG" "$MUSTACHE_CURRENT" ;; esac MUSTACHE_IS_BEGINNING=false - mustache-split MUSTACHE_CONTENT "$MUSTACHE_CONTENT" '{{' '}}' + moSplit MUSTACHE_CONTENT "$MUSTACHE_CONTENT" '{{' '}}' done echo -n "${MUSTACHE_CONTENT[0]}" @@ -510,10 +514,10 @@ mustache-parse() { # $4: Content after the tag # $5: true/false: is this the beginning of the content? # $6: Current context name -mustache-partial() { +moPartial() { local MUSTACHE_CONTENT MUSTACHE_FILENAME MUSTACHE_INDENT MUSTACHE_LINE MUSTACHE_PARTIAL MUSTACHE_STANDALONE - if mustache-is-standalone MUSTACHE_STANDALONE "$2" "$4" $5; then + if moIsStandalone MUSTACHE_STANDALONE "$2" "$4" $5; then MUSTACHE_STANDALONE=( $MUSTACHE_STANDALONE ) echo -n "${2:0:${MUSTACHE_STANDALONE[0]}}" MUSTACHE_INDENT=${2:${MUSTACHE_STANDALONE[0]}} @@ -524,23 +528,23 @@ mustache-partial() { MUSTACHE_CONTENT=$4 fi - mustache-trim-whitespace MUSTACHE_FILENAME "${3:1}" + moTrimWhitespace MUSTACHE_FILENAME "${3:1}" # Execute in subshell to preserve current cwd and environment ( # TODO: Remove dirname and use a function instead cd "$(dirname "$MUSTACHE_FILENAME")" - mustache-indent-lines MUSTACHE_PARTIAL "$MUSTACHE_INDENT" "$( - mustache-load-file MUSTACHE_PARTIAL "${MUSTACHE_FILENAME##*/}" + moIndentLines MUSTACHE_PARTIAL "$MUSTACHE_INDENT" "$( + moLoadFile MUSTACHE_PARTIAL "${MUSTACHE_FILENAME##*/}" # Fix bash handling of subshells - # The extra dot is removed in mustache-indent-lines + # The extra dot is removed in moIndentLines echo -n "${MUSTACHE_PARTIAL}." )" - mustache-parse "$MUSTACHE_PARTIAL" "$6" true + moParse "$MUSTACHE_PARTIAL" "$6" true ) - local "$1" && mustache-indirect "$1" "$MUSTACHE_CONTENT" + local "$1" && moIndirect "$1" "$MUSTACHE_CONTENT" } @@ -551,20 +555,20 @@ mustache-partial() { # Parameters: # $1: Name of environment variable or function # $2: Current context -mustache-show() { +moShow() { local JOINED MUSTACHE_NAME_PARTS - if mustache-is-function "$1"; then + if moIsFunction "$1"; then CONTENT=$($1 "") - mustache-parse "$CONTENT" "$2" false + moParse "$CONTENT" "$2" false return 0 fi - mustache-split MUSTACHE_NAME_PARTS "$1" "." + moSplit MUSTACHE_NAME_PARTS "$1" "." if [[ -z "${MUSTACHE_NAME_PARTS[1]}" ]]; then - if mustache-is-array "$1"; then - eval mustache-join JOINED "," "\${$1[@]}" + if moIsArray "$1"; then + eval moJoin JOINED "," "\${$1[@]}" echo -n "$JOINED" else echo -n "${!1}" @@ -583,11 +587,11 @@ mustache-show() { # $2: String to split # $3: Starting delimiter # $4: Ending delimiter (optional) -mustache-split() { +moSplit() { local POS RESULT RESULT=( "$2" ) - mustache-find-string POS "${RESULT[0]}" "$3" + moFindString POS "${RESULT[0]}" "$3" if [[ "$POS" -ne -1 ]]; then # The first delimiter was found @@ -595,7 +599,7 @@ mustache-split() { RESULT[0]=${RESULT[0]:0:$POS} if [[ ! -z "$4" ]]; then - mustache-find-string POS "${RESULT[1]}" "$4" + moFindString POS "${RESULT[1]}" "$4" if [[ "$POS" -ne -1 ]]; then # The second delimiter was found @@ -605,7 +609,7 @@ mustache-split() { fi fi - local "$1" && mustache-indirect-array "$1" "${RESULT[@]}" + local "$1" && moIndirectArray "$1" "${RESULT[@]}" } @@ -619,16 +623,16 @@ mustache-split() { # $3: Tag content (not used) # $4: Content after the tag # $5: true/false: is this the beginning of the content? -mustache-standalone-allowed() { +moStandaloneAllowed() { local STANDALONE_BYTES - if mustache-is-standalone STANDALONE_BYTES "$2" "$4" $5; then + if moIsStandalone STANDALONE_BYTES "$2" "$4" $5; then STANDALONE_BYTES=( $STANDALONE_BYTES ) echo -n "${2:0:${STANDALONE_BYTES[0]}}" - local "$1" && mustache-indirect "$1" "${4:${STANDALONE_BYTES[1]}}" + local "$1" && moIndirect "$1" "${4:${STANDALONE_BYTES[1]}}" else echo -n "$2" - local "$1" && mustache-indirect "$1" "$4" + local "$1" && moIndirect "$1" "$4" fi } @@ -641,9 +645,9 @@ mustache-standalone-allowed() { # $2: Content before the tag that was not yet written # $3: Tag content (not used) # $4: Content after the tag -mustache-standalone-denied() { +moStandaloneDenied() { echo -n "$2" - local "$1" && mustache-indirect "$1" "$4" + local "$1" && moIndirect "$1" "$4" } @@ -659,11 +663,11 @@ mustache-standalone-denied() { # # Return code: # 0 if the name is not empty, 1 otherwise -mustache-test() { +moTest() { # Test for functions - mustache-is-function "$1" && return 0 + moIsFunction "$1" && return 0 - if mustache-is-array "$1"; then + if moIsArray "$1"; then # Arrays must have at least 1 element eval '[[ "${#'"$1"'[@]}" -gt 0 ]]' && return 0 else @@ -683,7 +687,7 @@ mustache-test() { # $3: true/false - trim front? # $4: true/false - trim end? # $5-*: Characters to trim -mustache-trim-chars() { +moTrimChars() { local BACK CURRENT FRONT LAST TARGET VAR TARGET=$1 @@ -705,7 +709,7 @@ mustache-trim-chars() { done done - local "$TARGET" && mustache-indirect "$TARGET" "$CURRENT" + local "$TARGET" && moIndirect "$TARGET" "$CURRENT" } @@ -714,21 +718,49 @@ mustache-trim-chars() { # Parameters: # $1: Name of variable to store trimmed string # $2: The string -mustache-trim-whitespace() { +moTrimWhitespace() { local RESULT - mustache-trim-chars RESULT "$2" true true $'\r' $'\n' $'\t' " " - local "$1" && mustache-indirect "$1" "$RESULT" + moTrimChars RESULT "$2" true true $'\r' $'\n' $'\t' " " + local "$1" && moIndirect "$1" "$RESULT" } +# Displays the usage for mo. Pulls this from the file that contained +# the `mo` function. Likely will only work when +# +# $1 - Filename that has the help message +# +# Returns nothing. +moUsage() { + grep '^#/' < "$0" | cut -c 4- +} + + +# Template parser +# +# $* - Filenames to parse. Can use -h or --help as the only option +# in order to show a help message. +# +# Returns nothing. mo() ( # Execute in a subshell so IFS is reset IFS=$' \n\t' - mustache-get-content MUSTACHE_CONTENT "$@" - mustache-parse "$MUSTACHE_CONTENT" "" true + + if [[ $# -gt 0 ]]; then + case "$1" in + -h|--h|--he|--hel|--help) + moUsage "$0" + exit 0 + ;; + esac + fi + + moGetContent MUSTACHE_CONTENT "$@" + moParse "$MUSTACHE_CONTENT" "" true ) + if [[ "$0" == "$BASH_SOURCE" ]] || ! [[ -n "$BASH_SOURCE" ]]; then mo "$@" fi