mirror of
https://github.com/tests-always-included/mo.git
synced 2024-12-18 16:27:52 +00:00
Alphabetiation of functions
Oh my goodness, it needed some sort of organiation in there.
This commit is contained in:
parent
b469554ac1
commit
68c3141678
646
mo
646
mo
@ -1,61 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Return 0 if the passed name is a function. Function names are captured
|
||||
# at the start of the program and are stored in the $MUSTACHE_FUNCTIONS array.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name to check if it's a function
|
||||
#
|
||||
# Return code:
|
||||
# 0 if the name is a function, 1 otherwise
|
||||
mustache-is-function() {
|
||||
local NAME
|
||||
|
||||
for NAME in ${MUSTACHE_FUNCTIONS[@]}; do
|
||||
if [[ "$NAME" == "$1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# Process a chunk of content some number of times.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Content to parse and reparse and reparse
|
||||
# $2: Tag prefix (context name)
|
||||
# $3-*: Names to insert into the parsed content
|
||||
mustache-loop() {
|
||||
local CONTENT CONTEXT CONTEXT_BASE IGNORE
|
||||
|
||||
CONTENT=$1
|
||||
CONTEXT_BASE=$2
|
||||
shift 2
|
||||
|
||||
while [[ "${#@}" -gt 0 ]]; do
|
||||
mustache-full-tag-name CONTEXT "$CONTEXT_BASE" "$1"
|
||||
mustache-parse IGNORE "$CONTENT" "$CONTEXT" false
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Return a dotted name based on current context and target name
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Target variable to store results
|
||||
# $2: Context name
|
||||
# $3: Desired variable name
|
||||
mustache-full-tag-name() {
|
||||
if [[ -z "$2" ]]; then
|
||||
local "$1" && mustache-indirect "$1" "$3"
|
||||
else
|
||||
local "$1" && mustache-indirect "$1" "${2}.${3}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Eat content until the right end tag is found. Returns an array with the
|
||||
# following members:
|
||||
@ -130,6 +74,259 @@ mustache-find-end-tag() {
|
||||
}
|
||||
|
||||
|
||||
# Find the first index of a substring
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Destination variable
|
||||
# $2: Haystack
|
||||
# $3: Needle
|
||||
mustache-find-string() {
|
||||
local POS STRING
|
||||
|
||||
STRING=${2%%$3*}
|
||||
[[ "$STRING" == "$2" ]] && POS=-1 || POS=${#STRING}
|
||||
local "$1" && mustache-indirect "$1" $POS
|
||||
}
|
||||
|
||||
|
||||
# Return a dotted name based on current context and target name
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Target variable to store results
|
||||
# $2: Context name
|
||||
# $3: Desired variable name
|
||||
mustache-full-tag-name() {
|
||||
if [[ -z "$2" ]]; then
|
||||
local "$1" && mustache-indirect "$1" "$3"
|
||||
else
|
||||
local "$1" && mustache-indirect "$1" "${2}.${3}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Return the content to parse. Can be a list of partials for files or
|
||||
# the content from stdin.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name to assign this content back as
|
||||
# $2-*: File names (optional)
|
||||
mustache-get-content() {
|
||||
local CONTENT FILENAME TARGET
|
||||
|
||||
TARGET=$1
|
||||
shift
|
||||
if [[ "${#@}" -gt 0 ]]; then
|
||||
CONTENT=""
|
||||
|
||||
for FILENAME in ${1+"$@"}; do
|
||||
# This is so relative paths work from inside template files
|
||||
CONTENT="$CONTENT"'{{>'"$FILENAME"'}}'
|
||||
done
|
||||
else
|
||||
mustache-load-file CONTENT /dev/stdin
|
||||
fi
|
||||
|
||||
local "$TARGET" && mustache-indirect "$TARGET" "$CONTENT"
|
||||
}
|
||||
|
||||
|
||||
# Indent a string, placing the indent at the beginning of every
|
||||
# line that has any content.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of destination variable to get an array of lines
|
||||
# $2: The indent string
|
||||
# $3: The string to reindent
|
||||
mustache-indent-lines() {
|
||||
local CONTENT FRAGMENT POS_N POS_R RESULT TRIMMED
|
||||
|
||||
RESULT=""
|
||||
CONTENT="${3:0: -1}" # Remove newline and dot from workaround - in mustache-partial
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
local "$1" && mustache-indirect "$1" "$CONTENT"
|
||||
return 0
|
||||
fi
|
||||
|
||||
mustache-find-string POS_N "$CONTENT" $'\n'
|
||||
mustache-find-string POS_R "$CONTENT" $'\r'
|
||||
|
||||
while [[ "$POS_N" -gt -1 ]] || [[ "$POS_R" -gt -1 ]]; do
|
||||
if [[ "$POS_N" -gt -1 ]]; then
|
||||
FRAGMENT="${CONTENT:0:$POS_N + 1}"
|
||||
CONTENT=${CONTENT:$POS_N + 1}
|
||||
else
|
||||
FRAGMENT="${CONTENT:0:$POS_R + 1}"
|
||||
CONTENT=${CONTENT:$POS_R + 1}
|
||||
fi
|
||||
|
||||
mustache-trim-chars 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'
|
||||
done
|
||||
|
||||
mustache-trim-chars TRIMMED "$CONTENT" false true " " "$'\t'"
|
||||
|
||||
if [ ! -z "$TRIMMED" ]; then
|
||||
CONTENT="$2$CONTENT"
|
||||
fi
|
||||
|
||||
RESULT="$RESULT$CONTENT"
|
||||
|
||||
local "$1" && mustache-indirect "$1" "$RESULT"
|
||||
}
|
||||
|
||||
|
||||
# Send a variable up to caller of a function
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name
|
||||
# $2: Value
|
||||
mustache-indirect() {
|
||||
unset -v "$1"
|
||||
printf -v "$1" '%s' "$2"
|
||||
}
|
||||
|
||||
|
||||
# Send an array up to caller of a function
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name
|
||||
# $2-*: Array elements
|
||||
mustache-indirect-array() {
|
||||
unset -v "$1"
|
||||
eval $1=\(\"\${@:2}\"\)
|
||||
}
|
||||
|
||||
|
||||
# Determine if a given environment variable exists and if it is an array.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of environment variable
|
||||
#
|
||||
# Return code:
|
||||
# 0 if the name is not empty, 1 otherwise
|
||||
mustache-is-array() {
|
||||
local MUSTACHE_TEST
|
||||
|
||||
MUSTACHE_TEST=$(declare -p "$1" 2>/dev/null) || return 1
|
||||
[[ "${MUSTACHE_TEST:0:10}" == "declare -a" ]] && return 0
|
||||
[[ "${MUSTACHE_TEST:0:10}" == "declare -A" ]] && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# Return 0 if the passed name is a function. Function names are captured
|
||||
# at the start of the program and are stored in the $MUSTACHE_FUNCTIONS array.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name to check if it's a function
|
||||
#
|
||||
# Return code:
|
||||
# 0 if the name is a function, 1 otherwise
|
||||
mustache-is-function() {
|
||||
local NAME
|
||||
|
||||
for NAME in ${MUSTACHE_FUNCTIONS[@]}; do
|
||||
if [[ "$NAME" == "$1" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# Determine if the tag is a standalone tag based on whitespace before and
|
||||
# after the tag.
|
||||
#
|
||||
# Passes back a string containing two numbers in the format "BEFORE AFTER"
|
||||
# like "27 10". It indicates the number of bytes remaining in the "before"
|
||||
# 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
|
||||
# RESULT_ARRAY=( $RESULT )
|
||||
# echo "${before:0:${RESULT_ARRAY[0]}}...${after:${RESULT_ARRAY[1]}}"
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable to pass data back
|
||||
# $2: Content before the tag
|
||||
# $3: Content after the tag
|
||||
# $4: true/false: is this the beginning of the content?
|
||||
mustache-is-standalone() {
|
||||
local AFTER_TRIMMED BEFORE_TRIMMED CHAR
|
||||
|
||||
mustache-trim-chars BEFORE_TRIMMED "$2" false true " " "$'\t'"
|
||||
mustache-trim-chars AFTER_TRIMMED "$3" true false " " "$'\t'"
|
||||
CHAR=${BEFORE_TRIMMED: -1}
|
||||
|
||||
if [[ "$CHAR" != $'\n' ]] && [[ "$CHAR" != $'\r' ]]; then
|
||||
if [[ ! -z "$CHAR" ]] || ! $4; then
|
||||
return 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
CHAR=${AFTER_TRIMMED:0:1}
|
||||
|
||||
if [[ "$CHAR" != $'\n' ]] && [[ "$CHAR" != $'\r' ]] && [[ ! -z "$CHAR" ]]; then
|
||||
return 2;
|
||||
fi
|
||||
|
||||
if [[ "$CHAR" == $'\r' ]] && [[ "${AFTER_TRIMMED:1:1}" == $'\n' ]]; then
|
||||
CHAR="$CHAR"$'\n'
|
||||
fi
|
||||
|
||||
local "$1" && mustache-indirect "$1" "$((${#BEFORE_TRIMMED})) $((${#3} + ${#CHAR} - ${#AFTER_TRIMMED}))"
|
||||
}
|
||||
|
||||
|
||||
# Read a file
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name to receive the file's content
|
||||
# $2: Filename to load
|
||||
mustache-load-file() {
|
||||
local CONTENT
|
||||
|
||||
# The subshell removes any trailing newlines. We forcibly add
|
||||
# a dot to the content to preserve all newlines.
|
||||
# TODO: remove cat and replace with read loop?
|
||||
CONTENT=$(cat $2; echo '.')
|
||||
CONTENT=${CONTENT:0: -1} # Remove last dot
|
||||
|
||||
local "$1" && mustache-indirect "$1" "$CONTENT"
|
||||
}
|
||||
|
||||
|
||||
# Process a chunk of content some number of times.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Content to parse and reparse and reparse
|
||||
# $2: Tag prefix (context name)
|
||||
# $3-*: Names to insert into the parsed content
|
||||
mustache-loop() {
|
||||
local CONTENT CONTEXT CONTEXT_BASE IGNORE
|
||||
|
||||
CONTENT=$1
|
||||
CONTEXT_BASE=$2
|
||||
shift 2
|
||||
|
||||
while [[ "${#@}" -gt 0 ]]; do
|
||||
mustache-full-tag-name CONTEXT "$CONTEXT_BASE" "$1"
|
||||
mustache-parse IGNORE "$CONTENT" "$CONTEXT" false
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
# Parse a block of text
|
||||
#
|
||||
# Parameters:
|
||||
@ -309,141 +506,6 @@ mustache-partial() {
|
||||
}
|
||||
|
||||
|
||||
# Indent a string, placing the indent at the beginning of every
|
||||
# line that has any content.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of destination variable to get an array of lines
|
||||
# $2: The indent string
|
||||
# $3: The string to reindent
|
||||
mustache-indent-lines() {
|
||||
local CONTENT FRAGMENT POS_N POS_R RESULT TRIMMED
|
||||
|
||||
RESULT=""
|
||||
CONTENT="${3:0: -1}" # Remove newline and dot from workaround - in mustache-partial
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
local "$1" && mustache-indirect "$1" "$CONTENT"
|
||||
return 0
|
||||
fi
|
||||
|
||||
mustache-find-string POS_N "$CONTENT" $'\n'
|
||||
mustache-find-string POS_R "$CONTENT" $'\r'
|
||||
|
||||
while [[ "$POS_N" -gt -1 ]] || [[ "$POS_R" -gt -1 ]]; do
|
||||
if [[ "$POS_N" -gt -1 ]]; then
|
||||
FRAGMENT="${CONTENT:0:$POS_N + 1}"
|
||||
CONTENT=${CONTENT:$POS_N + 1}
|
||||
else
|
||||
FRAGMENT="${CONTENT:0:$POS_R + 1}"
|
||||
CONTENT=${CONTENT:$POS_R + 1}
|
||||
fi
|
||||
|
||||
mustache-trim-chars 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'
|
||||
done
|
||||
|
||||
mustache-trim-chars TRIMMED "$CONTENT" false true " " "$'\t'"
|
||||
|
||||
if [ ! -z "$TRIMMED" ]; then
|
||||
CONTENT="$2$CONTENT"
|
||||
fi
|
||||
|
||||
RESULT="$RESULT$CONTENT"
|
||||
|
||||
local "$1" && mustache-indirect "$1" "$RESULT"
|
||||
}
|
||||
|
||||
|
||||
# Handle the content for a standalone tag. This means removing whitespace
|
||||
# (not newlines) before a tag and whitespace and a newline after a tag.
|
||||
# That is, assuming, that the line is otherwise empty.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of destination "content" variable.
|
||||
# $2: Content before the tag that was not yet written
|
||||
# $3: Tag content (not used)
|
||||
# $4: Content after the tag
|
||||
# $5: true/false: is this the beginning of the content?
|
||||
mustache-standalone-allowed() {
|
||||
local STANDALONE_BYTES
|
||||
|
||||
if mustache-is-standalone 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]}}"
|
||||
else
|
||||
echo -n "$2"
|
||||
local "$1" && mustache-indirect "$1" "$4"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Determine if the tag is a standalone tag based on whitespace before and
|
||||
# after the tag.
|
||||
#
|
||||
# Passes back a string containing two numbers in the format "BEFORE AFTER"
|
||||
# like "27 10". It indicates the number of bytes remaining in the "before"
|
||||
# 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
|
||||
# RESULT_ARRAY=( $RESULT )
|
||||
# echo "${before:0:${RESULT_ARRAY[0]}}...${after:${RESULT_ARRAY[1]}}"
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable to pass data back
|
||||
# $2: Content before the tag
|
||||
# $3: Content after the tag
|
||||
# $4: true/false: is this the beginning of the content?
|
||||
mustache-is-standalone() {
|
||||
local AFTER_TRIMMED BEFORE_TRIMMED CHAR
|
||||
|
||||
mustache-trim-chars BEFORE_TRIMMED "$2" false true " " "$'\t'"
|
||||
mustache-trim-chars AFTER_TRIMMED "$3" true false " " "$'\t'"
|
||||
CHAR=${BEFORE_TRIMMED: -1}
|
||||
|
||||
if [[ "$CHAR" != $'\n' ]] && [[ "$CHAR" != $'\r' ]]; then
|
||||
if [[ ! -z "$CHAR" ]] || ! $4; then
|
||||
return 1;
|
||||
fi
|
||||
fi
|
||||
|
||||
CHAR=${AFTER_TRIMMED:0:1}
|
||||
|
||||
if [[ "$CHAR" != $'\n' ]] && [[ "$CHAR" != $'\r' ]] && [[ ! -z "$CHAR" ]]; then
|
||||
return 2;
|
||||
fi
|
||||
|
||||
if [[ "$CHAR" == $'\r' ]] && [[ "${AFTER_TRIMMED:1:1}" == $'\n' ]]; then
|
||||
CHAR="$CHAR"$'\n'
|
||||
fi
|
||||
|
||||
local "$1" && mustache-indirect "$1" "$((${#BEFORE_TRIMMED})) $((${#3} + ${#CHAR} - ${#AFTER_TRIMMED}))"
|
||||
}
|
||||
|
||||
|
||||
# Handle the content for a tag that is never "standalone". No adjustments
|
||||
# are made for newlines and whitespace.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of destination "content" variable.
|
||||
# $2: Content before the tag that was not yet written
|
||||
# $3: Tag content (not used)
|
||||
# $4: Content after the tag
|
||||
mustache-standalone-denied() {
|
||||
echo -n "$2"
|
||||
local "$1" && mustache-indirect "$1" "$4"
|
||||
}
|
||||
|
||||
|
||||
# Show an environment variable or the output of a function.
|
||||
#
|
||||
# Limit/prefix any variables used
|
||||
@ -471,6 +533,77 @@ mustache-show() {
|
||||
}
|
||||
|
||||
|
||||
# Split a larger string into an array
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Destination variable
|
||||
# $2: String to split
|
||||
# $3: Starting delimiter
|
||||
# $4: Ending delimiter (optional)
|
||||
mustache-split() {
|
||||
local POS RESULT
|
||||
|
||||
RESULT=( "$2" )
|
||||
mustache-find-string POS "${RESULT[0]}" "$3"
|
||||
|
||||
if [[ "$POS" -ne -1 ]]; then
|
||||
# The first delimiter was found
|
||||
RESULT[1]=${RESULT[0]:$POS + ${#3}}
|
||||
RESULT[0]=${RESULT[0]:0:$POS}
|
||||
|
||||
if [[ ! -z "$4" ]]; then
|
||||
mustache-find-string POS "${RESULT[1]}" "$4"
|
||||
|
||||
if [[ "$POS" -ne -1 ]]; then
|
||||
# The second delimiter was found
|
||||
RESULT[2]="${RESULT[1]:$POS + ${#4}}"
|
||||
RESULT[1]="${RESULT[1]:0:$POS}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
local "$1" && mustache-indirect-array "$1" "${RESULT[@]}"
|
||||
}
|
||||
|
||||
|
||||
# Handle the content for a standalone tag. This means removing whitespace
|
||||
# (not newlines) before a tag and whitespace and a newline after a tag.
|
||||
# That is, assuming, that the line is otherwise empty.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of destination "content" variable.
|
||||
# $2: Content before the tag that was not yet written
|
||||
# $3: Tag content (not used)
|
||||
# $4: Content after the tag
|
||||
# $5: true/false: is this the beginning of the content?
|
||||
mustache-standalone-allowed() {
|
||||
local STANDALONE_BYTES
|
||||
|
||||
if mustache-is-standalone 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]}}"
|
||||
else
|
||||
echo -n "$2"
|
||||
local "$1" && mustache-indirect "$1" "$4"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Handle the content for a tag that is never "standalone". No adjustments
|
||||
# are made for newlines and whitespace.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of destination "content" variable.
|
||||
# $2: Content before the tag that was not yet written
|
||||
# $3: Tag content (not used)
|
||||
# $4: Content after the tag
|
||||
mustache-standalone-denied() {
|
||||
echo -n "$2"
|
||||
local "$1" && mustache-indirect "$1" "$4"
|
||||
}
|
||||
|
||||
|
||||
# Returns 0 (success) if the named thing is a function or if it is a non-empty
|
||||
# environment variable.
|
||||
#
|
||||
@ -499,24 +632,6 @@ mustache-test() {
|
||||
}
|
||||
|
||||
|
||||
# Determine if a given environment variable exists and if it is an array.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Name of environment variable
|
||||
#
|
||||
# Return code:
|
||||
# 0 if the name is not empty, 1 otherwise
|
||||
mustache-is-array() {
|
||||
local MUSTACHE_TEST
|
||||
|
||||
MUSTACHE_TEST=$(declare -p "$1" 2>/dev/null) || return 1
|
||||
[[ "${MUSTACHE_TEST:0:10}" == "declare -a" ]] && return 0
|
||||
[[ "${MUSTACHE_TEST:0:10}" == "declare -A" ]] && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
# Trim the leading whitespace only
|
||||
#
|
||||
# Parameters:
|
||||
@ -564,119 +679,6 @@ mustache-trim-whitespace() {
|
||||
}
|
||||
|
||||
|
||||
# Split a larger string into an array
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Destination variable
|
||||
# $2: String to split
|
||||
# $3: Starting delimiter
|
||||
# $4: Ending delimiter (optional)
|
||||
mustache-split() {
|
||||
local POS RESULT
|
||||
|
||||
RESULT=( "$2" )
|
||||
mustache-find-string POS "${RESULT[0]}" "$3"
|
||||
|
||||
if [[ "$POS" -ne -1 ]]; then
|
||||
# The first delimiter was found
|
||||
RESULT[1]=${RESULT[0]:$POS + ${#3}}
|
||||
RESULT[0]=${RESULT[0]:0:$POS}
|
||||
|
||||
if [[ ! -z "$4" ]]; then
|
||||
mustache-find-string POS "${RESULT[1]}" "$4"
|
||||
|
||||
if [[ "$POS" -ne -1 ]]; then
|
||||
# The second delimiter was found
|
||||
RESULT[2]="${RESULT[1]:$POS + ${#4}}"
|
||||
RESULT[1]="${RESULT[1]:0:$POS}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
local "$1" && mustache-indirect-array "$1" "${RESULT[@]}"
|
||||
}
|
||||
|
||||
# Find the first index of a substring
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Destination variable
|
||||
# $2: Haystack
|
||||
# $3: Needle
|
||||
mustache-find-string() {
|
||||
local POS STRING
|
||||
|
||||
STRING=${2%%$3*}
|
||||
[[ "$STRING" == "$2" ]] && POS=-1 || POS=${#STRING}
|
||||
local "$1" && mustache-indirect "$1" $POS
|
||||
}
|
||||
|
||||
|
||||
# Send a variable up to caller of a function
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name
|
||||
# $2: Value
|
||||
mustache-indirect() {
|
||||
unset -v "$1"
|
||||
printf -v "$1" '%s' "$2"
|
||||
}
|
||||
|
||||
|
||||
# Send an array up to caller of a function
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name
|
||||
# $2-*: Array elements
|
||||
mustache-indirect-array() {
|
||||
unset -v "$1"
|
||||
eval $1=\(\"\${@:2}\"\)
|
||||
}
|
||||
|
||||
|
||||
# Return the content to parse. Can be a list of partials for files or
|
||||
# the content from stdin.
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name to assign this content back as
|
||||
# $2-*: File names (optional)
|
||||
mustache-get-content() {
|
||||
local CONTENT FILENAME TARGET
|
||||
|
||||
TARGET=$1
|
||||
shift
|
||||
if [[ "${#@}" -gt 0 ]]; then
|
||||
CONTENT=""
|
||||
|
||||
for FILENAME in ${1+"$@"}; do
|
||||
# This is so relative paths work from inside template files
|
||||
CONTENT="$CONTENT"'{{>'"$FILENAME"'}}'
|
||||
done
|
||||
else
|
||||
mustache-load-file CONTENT /dev/stdin
|
||||
fi
|
||||
|
||||
local "$TARGET" && mustache-indirect "$TARGET" "$CONTENT"
|
||||
}
|
||||
|
||||
|
||||
# Read a file
|
||||
#
|
||||
# Parameters:
|
||||
# $1: Variable name to receive the file's content
|
||||
# $2: Filename to load
|
||||
mustache-load-file() {
|
||||
local CONTENT
|
||||
|
||||
# The subshell removes any trailing newlines. We forcibly add
|
||||
# a dot to the content to preserve all newlines.
|
||||
# TODO: remove cat and replace with read loop?
|
||||
CONTENT=$(cat $2; echo '.')
|
||||
CONTENT=${CONTENT:0: -1} # Remove last dot
|
||||
|
||||
local "$1" && mustache-indirect "$1" "$CONTENT"
|
||||
}
|
||||
|
||||
|
||||
# Save the list of functions as an array
|
||||
MUSTACHE_FUNCTIONS=$(declare -F)
|
||||
MUSTACHE_FUNCTIONS=( ${MUSTACHE_FUNCTIONS//declare -f /} )
|
||||
|
Loading…
Reference in New Issue
Block a user