+#!/bin/bash
+# set -x
+
+#
+# populate.sh
+#
+# Copyright (C) 2007 nastasi@alternativeoutput.it
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details. You should have received a
+# copy of the GNU General Public License along with this program; if
+# not, write to the Free Software Foundation, Inc, 59 Temple Place -
+# Suite 330, Boston, MA 02111-1307, USA.
+#
+
+#
+# Description of tag behaviors
+# ----------------------------
+#
+# | |
+# Template Tag | Assoc. Var | Description
+# ------------------------+----------------------------+-------------------
+# #T_<tagname># | $T_<tagname> | simple tag
+# ##T_<blkname>:start## | $B_<tagname> | block tag begin
+# . . . . . | |
+# #T_<tagname># | $T_<blkname>_<tagname> | tag inside a block
+# #T_<tagname>_X# | $T_<blkname>_<tagname>_<#> | indexed tag inside a block
+# | | (the first in the alphab. order must
+# | | exists to enable the entire block)
+# . . . . . | |
+# ##T_<blkname>:stop## | | block tag finish
+#
+
+# TODO
+#
+# Aggiungere la filtratura per tipo di output
+#
+# loop formati
+#+ loop lingue
+#+ loop for recursion (general)
+#+ get blocchi dal template
+#+ sost TAG nei blocchi con le VAR
+#+ loop for recursion (for each row of each block)
+#+ per ogni set di var per quel blocco (flat o con indice)
+#+ fino a quando la prima con indice non e' stringa vuota
+#+ fine loop for recursion (for each row of each block)
+#+ sostituire i TAG nel template con i blocchi
+#+ sostituire i TAG nel template con le VAR
+#
+#+ produrre il file in output
+#+ fine loop for recursion (general)
+#+ fine loop lingue
+# fine loop formati
+#
+#
+
+# GLOBAL VARS
+# debug=1
+debug=""
+verbose=""
+NEWLI="#aCaPo#"
+
+TMPFILE="/tmp/populate1_$$.tmp"
+TMP2FILE="/tmp/populate2_$$.tmp"
+TMP3FILE="/tmp/populate3_$$.tmp"
+TMP4FILE="/tmp/populate4_$$.tmp"
+
+
+#
+# FUNCTIONS
+#
+function usage() {
+ echo "Usage: $1 [-v] [-d] [-h] data-file"
+ echo " -v Verbose enable."
+ echo " -d Debug enable."
+ echo " -h This help."
+ exit 0
+}
+
+function vars_get() {
+ # echo "vars_get start"
+ sed -n 's/\(#T_[A-Z_]\+#\)/\n\1\n/gp' | grep '^#T_' | sort | uniq | sed 's/#\(T_[A-Z_]\+\)#/\1/g'
+ # echo "vars_get stop"
+ return 0
+}
+
+function unsedify() {
+
+ (
+ if [ $# -eq 1 ]; then
+ echo "$1"
+ else
+ cat
+ fi
+ ) | sed 's/\(["\\\/\$]\)/\\\1/g'
+
+ return 0
+}
+
+function formatify() {
+ (
+ if [ $# -eq 2 ]; then
+ echo "$2"
+ else
+ cat
+ fi
+ ) | (
+ if [ "$1" = "tex" ]; then
+ sed 's/à/\\`a/g;s/è/\\`e/g;s/ì/\\`i/g;s/ò/\\`o/g;s/ù/\\`u/g;s/áéíóú/\\'"'"'a/g;
+s/é/\\'"'"'e/g;s/í/\\'"'"'i/g;s/ó/\\'"'"'o/g;s/ú/\\'"'"'u/g;s/°/\$\^\\circ\$/g;
+s/<i>/\\textit{/g;s/<b>/\\textbf{/g;s/<\/[ib]>/}/g;s/<url>/URL: \\textit\{/g;s/<\/url>/\}/g;
+s/‟/``/g;s/”/'"''"'/g;s/<lang:tex>//g;s/<\/lang:tex>//g;s/<lang:[^>]*>.*<\/lang:[^>]*>//g'
+ elif [ "$1" = "htm" ]; then
+ sed "s/${NEWLI}${NEWLI}/<br>${NEWLI}/g;"'s/<url>\([^<]*\)<\/url>/<a href="\1">\1<\/a>/g;
+s/<lang:htm>//g;s/<\/lang:htm>//g;s/<lang:[^>]*>.*<\/lang:[^>]*>//g'
+ fi
+ )
+
+
+}
+
+function debecho() {
+ if [ -z $debug ]; then
+ return 0
+ fi
+ echo "debug "$*
+ return 0
+}
+
+function populator() {
+ local tmplname lng frmt
+
+ tmplname="$1"
+ contname="$2"
+ lng="$3"
+ frmt="$4"
+
+ tmplname="${tmplname}.${frmt}"
+ if [ $lng ]; then
+ lngsfx="_`echo "$lng" | tr '[:lower:]' '[:upper:]'`"
+ filesfx="_$lng"
+ else
+ lngsfx=""
+ filesfx=""
+ fi
+
+ oldifs="$IFS"
+ IFS="
+"
+ anotherloop=0
+
+ #
+ # Recursion loop, resolve TAG created with a tag substitution, on the entire document.
+ #
+ while [ $anotherloop -eq 0 ]; do
+ debecho "ANOTHERLOOP"
+ #
+ # GET BLOCKS
+ #
+
+ # add normal tag before each block, output to TMPFILE
+ cat $tmplname | sed 's/^\(##\(T_[A-Z_0-9]\+\):start##\)$/#\2#\n\1/g' > $TMPFILE
+
+ # get all blocks from the template, output to TMP2FILE
+ cat $TMPFILE | sed -n '/##T_[A-Z_0-9]\+:start##/,/##T_[A-Z_0-9]\+:end##/p' > $TMP2FILE
+
+ # remove blocks from the template, output to TMP3FILE
+ cat $TMPFILE | sed '/##T_[A-Z_0-9]\+:start##/,/##T_[A-Z_0-9]\+:end##/d' > $TMP3FILE
+
+ # get line number of the start of all blocks
+ blist="`cat $TMP2FILE | grep -n '^##T_[A-Z_0-9]\+:start##$' | cut -d : -f 1`"
+
+ # for each line number ...
+ for i in `echo "$blist"`; do
+ # extracts the current block
+ block_cur="`cat $TMP2FILE | sed -n $i',/##T_[A-Z_0-9]\+:end##/p'`"
+
+ # extracts the name of the block variable
+ block_var="`echo "$block_cur" | sed -n "1,1p" | sed 's/^\(##T\(_[A-Z_0-9]\+\):start##\)$/B\2/g'`"
+ # remove first and last line (block delimiters) and double '\' char, substitute \n with $NEWLI
+ block_val="`echo "$block_cur" | sed '1d;$d;s/\\\\/\\\\\\\\/g' | sed "s/\$/$NEWLI\\\\\\/g"`"
+
+ # assign the value to the var
+ read $block_var <<< "$block_val"
+
+ debecho "vv------------------------------"
+ debecho "BLOCK_VAR: $block_var"
+ debecho "BLOCK_VAL: ${!block_var}"
+ debecho "^^------------------------------"
+ done
+
+ #
+ # SUBSTITUTE TAG INSIDE EACH BLOCK
+ #
+ if [ $debug ]; then
+ echo "debug blocks: ${!B_*}"
+ fi
+ for i in ${!B_*}; do
+ blk_var="`echo "$i" | sed 's/^B_/T_/g'`"
+ debecho "Tag_var: $tag_var"
+ blk_val=""
+ outindex=1
+ for idx in `seq 1 100`; do
+ debecho "ISFIRST YES"
+ isfirst="YES"
+
+ blk_src="${!i}"
+ #
+ # Recursion loop, resolve TAG created with a tag substitution, for each row of each block.
+ #
+ blk_anotherloop=0
+ while [ $blk_anotherloop -eq 0 ]; do
+ debecho "BLK_ANOTHERLOOP $i $idx"
+ sedargs=""
+ tlist="`echo "$blk_src" | vars_get`"
+ debecho "TILIST $tlist"
+
+ for e in $tlist; do
+ debecho "LOO1"
+
+ tag_var="`echo "$i $e" | sed 's/^B_\([A-Z_]\+\) T_\([A-Z_]\+\)/T_\1_\2/g'`"
+ echo "$tag_var" | grep -q '_X$'
+ if [ $? -eq 0 ]; then
+ # fault back to original language if not defined
+ for ll in $lngsfx ""; do
+ tag_ele="`echo "$tag_var" | sed 's/X$//g'`${idx}${ll}"
+ debecho "tag_ele: $tag_ele"
+ debecho " BRA3"
+ declare -p $tag_ele >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ break
+ else
+ if [ "$isfirst" = "YES" -a -z "$ll" ]; then
+ outindex=0
+ break 4
+ fi
+ if [ -z "$ll" ]; then
+ echo "WARN: undefined [$tag_ele]"
+ elif [ "$verbose" ]; then
+ tag_fback="`echo "$tag_var" | sed 's/X$//g'`${idx}"
+ echo "WARN: undefined [$tag_ele]; fault back to main [${!tag_fback}]"
+ fi
+ fi
+ if [ -z "$ll" ]; then
+ debecho " ISFIRST NO"
+ isfirst="NO"
+ fi
+ done
+
+ else
+ debecho " BRA4"
+ # faultback to original language if not defined
+ for ll in $lngsfx ""; do
+ tag_ele="${tag_var}${ll}"
+ debecho " tag_ele: $tag_ele"
+
+ declare -p $tag_ele >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ break
+ else
+ if [ -z "$ll" ]; then
+ echo "WARN: undefined [$tag_ele]"
+ elif [ "$verbose" ]; then
+ echo "WARN: undefined [$tag_ele]; fault back to main [${!tag_var}]"
+ fi
+ fi
+ done
+ fi
+ tag_val="`echo "${!tag_ele}" | sed "s/\$/$NEWLI/g" | tr -d '\n' | sed "s/$NEWLI\$//g" \
+ | formatify $frmt`"
+ debecho " tag_val: $tag_val"
+
+ # TAG replacement
+ tag_val="`unsedify "$tag_val"`"
+ sedargs="${sedargs}s/#${e}#/$tag_val/g;"
+ done # for e ...
+ debecho "----------------------------------"
+ debecho "$sedargs"
+ blk_val="${blk_val}`echo "$blk_src" | sed "$sedargs"`"
+ if [ $? -ne 0 ]; then
+ echo "$sedargs" > sedargs.txt
+ exit 111
+ fi
+
+ echo "$blk_val" | grep -q '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
+ if [ $? -eq 0 ]; then
+ # echo "$blk_val" | grep '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
+ # echo "POST BLK GREP"
+ # read
+ blk_src="$blk_val"
+ blk_val=""
+ blk_anotherloop=0
+ else
+ blk_anotherloop=1
+ fi
+ done # while [ $blk_another_loop ....
+ if [ $outindex -eq 0 ]; then
+ break
+ fi
+ done
+
+ debecho "++++++++++++++++++++++++++++++++++"
+ debecho "BLK_VAL: $blk_val"
+ debecho "**********************************"
+ # read $blk_var <<< "$blk_val"
+
+ # TAG replacement
+ blk_val="`unsedify "$blk_val" | sed "s/$NEWLI\$//g"`"
+ debecho "BLK_VAR: $blk_var: $blk_val"
+ debecho "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ cat $TMP3FILE | sed "s/#${blk_var}#/$blk_val/g" >$TMP4FILE
+ mv $TMP4FILE $TMP3FILE
+ done
+
+ # cat, sed to avoid multitag on single line, grep of tags, sort, uniq, sed to remove '#' chars
+ t_vars="`cat $TMP3FILE | vars_get`"
+
+ for tag_var in $t_vars; do
+ # echo "TAG_VAR: $tag_var"
+ for ll in $lngsfx ""; do
+ tag_ele="${tag_var}${ll}"
+ declare -p $tag_ele >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ break
+ else
+ if [ -z "$ll" ]; then
+ echo "WARN: undefined [$tag_ele]"
+ elif [ "$verbose" ]; then
+ echo "WARN: undefined [$tag_ele]; fault back to main [${!tag_var}]"
+ fi
+ fi
+ done
+ # TAG replacement
+ tag_val="`echo "${!tag_ele}" | sed "s/\$/$NEWLI/g" | tr -d '\n' | sed "s/$NEWLI\$//g" \
+ | formatify $frmt | unsedify`"
+
+
+ cat $TMP3FILE | sed "s/#${tag_var}#/$tag_val/g" >$TMP4FILE
+ mv $TMP4FILE $TMP3FILE
+ done
+
+ cat $TMP3FILE | grep -q '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
+ if [ $? -eq 0 ]; then
+ # cat $TMP3FILE | grep -q '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
+ # echo POSTGREP
+ # read
+ anotherloop=0
+ cat $TMP3FILE | sed "s/$NEWLI/\n/g" > $TMP4FILE
+ tmplname="$TMP4FILE"
+ else
+ anotherloop=1
+ fi
+ done # while [ $anotherloop -eq 0 ]; do
+ cat $TMP3FILE | sed "s/$NEWLI/\n/g" > ${contname}${filesfx}.$frmt
+
+ rm -f $TMPFILE $TMP2FILE $TMP3FILE $TMP4FILE
+
+ IFS="$oldifs"
+
+ return 0
+}
+
+#
+# MAIN
+#
+
+# maybe parametrizable
+# tmplname="temptest"
+tmplname="cv_template"
+while [ $# ]; do
+ case $1 in
+ -v) verbose="Y"
+ ;;
+ -d) debug="Y"
+ ;;
+ -h) usage $0
+ ;;
+ *) break
+ esac
+ shift
+done
+contname="$1"
+
+rm -f $TMPFILE $TMP2FILE $TMP3FILE $TMP4FILE
+
+if [ ! -f ${contname}.data ]; then
+ echo "File ${contname}.data not exists"
+ exit 1
+fi
+
+# source the data file from template scope
+. ${tmplname}.data
+
+# source the data file from user scope
+. ${contname}.data
+
+for frmt in tex htm; do
+ for lng in "" eng; do
+ echo "Format: $frmt Lang: $lng"
+ populator "$tmplname" "$contname" "$lng" "$frmt"
+ done
+done
+
+exit 0