Added associative array extraction

This commit is contained in:
Joseph Dalrymple 2023-04-04 01:14:18 -05:00
parent 6dc284f05a
commit f2f2ddbbd2
4 changed files with 114 additions and 14 deletions

98
mo
View File

@ -444,6 +444,38 @@ moIndirect() {
}
# Internal: Expand an array to local variables
#
# $1 - Array name
#
# If an associative array's key is also declared an array
# then its value will be treated as an array
#
# Returns nothing.
moExpandAssoc() {
local moKeys moValue moValueArr
moKeys=($(eval 'echo "${!'$1'[@]}"'))
for k in "${moKeys[@]}"; do
moValue=$(eval 'echo "${'$1'['$k']}"')
local "$k" && moIndirect "$k" "$moValue"
done
}
# Internal: Cleans the values from a previous expanded assoc
#
# $1 - Array name
#
# Returns nothing.
moCleanExpanded() {
local moKeys moValue moValueArr
moKeys=($(eval 'echo "${!'$1'[@]}"'))
for k in "${moKeys[@]}"; do
unset -v "$k"
done
}
# Internal: Send an array as a variable up to caller of a function
#
# $1 - Variable name
@ -500,6 +532,36 @@ moIsArray() {
}
# Internal: Determine if a given environment variable exists and if it is
# an associative array.
#
# $1 - Name of environment variable
#
# Be extremely careful. Even if strict mode is enabled, it is not honored
# in newer versions of Bash. Any errors that crop up here will not be
# caught automatically.
#
# Examples
#
# declare -A var
# var[foo]="bar"
# if moIsArray var; then
# echo "This is an array"
# echo "Make sure you don't accidentally use \$var"
# fi
#
# Returns 0 if the name is not empty, 1 otherwise.
moIsAssocArray() {
# Namespace this variable so we don't conflict with what we're testing.
local moTestResult
moTestResult=$(declare -p "$1" 2>/dev/null) || return 1
[[ "${moTestResult:0:10}" == "declare -A" ]] && return 0
return 1
}
# Internal: Determine if the given name is a defined function.
#
# $1 - Function name to check
@ -634,25 +696,33 @@ moLoadFile() {
# Internal: Process a chunk of content some number of times. Writes output
# to stdout.
# to stdout. Extracts associative arrays to scope before processing.
#
# $1 - Content to parse repeatedly
# $2 - Tag prefix (context name)
# $3-@ - Names to insert into the parsed content
# $1 - Name of current array
# $2 - Current block
#
# Returns nothing.
moLoop() {
local content context contextBase
local moFullKey moValue moKeys moTag
content=$1
contextBase=$2
shift 2
moTag=$1
moBlock=$2
while [[ "${#@}" -gt 0 ]]; do
moFullTagName context "$contextBase" "$1"
moParse "$content" "$context" false
shift
done
declare -a moKeys
moKeys=($(eval "echo \"\${!${moTag}[@]}\""))
for k in "${moKeys[@]}"; do
moFullTagName moFullKey "$moTag" "$k"
moValue=$(moShow "$moFullKey" "$moFullKey")
if moIsAssocArray "$moValue"; then
moExpandAssoc "$moValue"
moParse "$moBlock" "$moFullKey" false
moCleanExpanded "$moValue"
else
moParse "$moBlock" "$moFullKey" false
fi
done;
}
@ -701,7 +771,7 @@ moParse() {
moParse "$moContent" "$moCurrent" false
moContent="${moBlock[2]}"
elif moIsArray "$moTag"; then
eval "moLoop \"\${moBlock[0]}\" \"$moTag\" \"\${!${moTag}[@]}\""
moLoop "$moTag" "${moBlock[0]}"
else
moParse "${moBlock[0]}" "$moCurrent" true
fi

View File

@ -0,0 +1,12 @@
declare -a navItems nonFunctional
declare -A homeLink otherLink
homeLink[title]="Home"
homeLink[url]="https://www.example.com/home"
otherLink[title]="Other Link"
otherLink[url]="https://www.example.com/other-page"
navItems=(homeLink otherLink)
stringArray=("homeLink" "otherLink")

View File

@ -0,0 +1,8 @@
# Links
- [Home](https://www.example.com/home)
- [Other Link](https://www.example.com/other-page)
# Standard List
- homeLink
- otherLink

View File

@ -0,0 +1,10 @@
# Links
{{#navItems}}
- [{{title}}]({{url}})
{{/navItems}}
# Standard List
{{#stringArray}}
- {{.}}
{{/stringArray}}