zodiac/lib/render.awk

187 lines
4.0 KiB
Awk
Raw Normal View History

#
# Render a zodiac page
#
2011-09-22 17:28:24 +02:00
BEGIN {
action = "none"
2011-10-08 02:28:42 +02:00
ext = "none"
main = "_main"
2011-09-22 17:28:24 +02:00
helpers_loaded = "no"
layout = ""
}
{
2011-10-04 23:34:34 +02:00
split(FILENAME, parts, ".")
ext = parts[length(parts)]
if (FILENAME == "-") {
2011-10-08 02:28:42 +02:00
action = "config"
} else if (ext == "meta") {
action = "meta"
} else if (ext == "layout") {
action = "layout"
} else {
action = "page"
filter_ext = ext
2011-10-08 02:28:42 +02:00
}
}
2011-09-22 17:28:24 +02:00
# Process lines from meta files
action == "meta" {
split($0, kv, ": ")
data[kv[1]] = kv[2]
next
}
# Done processing meta
# Since data is loaded now, load the helpers
action != "meta" && action != "config" && helpers_loaded == "no" && helpers == "yes" {
2011-09-22 17:28:24 +02:00
load_helpers()
helpers_loaded = "yes"
}
# Process lines from the page
action == "page" {
if (!contents[main]) {
contents[main] = bind_data($0)
2011-10-08 02:28:42 +02:00
# save the extension for this content type
# to find the appropriate filter to render it
filter_exts[main] = ext
2011-09-22 17:28:24 +02:00
} else {
contents[main] = contents[main] "\n" bind_data($0)
2011-09-22 17:28:24 +02:00
}
next
}
# Process lines from the layout
action == "layout" {
# replace yield with rendered content
if (match($0, /{{{yield}}}/)) {
sub(/{{{yield}}}/, escape_special_chars(render_content(main)))
2011-09-22 17:28:24 +02:00
}
if (layout == "") {
layout = bind_data($0)
} else {
layout = layout "\n" bind_data($0)
}
}
END {
if (layout != "") {
print layout
} else {
print render_content(main)
2011-09-22 17:28:24 +02:00
}
}
function bind_data(txt, tag, key, partial_txt) {
2013-11-15 10:18:29 +01:00
if (match(txt, /{{> ([^}]*)}}/)) {
2011-09-22 17:28:24 +02:00
tag = substr(txt, RSTART, RLENGTH)
match(tag, /([[:alnum:]_]|[?]).*[^}]/)
2011-09-22 17:28:24 +02:00
key = substr(tag, RSTART, RLENGTH)
2013-11-15 10:18:29 +01:00
partial_txt = load_partial(key)
gsub(tag, escape_special_chars(partial_txt), txt)
return bind_data(txt)
} else if (match(txt, /{{([^}]*)}}/)) {
tag = substr(txt, RSTART, RLENGTH)
match(tag, /([[:alnum:]_]|[?]).*[^}]/)
key = substr(tag, RSTART, RLENGTH)
gsub(tag, escape_special_chars(data[key]), txt)
return bind_data(txt)
2011-09-22 17:28:24 +02:00
} else {
return txt
}
}
2013-11-15 10:18:29 +01:00
# Returns the text from a partial
#
# It will load the partial from the cache if possible.
# Otherwise it will open the partial file and load each
# line.
#
# Nothing is returned if the file doesn't exist.
function load_partial(key, partial, pwd, partial_file, partial_txt, line) {
2013-11-15 10:18:29 +01:00
partial = partials[key]
if (partial) {
return partial
} else {
pwd = ENVIRON["PWD"]
partial_file = pwd "/" proj "/" key ".partial"
if (is_file(partial_file)) {
while((getline line < partial_file) > 0) {
if (partial_txt) {
partial_txt = partial_txt "\n" line
} else {
partial_txt = line
}
}
close(partial_file)
partials[key] = partial_txt
return partial_txt
}
}
}
# Check if a file exists
function is_file(file, check, response) {
2013-11-15 10:18:29 +01:00
check = "[ -f " file " ] && echo yes"
check | getline response
close(check)
if (response == "yes") {
return "yes"
}
}
function render_content(type, ext_key, filter_ext, filter_cmd, txt) {
2011-10-08 02:28:42 +02:00
ext_key = type "_ext"
# Get the extension of the content type
filter_ext = filter_exts[type]
2011-10-08 02:28:42 +02:00
# Get the appropriate filter command for this extension
filter_cmd = filter[filter_ext]
2011-10-08 02:28:42 +02:00
# Get the text of the content for the given type
txt = contents[type]
if (filter_cmd != "none") {
return run_filter(filter_cmd, txt)
} else {
return txt
}
2011-09-22 17:28:24 +02:00
}
2011-10-24 16:37:08 +02:00
function run_filter(cmd, txt, rand_date, tmpfile, rendered_txt, date_cmd, filter_cmd, line) {
2011-09-22 17:28:24 +02:00
date_cmd = "date +%Y%m%d%H%M%S"
date_cmd | getline rand_date
close(date_cmd)
tmpfile = "/tmp/awk_render" rand_date
2011-10-08 02:28:42 +02:00
filter_cmd = cmd " > " tmpfile
2011-09-22 17:28:24 +02:00
2011-10-24 16:37:08 +02:00
# pipe content to filter command
2011-10-08 02:28:42 +02:00
print txt | filter_cmd
close(filter_cmd)
2011-09-22 17:28:24 +02:00
# pull out the filtered page
while((getline line < tmpfile) > 0) {
rendered_txt = rendered_txt "\n" line
}
close(tmpfile)
system("rm " tmpfile)
return rendered_txt
}
2011-12-02 16:28:23 +01:00
# Prevent awk from replacing ampersands with matched text
function escape_special_chars( txt) {
gsub(/&/, "\\\\&", txt)
return txt
}