diff options
| -rw-r--r-- | example.csma | 42 | ||||
| -rw-r--r-- | preproc.awk | 188 |
2 files changed, 230 insertions, 0 deletions
diff --git a/example.csma b/example.csma new file mode 100644 index 0000000..bc78e34 --- /dev/null +++ b/example.csma @@ -0,0 +1,42 @@ +<Colors> { + <Text> { + <FG> { red } + } +} +<Alignment> { + <Center> { + margin-left: auto; + margin-right: auto; + } +} + +#b { + color: <Colors/Text/FG>; +} + +<Object a> { + #a { + abc: a; + color: <Colors/Text/FG>; + margin: 2em; + } + <Object b> +} + +<Object b/Val> + +<Object b> +// This is an example object +{ + .b { + margin: 0.2em; + padding: 0.5em; + } + <Val> { + a { + display: table; + <Alignment/Center> + } + } +} + diff --git a/preproc.awk b/preproc.awk new file mode 100644 index 0000000..50f6660 --- /dev/null +++ b/preproc.awk @@ -0,0 +1,188 @@ +BEGIN { + stage1 = 1 + depth = 0 + nql = 0 +} + +function nameQueuePush(name) { + prename = "" + if (nql > 0) { + name = nameQueue[nql-1] "/" name + } + nameQueue[nql++] = name + nameClose[name] = depth +} + +function nameQueueTop() { + return "<" nameQueue[nql - 1] ">" +} + +function nameQueueGet(ind) { + return "<" nameQueue[ind] ">" +} + +function nameCloseTop() { + return nameClose[nameQueue[nql - 1]] +} + +function nameQueuePop() { + delete nameClose[nameQueue[nql - 1]] + delete nameQueue[--nql] +} + +# Comments +/^\/\/.*$/ { + next +} + +# +# Stage 1 +# Gather definitions +# + +# function printNQ() { +# print "All in nameQueue:" +# for (ind in nameQueue) { +# print "[" ind "] " nameQueue[ind] " | " nameClose[nameQueue[ind]] +# } +# } +# +# stage1 { +# print "" +# print $0 +# print "Depth: " depth +# printNQ() +# } + +stage1 && gotNameOnly { + if ($0 ~ /^[[:blank:]]*$/) { + next + } + + gotNameOnly = 0 + if ($0 ~ /^[[:blank:]]*\{/) { + depth++ + next + } + else { + nameQueuePop() + for (ind in nameQueue) { + macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS nameOnly + } + } +} + +stage1 && /<[^>]*>[[:blank:]]*\{/ { + match($0, /<[^>]*>/) + nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2)) + sub(/^[^{]*{[[:blank:]]*/, "") + depth++ + if ($0 == "") next +} + +# Macro placement +stage1 && /<[^>]*>/ { + for (i = 0; i < length(nameQueue); i++) { + sub(/^ /, "") + } + nameOnly = $0 + match($0, /<[^>]*>/); + nameQueuePush(substr($0, RSTART + 1, RLENGTH - 2)) + gotNameOnly = 1 + next +} + +stage1 && depth >= 1 { + depth += gsub("{", "{") - gsub("}", "}") + + for (i = 0; i < length(nameQueue); i++) { + sub(/^ /, "") + } + + skipORS = 0 + if (depth <= nameCloseTop()) { + sub(/[[:blank:]]*}[[:blank:]]*$/, "") + skipORS = 1 + } + + for (ind in nameQueue) { + if (length(macros[nameQueueGet(ind)]) != 0 && !skipORS) { + macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] ORS + } + macros[nameQueueGet(ind)] = macros[nameQueueGet(ind)] $0 + } + + if (depth <= nameCloseTop()) { + nameQueuePop() + } + next +} + +ENDFILE { + if (stage1) { + stage1 = 0 + stage2 = 1 + depth = 0 + gotNameOnly = 0 + + for (name in macros) { + for (subname in macros) { + gsub(subname, macros[subname], macros[name]) + } + } + } +} + +# +# Stage 2 +# Do placements +# + +stage2 && depth >= 1 { + depth += gsub("{", "{") - gsub("}", "}") + next +} + +stage2 && gotNameOnly { + if ($0 ~ /^[[:blank:]]*$/) { + next + } + + gotNameOnly = 0 + # If is definition + if ($0 ~ /^[[:blank:]]*\{/) { + depth = 1 + macroName = "" + next + } + else { + print macros[macroName] + macroName = "" + } +} + +stage2 && /^[[:blank:]]*<[^>]*>/ { + match($0, /<[^>]*>/) + macroName = substr($0, RSTART, RLENGTH) + if ($0 ~ "{") depth = 1 + else gotNameOnly = 1 + next +} + +stage2 && depth == 0 { + while(match($0, /<[^>]*>/)) { + macroName = substr($0, RSTART, RLENGTH) + sub(macroName, macros[macroName]) + } + print +} + +END { + if (macroName != "") + print macros[macroName] + + # print "All macros:" + # for (macroName in macros) { + # print macroName ORS macros[macroName] + # } +} |
