Renaming all functions

This makes function names POSIX compliant.  Not a big deal with bash,
but very important if you want to use tools like ctags or tomdoc.sh.
This commit is contained in:
Tyler Akins 2015-10-02 09:06:16 -05:00
parent b16d73b5a7
commit 851e619fbd
2 changed files with 244 additions and 209 deletions

View File

@ -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
mustache-standalone-allowed RESULT before tag after > diagnostic.test
moIsStandalone() { return 1; }
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"

278
mo
View File

@ -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