specifications

Specification and standard documents
git clone git://git.finwo.net/misc/specifications
Log | Files | Refs | README | LICENSE

template.sh (2651B)


      1 #!/usr/bin/env bash
      2 # e660cc6c-638a-4f9b-9527-ff96a19bbeed
      3 
      4 # Very simple templating system that replaces {{VAR}} by the value of $VAR.
      5 # Supports default values by writting {{VAR=value}} in the template.
      6 
      7 # Replaces all {{VAR}} by the $VAR value in a template file and outputs it
      8 
      9 FIND=$(command -v gfind find | head -1)
     10 
     11 readonly PROGNAME=$(basename $0)
     12 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
     13 
     14 # Usage string
     15 usage="
     16 Usage:
     17   ${PROGNAME} -h|--help
     18   ${PROGNAME} --update
     19   ${PROGNAME} [-c|--config config_file] [-p|--partials partials_dir] template_file [...template_file]
     20 
     21 Options:
     22   -h --help             Show this help text
     23      --update           Perform a self-update
     24   -c --config <path>    Specify config file
     25   -p --partials <path>  Specify partials directory
     26 "
     27 
     28 # Declare storage
     29 declare -A TOKENS
     30 declare -A TEMPLATES
     31 declare -A PARTIALS
     32 PARTIALARGS=
     33 INDEX=0
     34 
     35 # Parse arguments
     36 while [ "$#" -gt 0 ]; do
     37   case "$1" in
     38     -h|--help)
     39       echo "$usage"
     40       exit 0
     41       ;;
     42     --update)
     43       curl -L -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/finwo/ini-tools/master/template.sh > "${DIR}/${PROGNAME}"
     44       exit $?
     45       ;;
     46     -c|--config)
     47       shift
     48       PARTIALARGS="${PARTIALARGS} -c ${1}"
     49       if [[ -f "${1}" ]]; then
     50         while IFS='\n' read line; do
     51           key=${line%%=*}
     52           value=${line#*=}
     53           if [ -z "$key" ]; then continue; fi
     54           TOKENS["$key"]="$value"
     55         done <<< "$(${DIR}/ini.sh ${1})"
     56       fi
     57       ;;
     58     -p|--partials)
     59       shift
     60       PARTIALARGS="${PARTIALARGS} -p ${1}"
     61       if [[ -d "${1}" ]]; then
     62         while IFS=':' read name filename; do
     63           PARTIALS["$name"]="${filename}"
     64         done <<< "$(${FIND} "${1}" -type f -printf "%P:%p\n")"
     65       fi
     66       ;;
     67     *)
     68       if [[ -f "${1}" ]]; then
     69         TEMPLATES[$INDEX]="${1}"
     70         INDEX=$(( $INDEX + 1 ))
     71       fi
     72       ;;
     73   esac
     74   shift
     75 done
     76 
     77 # Cancel if we have no config files
     78 if [ "${INDEX}" -eq 0 ]; then
     79   echo "ERROR: You need to specify a template file" >&2
     80   echo "$usage"
     81   exit 1
     82 fi
     83 
     84 # Handle all given templates
     85 for templatefile in "${TEMPLATES[@]}"; do
     86   CONTENT=$(cat $templatefile);
     87 
     88   # Replace tokens
     89   for token in "${!TOKENS[@]}"; do
     90     CONTENT=${CONTENT//"{{$token}}"/"${TOKENS[$token]}"}
     91   done
     92 
     93   # Handle partials
     94   for partial in "${!PARTIALS[@]}"; do
     95     if [[ "${CONTENT}" == *"{{>${partial}}}"* ]]; then
     96       PARTIALCONTENT="$(${DIR}/${PROGNAME} ${PARTIALARGS} ${PARTIALS[$partial]})"
     97       CONTENT=${CONTENT//"{{>$partial}}"/"${PARTIALCONTENT}"}
     98     fi
     99   done
    100 
    101   # Output the result
    102   echo -e "${CONTENT//"\\"/"\\\\"}"
    103 done
    104 
    105