de6b1b7baa64ae3f41a5bbd5d679278fd3edc50d
[populate.git] / populate.sh
1 #!/bin/bash
2 # set -x
3
4 #
5 #   populate.sh
6 #
7 #   Copyright (C) 2007 nastasi@alternativeoutput.it
8 #
9 #  This program is free software; you can redistribute it and/or modify
10 #  it under the terms of the GNU General Public License as published by
11 #  the Free Software Foundation; either version 2 of the License, or
12 #  (at your option) any later version.
13 #
14 #  This program is distributed in the hope that it will be useful, but
15 #  WITHOUT ANY WARRANTY; without even the implied warranty of
16 #  MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 #  General Public License for more details. You should have received a
18 #  copy of the GNU General Public License along with this program; if
19 #  not, write to the Free Software Foundation, Inc, 59 Temple Place -
20 #  Suite 330, Boston, MA 02111-1307, USA.
21 #
22
23 #
24 # Description of tag behaviors
25 # ----------------------------
26 #
27 #                         |                            |
28 #       Template Tag      |         Assoc. Var         |  Description
29 # ------------------------+----------------------------+-------------------              
30 #   #T_<tagname>#         | $T_<tagname>               |  simple tag
31 #   ##T_<blkname>:start## | $B_<tagname>               |  block tag begin
32 #        . . . . .        |                            |
33 #      #T_<tagname>#      | $T_<blkname>_<tagname>     |  tag inside a block
34 #      #T_<tagname>_X#    | $T_<blkname>_<tagname>_<#> |  indexed tag inside a block
35 #                         |                            |  (the first in the alphab. order must
36 #                         |                            |   exists to enable the entire block)
37 #        . . . . .        |                            |
38 #   ##T_<blkname>:stop##  |                            |  block tag finish
39 #
40
41 # TODO
42 #
43 #  Aggiungere la filtratura per tipo di output
44 #
45 #  loop formati
46 #+   loop lingue
47 #+     loop for recursion (general)
48 #+       get blocchi dal template
49 #+       sost TAG nei blocchi con le VAR
50 #+           loop for recursion (for each row of each block)
51 #+             per ogni set di var per quel blocco (flat o con indice)
52 #+             fino a quando la prima con indice non e' stringa vuota
53 #+           fine loop for recursion (for each row of each block)
54 #+       sostituire i TAG nel template con i blocchi
55 #+       sostituire i TAG nel template con le VAR
56 #
57 #+       produrre il file in output
58 #+     fine loop for recursion (general)
59 #+   fine loop lingue
60 #  fine loop formati
61 #
62 #
63
64 #  GLOBAL VARS
65 # debug=1
66 debug=""
67 verbose=""
68 NEWLI="#aCaPo#"
69
70 TMPFILE="/tmp/populate1_$$.tmp"
71 TMP2FILE="/tmp/populate2_$$.tmp"
72 TMP3FILE="/tmp/populate3_$$.tmp"
73 TMP4FILE="/tmp/populate4_$$.tmp"
74
75
76 #
77 #  FUNCTIONS
78 #
79 function usage() {
80     echo "Usage: $1 [-v] [-d] [-h] data-file"
81     echo "  -v     Verbose enable."
82     echo "  -d     Debug enable."
83     echo "  -h     This help."
84     exit 0
85 }
86
87 function vars_get() {
88     # echo "vars_get start"
89     sed -n 's/\(#T_[A-Z_]\+#\)/\n\1\n/gp' | grep '^#T_' | sort | uniq | sed 's/#\(T_[A-Z_]\+\)#/\1/g'
90     # echo "vars_get stop"
91     return 0
92 }
93
94 function unsedify() {
95     
96     (
97         if [ $# -eq 1 ]; then
98             echo "$1" 
99         else
100             cat
101         fi
102     ) | sed 's/\(["\\\/\$]\)/\\\1/g'
103
104     return 0
105 }
106
107 function formatify() {
108     (
109         if [ $# -eq 2 ]; then
110             echo "$2" 
111         else
112             cat
113         fi
114     ) | (
115         if [ "$1" = "tex" ]; then
116             sed 's/à/\\`a/g;s/è/\\`e/g;s/ì/\\`i/g;s/ò/\\`o/g;s/ù/\\`u/g;s/áéíóú/\\'"'"'a/g;
117 s/é/\\'"'"'e/g;s/í/\\'"'"'i/g;s/ó/\\'"'"'o/g;s/ú/\\'"'"'u/g;s/°/\$\^\\circ\$/g;
118 s/<i>/\\textit{/g;s/<b>/\\textbf{/g;s/<\/[ib]>/}/g;s/<url>/URL: \\textit\{/g;s/<\/url>/\}/g;
119 s/“/``/g;s/”/'"''"'/g;s/<lang:tex>//g;s/<\/lang:tex>//g;s/<lang:[^>]*>.*<\/lang:[^>]*>//g'
120         elif [ "$1" = "htm" ]; then
121             sed "s/${NEWLI}${NEWLI}/<br>${NEWLI}/g;"'s/<url>\([^<]*\)<\/url>/<a href="\1">\1<\/a>/g;
122 s/<lang:htm>//g;s/<\/lang:htm>//g;s/<lang:[^>]*>.*<\/lang:[^>]*>//g'
123         fi
124     )
125
126     
127 }
128
129 function debecho() {
130     if [ -z $debug ]; then
131        return 0
132     fi
133     echo "debug "$*
134     return 0
135 }
136
137 function populator() {
138     local tmplname lng frmt
139
140     tmplname="$1"
141     contname="$2"
142     lng="$3"
143     frmt="$4"
144
145     tmplname="${tmplname}.${frmt}"
146     if [ $lng ]; then
147         lngsfx="_`echo "$lng" | tr '[:lower:]' '[:upper:]'`"
148         filesfx="_$lng"
149     else
150         lngsfx=""
151         filesfx=""
152     fi
153
154     oldifs="$IFS"
155     IFS="
156 "
157     anotherloop=0
158
159     #
160     #  Recursion loop, resolve TAG created with a tag substitution, on the entire document.
161     #
162     while [ $anotherloop -eq 0 ]; do
163         debecho "ANOTHERLOOP"
164         #
165         # GET BLOCKS
166         #
167
168         # add normal tag before each block, output to TMPFILE
169         cat $tmplname | sed 's/^\(##\(T_[A-Z_0-9]\+\):start##\)$/#\2#\n\1/g' > $TMPFILE
170
171         # get all blocks from the template, output to TMP2FILE
172         cat $TMPFILE | sed -n '/##T_[A-Z_0-9]\+:start##/,/##T_[A-Z_0-9]\+:end##/p' > $TMP2FILE
173
174         # remove blocks from the template, output to TMP3FILE 
175         cat $TMPFILE | sed '/##T_[A-Z_0-9]\+:start##/,/##T_[A-Z_0-9]\+:end##/d' > $TMP3FILE
176
177         # get line number of the start of all blocks
178         blist="`cat $TMP2FILE | grep -n '^##T_[A-Z_0-9]\+:start##$' | cut -d : -f 1`"
179
180         # for each line number ...
181         for i in `echo "$blist"`; do
182             # extracts the current block
183             block_cur="`cat $TMP2FILE | sed -n $i',/##T_[A-Z_0-9]\+:end##/p'`"
184
185             # extracts the name of the block variable
186             block_var="`echo "$block_cur" | sed -n "1,1p" | sed 's/^\(##T\(_[A-Z_0-9]\+\):start##\)$/B\2/g'`"
187             # remove first and last line (block delimiters) and double '\' char, substitute \n with $NEWLI  
188             block_val="`echo "$block_cur" | sed '1d;$d;s/\\\\/\\\\\\\\/g' | sed "s/\$/$NEWLI\\\\\\/g"`"
189
190             # assign the value to the var
191             read $block_var <<< "$block_val"
192
193             debecho "vv------------------------------"
194             debecho "BLOCK_VAR: $block_var"
195             debecho "BLOCK_VAL: ${!block_var}"
196             debecho "^^------------------------------"
197         done
198
199         # 
200         #  SUBSTITUTE TAG INSIDE EACH BLOCK
201         #
202         if [ $debug ]; then
203             echo "debug blocks: ${!B_*}"
204         fi
205         for i in ${!B_*}; do
206             blk_var="`echo "$i" | sed 's/^B_/T_/g'`"
207             debecho "Tag_var: $tag_var"
208             blk_val=""
209             outindex=1
210             for idx in `seq 1 100`; do
211                 debecho "ISFIRST YES"
212                 isfirst="YES"
213
214                 blk_src="${!i}"
215                 #
216                 #  Recursion loop, resolve TAG created with a tag substitution, for each row of each block.
217                 #
218                 blk_anotherloop=0
219                 while [ $blk_anotherloop -eq 0 ]; do
220                     debecho "BLK_ANOTHERLOOP $i $idx"
221                     sedargs=""
222                     tlist="`echo "$blk_src" | vars_get`"
223                     debecho "TILIST $tlist"
224                 
225                     for e in $tlist; do
226                         debecho "LOO1"
227                     
228                         tag_var="`echo "$i $e" | sed 's/^B_\([A-Z_]\+\) T_\([A-Z_]\+\)/T_\1_\2/g'`"
229                         echo "$tag_var" | grep -q '_X$'
230                         if [ $? -eq 0 ]; then
231                             # fault back to original language if not defined
232                             for ll in $lngsfx ""; do
233                                 tag_ele="`echo "$tag_var" | sed 's/X$//g'`${idx}${ll}"
234                                 debecho "tag_ele: $tag_ele"
235                                 debecho "  BRA3"
236                                 declare -p $tag_ele >/dev/null 2>&1
237                                 if [ $? -eq 0 ]; then
238                                     break
239                                 else
240                                     if [ "$isfirst" = "YES" -a -z "$ll" ]; then
241                                         outindex=0
242                                         break 4
243                                     fi
244                                     if [ -z "$ll" ]; then
245                                         echo "WARN: undefined [$tag_ele]"
246                                     elif [ "$verbose" ]; then
247                                         tag_fback="`echo "$tag_var" | sed 's/X$//g'`${idx}"
248                                         echo "WARN: undefined [$tag_ele]; fault back to main [${!tag_fback}]"
249                                     fi
250                                 fi
251                                 if [ -z "$ll" ]; then
252                                     debecho "  ISFIRST NO"
253                                     isfirst="NO"
254                                 fi
255                             done
256
257                         else
258                             debecho "  BRA4"
259                             # faultback to original language if not defined
260                             for ll in $lngsfx ""; do
261                                 tag_ele="${tag_var}${ll}"
262                                 debecho "  tag_ele: $tag_ele"
263
264                                 declare -p $tag_ele >/dev/null 2>&1
265                                 if [ $? -eq 0 ]; then
266                                     break
267                                 else
268                                     if [ -z "$ll" ]; then
269                                         echo "WARN: undefined [$tag_ele]"
270                                     elif [ "$verbose" ]; then
271                                         echo "WARN: undefined [$tag_ele]; fault back to main [${!tag_var}]"
272                                     fi
273                                 fi
274                             done
275                         fi
276                         tag_val="`echo "${!tag_ele}" | sed "s/\$/$NEWLI/g" | tr -d '\n' | sed "s/$NEWLI\$//g" \
277                                 | formatify $frmt`"
278                         debecho "  tag_val: $tag_val"
279
280                         # TAG replacement
281                         tag_val="`unsedify "$tag_val"`"
282                         sedargs="${sedargs}s/#${e}#/$tag_val/g;"
283                     done # for e ...
284                     debecho "----------------------------------"
285                     debecho "$sedargs" 
286                     blk_val="${blk_val}`echo "$blk_src" | sed "$sedargs"`"
287                     if [ $? -ne 0 ]; then
288                         echo "$sedargs" > sedargs.txt
289                         exit 111
290                     fi
291                 
292                     echo "$blk_val" | grep -q '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
293                     if [ $? -eq 0 ]; then
294                         # echo "$blk_val" | grep '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
295                         # echo "POST BLK GREP"
296                         # read 
297                         blk_src="$blk_val"
298                         blk_val=""
299                         blk_anotherloop=0
300                     else
301                         blk_anotherloop=1
302                     fi
303                 done # while [ $blk_another_loop ....
304                 if [ $outindex -eq 0 ]; then
305                     break
306                 fi
307             done
308             
309             debecho "++++++++++++++++++++++++++++++++++"
310             debecho "BLK_VAL: $blk_val"
311             debecho "**********************************"
312             # read $blk_var <<< "$blk_val"
313             
314             # TAG replacement
315             blk_val="`unsedify "$blk_val" | sed "s/$NEWLI\$//g"`"
316             debecho "BLK_VAR: $blk_var: $blk_val"
317             debecho "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
318             cat $TMP3FILE | sed "s/#${blk_var}#/$blk_val/g"  >$TMP4FILE
319             mv $TMP4FILE $TMP3FILE    
320         done
321
322         # cat, sed to avoid multitag on single line, grep of tags, sort, uniq, sed to remove '#' chars
323         t_vars="`cat $TMP3FILE | vars_get`"
324
325         for tag_var in $t_vars; do 
326             # echo "TAG_VAR: $tag_var"
327             for ll in $lngsfx ""; do
328                 tag_ele="${tag_var}${ll}"
329                 declare -p $tag_ele >/dev/null 2>&1
330                 if [ $? -eq 0 ]; then
331                     break
332                 else
333                     if [ -z "$ll" ]; then
334                         echo "WARN: undefined [$tag_ele]"
335                     elif [ "$verbose" ]; then
336                         echo "WARN: undefined [$tag_ele]; fault back to main [${!tag_var}]"
337                     fi
338                 fi
339             done
340             # TAG replacement
341             tag_val="`echo "${!tag_ele}" | sed "s/\$/$NEWLI/g" | tr -d '\n' | sed "s/$NEWLI\$//g" \
342                   | formatify $frmt | unsedify`"
343             
344                 
345             cat $TMP3FILE | sed "s/#${tag_var}#/$tag_val/g" >$TMP4FILE
346             mv $TMP4FILE $TMP3FILE    
347         done
348         
349         cat $TMP3FILE | grep -q '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
350         if [ $? -eq 0 ]; then
351             # cat $TMP3FILE | grep -q '#\{1,2\}T_[A-Za-z_:]\+#\{1,2\}'
352             # echo POSTGREP
353             # read 
354             anotherloop=0
355             cat $TMP3FILE | sed "s/$NEWLI/\n/g" > $TMP4FILE
356             tmplname="$TMP4FILE"
357         else
358             anotherloop=1
359         fi
360     done #  while [ $anotherloop -eq 0 ]; do
361     cat $TMP3FILE | sed "s/$NEWLI/\n/g" > ${contname}${filesfx}.$frmt
362
363     rm -f $TMPFILE $TMP2FILE $TMP3FILE $TMP4FILE
364
365     IFS="$oldifs"
366
367     return 0
368 }
369
370 #
371 #  MAIN
372 #
373
374 # maybe parametrizable
375 # tmplname="temptest"
376 tmplname="cv_template"
377 while [ $# ]; do
378     case $1 in
379         -v) verbose="Y"
380             ;;
381         -d) debug="Y"
382             ;;
383         -h) usage $0
384             ;;
385         *)  break
386     esac
387     shift
388 done
389 contname="$1"
390
391 rm -f $TMPFILE $TMP2FILE $TMP3FILE $TMP4FILE
392
393 if [ ! -f ${contname}.data ]; then
394     echo "File ${contname}.data not exists"
395     exit 1
396 fi 
397
398 # source the data file from template scope
399 . ${tmplname}.data
400
401 # source the data file from user scope
402 . ${contname}.data
403
404 for frmt in tex htm; do
405     for lng in "" eng; do
406         echo "Format: $frmt  Lang: $lng"
407         populator "$tmplname" "$contname" "$lng" "$frmt"
408     done
409 done
410
411 exit 0