aat

git mirror of https://ccx.te2000.cz/bzr/aat
git clone https://ccx.te2000.cz/git/aat
Log | Files | Refs | README

commit dafa82ec9d25596ea28471a5ab0494cc334883e5
parent 774792d522f9347076cf7064311f462461160093
Author: Jan Pobrislo <ccx@webprojekty.cz>
Date:   Mon, 16 Sep 2013 23:20:41 +0200

extended to support syntax in hello2.aat
Diffstat:
Mbin/aat.awk | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mbin/aat_macros.sed | 7+++++++
Mdata.awk | 26++++++++++++++------------
Ahello3.aat | 9+++++++++
4 files changed, 96 insertions(+), 14 deletions(-)

diff --git a/bin/aat.awk b/bin/aat.awk @@ -9,6 +9,9 @@ BEGIN { tok_type = T_TEXT } +# Append 'content' to array of tokens. Token type is taken from current value +# of tok_type. It concatenates sequence of tokens of same type, unless +# tok_finished is set. function token(content) { if(!content) return # concatenate tokens of same type if the previous one doesn't end in newline @@ -23,8 +26,67 @@ function token(content) { tok_n, type_names[tok_type], tok_contents[tok_n] >"/dev/stderr" } -{ - line = $0 +function call_macro(name, args) { + # Macro to recursively parse another template + if(name == "include"){ + while(getline <args) { + parse_line($0) + } + } + + # Macro to insert another file as verbatim code + else if(name == "awk"){ + filename=substr(line, 6) + tok_type=T_AWK + while(getline <args) { + token($0 "\n") + } + } + + # Macro to insert another file as text + else if(name == "text"){ + filename=substr(line, 7) + while(getline <args) { + token($0 "\n") + } + } + + # Leave the @ there for postprocessing with sed + else { + tok_type=T_AWK + token("@" line "\n") + } +} + +function parse_line(line) { + # Handle linewise syntax + if(tok_type == T_TEXT) { + # if line starts with @@ or || it is actually an escape for having text + # start with single @ or | respectively + if(/^\(@@|\|\|\)/){ + line=substr(line, 2) + } + # Lines starting with @ are macros. Some are handled in call_macro, + # others currently by passing it through as awk code and postprocessing + # with sed. + else if(/^@/){ + match(substr(line, 2), "[^ \t]+") + call_macro( \ + substr(line, 1+RSTART, RLENGTH), \ + substr(line, 2+RSTART+RLENGTH) \ + ) + tok_type=T_TEXT + return + } + # Lines starting with | are considered verbatim awk code + else if(/^\|/) { + tok_type=T_AWK + token(substr(line, 2) "\n") + tok_type=T_TEXT + return + } + } + # Handle text, with interleaved blocks for code and expressions while(length(line)) { if(DEBUG) printf "%d: \"%s\"\n", tok_n, line >"/dev/stderr" eat_nl = 0 @@ -94,6 +156,8 @@ function token(content) { } } +{ parse_line($0) } + END { nl = 1 # are we on new line? for(tok_n=1; tok_types[tok_n]; tok_n++) { diff --git a/bin/aat_macros.sed b/bin/aat_macros.sed @@ -5,3 +5,10 @@ s/^[[:space:]]*IF[[:space:]]\+\(.\+\)$/if(\1) {\n/ s/^[[:space:]]*ELIF[[:space:]]\+\(.\+\)$/} else if(\1) {\n/ s/^[[:space:]]*ELSE[[:space:]]*$/} else {/ s/^[[:space:]]*ENDIF[[:space:]]*$/}/ + +s/^[[:space:]]*@for[[:space:]]\+\([[:alnum:]]\+\)[[:space:]]\+in[[:space:]]\+\(.\+\)$/for(_loop_\1=loop_start("\2", "\1_"); loop_iter(_loop_\1);) {/ +s/^[[:space:]]*@endfor[[:space:]]*$/} loop_end()/ +s/^[[:space:]]*@if[[:space:]]\+\(.\+\)$/if(\1) {\n/ +s/^[[:space:]]*@elif[[:space:]]\+\(.\+\)$/} else if(\1) {\n/ +s/^[[:space:]]*@else[[:space:]]*$/} else {/ +s/^[[:space:]]*@endif[[:space:]]*$/}/ diff --git a/data.awk b/data.awk @@ -40,7 +40,7 @@ state == 1 { m = match($0, ident_re) varname = substr($0, m, RLENGTH) V[varname] = substr($0, m+1+RLENGTH) - printf "got scalar: %s ⇒ %s (%d)\n", varname, V[varname], m + if(DEBUG) printf "got scalar: %s ⇒ %s (%d)\n", varname, V[varname], m next } @@ -88,17 +88,19 @@ function get(varname, i, n, names, values) { return V[varname] } -# just testing it out +# for testing it out, set TEST=1 on commandline END { - for(key in V) { - printf("%s⇒\t→%s←\n", key, V[key]) - } - print "--------------------" - print get("foo") - for(d1=loop_start("spam"); loop_iter(d1);) { - print get("name") "-" get("value") - for(d2=loop_start("spam", "i_"); loop_iter(d2);) { - print get("eggs") + get("i_eggs") + if(TEST) { + for(key in V) { + printf("%s⇒\t→%s←\n", key, V[key]) + } + print "--------------------" + print get("foo") + for(d1=loop_start("spam"); loop_iter(d1);) { + print get("name") "-" get("value") + for(d2=loop_start("spam", "i_"); loop_iter(d2);) { + print get("eggs") + get("i_eggs") + } loop_end() } loop_end() - } loop_end() + } } diff --git a/hello3.aat b/hello3.aat @@ -0,0 +1,9 @@ +|!/bin/awk -f +@awk data.awk +|END { +@ for name in names +Hello {{get("name_v")}}{{get("name__last") ? "!" : ","}} +@ endfor + +Welcome to the world of {{toupper("awk")}} templating! +|}