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:
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!
+|}