From ad7a86f1c518215f5eddc32b90bcd39e24192c8b Mon Sep 17 00:00:00 2001 From: nuex Date: Thu, 20 Oct 2011 14:29:30 -0400 Subject: [PATCH] custom configuration support - custom extensions - custom filters - ignore files matching given patterns --- Makefile | 6 +-- bin/zod.template | 92 ++++++++++++++++++++++++++++++++++-- bin/zod_render | 32 ------------- bin/zod_supported_extensions | 8 ---- example/site/helpers.awk | 7 +-- example/site/main.layout | 8 +++- lib/config.awk | 44 +++++++++++++++++ lib/opt_builder.awk | 35 ++++++++++++++ lib/render.awk | 50 +++++++------------- lib/supported_extensions.awk | 22 --------- 10 files changed, 196 insertions(+), 108 deletions(-) mode change 100644 => 100755 bin/zod.template delete mode 100755 bin/zod_render delete mode 100755 bin/zod_supported_extensions create mode 100644 lib/config.awk create mode 100644 lib/opt_builder.awk delete mode 100644 lib/supported_extensions.awk diff --git a/Makefile b/Makefile index 2452c04..ad2f6fa 100644 --- a/Makefile +++ b/Makefile @@ -7,20 +7,20 @@ all: @echo Compiled install: all - @echo Installing zod executables to ${PREFIX}/bin + @echo Installing zod executable to ${PREFIX}/bin @mkdir -p ${PREFIX}/bin @cp bin/zod ${PREFIX}/bin - @cp bin/zod_render ${PREFIX}/bin @echo Installing awk lib files to ${AWKLIB} @mkdir -p ${AWKLIB} @cp lib/render.awk ${AWKLIB} @cp lib/markdown.awk ${AWKLIB} + @cp lib/config.awk ${AWKLIB} + @cp lib/opt_builder.awk ${AWKLIB} @echo Installation Complete uninstall: @echo Uninstalling zod executable @rm ${PREFIX}/bin/zod - @rm ${PREFIX}/bin/zod_render @echo Uninstalling awk lib files @rm -rf ${AWKLIB} @echo Uninstallation Complete diff --git a/bin/zod.template b/bin/zod.template old mode 100644 new mode 100755 index 3b94e31..99ee0d1 --- a/bin/zod.template +++ b/bin/zod.template @@ -13,12 +13,94 @@ _zod_error() { exit 1 } +_zod_config() { + cat - "$cfg" < "$destination/$page" +} + +_zod_copy() { + file="$1" + destination="$(_zod_destination "$file")" + cp "$file" "$destination" +} + +_zod_exec() { + phase="$@" + set -- "$proj" -type f + for instruction in $(_zod_find_opt_builder "$phase" "$cfg"); do + inst=$(echo $instruction | sed 's/"//g') + case $inst in + or ) set -- "$@" -o;; + not ) set -- "$@" !;; + * ) set -- "$@" -name "$inst";; + esac + done + find "$@" | while read -r file; do + case "$phase" in + render ) _zod_render "$file";; + copy ) _zod_copy "$file";; + esac + done +} + [ "$#" -ne 2 ] && { echo "usage: zod projectdir targetdir"; exit; } [ ! -d "$proj" ] && _zod_error "project directory does not exist" [ ! -d "$target" ] && _zod_error "target directory does not exist" -find "$proj" -type f \ - ! -name "*.layout" \ - ! -name "*.meta" \ - ! -name "helpers.awk" \ - -exec zod_render "$zod_lib" "$proj" "$target" {} \; +[ -f "$proj/.zod/config" ] && cfg="$proj/.zod/config" + +_zod_exec "render" +_zod_exec "copy" diff --git a/bin/zod_render b/bin/zod_render deleted file mode 100755 index 1b2d4e2..0000000 --- a/bin/zod_render +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# render a zodiac page -# zod_render zodlibdir projdir targetdir md_builtin [files] - -zod_lib="$1" -proj="$2" -target="$3" -md_builtin="$4" -f="$5" - -# source zod sh functions -. $zod_lib/zod_functions - -ext=${f##*.} -meta=${f%.$ext}.meta - -set -- -f "$zod_lib/render.awk" -[ -f "$proj/helpers.awk" ] && set -- "$@" -f "$proj/helpers.awk" -set -- "$@" -v markdown_filter_cmd="$md_builtin" -[ -f "$proj/global.meta" ] && set -- "$@" $proj/global.meta -[ -f "$meta" ] && set -- "$@" $meta -set -- "$@" "$f" - -find "$proj" -type f -name "*.partial" -o -name "*.layout" -while read -r part; do - set -- "$@" "$part" -done - -page=${f##*/} -page=${page%.$ext}.html -__zod_destination "$proj" "$target" "$f" -awk "$@" > "$destination/$page" diff --git a/bin/zod_supported_extensions b/bin/zod_supported_extensions deleted file mode 100755 index 14f910e..0000000 --- a/bin/zod_supported_extensions +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# return a list of all supported file extensions - -zod_lib="$1" -filter_opts="$2" - -awk -f "$zod_lib/supported_extensions.awk" "$filter_opts" diff --git a/example/site/helpers.awk b/example/site/helpers.awk index 271935c..90d6f1a 100644 --- a/example/site/helpers.awk +++ b/example/site/helpers.awk @@ -5,9 +5,10 @@ function load_helpers() { } function page_title( title) { - if ("title" in data) { - return data["title"] " - " data["site_title"] + if (data["title"]) { + title = data["title"] " - " data["site_title"] } else { - return data["site_title"] + title = data["site_title"] } + return title } diff --git a/example/site/main.layout b/example/site/main.layout index e6164b0..fe5b972 100644 --- a/example/site/main.layout +++ b/example/site/main.layout @@ -6,10 +6,14 @@ {{page_title}} - {{>header}} +
+

{{site_title}}

+
{{{yield}}}
- {{>footer}} + diff --git a/lib/config.awk b/lib/config.awk new file mode 100644 index 0000000..9e6b5aa --- /dev/null +++ b/lib/config.awk @@ -0,0 +1,44 @@ +# +# Parse zodiac config +# + +# Ignore comments and empty lines +action == "config" && (NF == 0 || /^;/) { + next +} + +# Get the current section +action == "config" && (/^\[/ && match($0, /\[([[:alnum:]_]).*\]/)) { + section = substr($0, (RSTART + 1), (RLENGTH - 2)) + next +} + +# Get filters in the parse section +action == "config" && section == "parse" { + n = split($0, exts, ",") + for (i in exts) { + ext = exts[i] + gsub(/ /, "", ext) + filter[ext] = "none" + } + next +} + +# Get filters in the parse_convert section +action == "config" && section == "parse_convert" && (NF > 1) { + ext_list = $1 + cmd = $2 + n = split(ext_list, exts, ",") + for (i in exts) { + ext = exts[i] + gsub(/ /, "", ext) + filter[ext] = cmd + } + next +} + +# Get ignore patterns +action == "config" && section == "ignore" { + ignore[ignore_count++] = $0 + next +} diff --git a/lib/opt_builder.awk b/lib/opt_builder.awk new file mode 100644 index 0000000..ca075a7 --- /dev/null +++ b/lib/opt_builder.awk @@ -0,0 +1,35 @@ +# +# Build find options +# + +BEGIN { + section = "none" + action = "config" +} + +END { + for (ext in filter) { + exts[ext_count++] = "\"" "*." ext "\"" + } + for (i = 0; i < length(ignore); i++) { + instructions[inst_count++] = "not" + instructions[inst_count++] = "\"" ignore[i] "\"" + } + if (phase == "render") { + instructions[inst_count++] = exts[0] + for (i = 1; i < length(exts); i++) { + instructions[inst_count++] = "or" + instructions[inst_count++] = exts[i] + } + } else if (phase == "copy") { + for (i = 0; i < length(exts); i++) { + instructions[inst_count++] = "not" + instructions[inst_count++] = exts[i] + } + } + # print all instructions + for (i = 0; i < length(instructions); i++) { + instruction = instruction " " instructions[i] + } + print instruction +} diff --git a/lib/render.awk b/lib/render.awk index b208aa8..554af13 100644 --- a/lib/render.awk +++ b/lib/render.awk @@ -1,47 +1,30 @@ -# render.awk - Awk-based templating +# +# Render a zodiac page +# BEGIN { action = "none" ext = "none" - main_content_type = "_main" + main = "_main" helpers_loaded = "no" layout = "" - filter_cmds["htm"] = "none" - filter_cmds["html"] = "none" - filter_cmds["md"] = markdown_filter_cmd } { split(FILENAME, parts, ".") ext = parts[length(parts)] - if (ext == "config") { + if ((FILENAME == "config") || (FILENAME == "-")) { action = "config" } else if (ext == "meta") { action = "meta" } else if (ext == "layout") { action = "layout" } else { - # not a known extension, assuming this line - # is from a page - content_extension = ext action = "page" + filter_ext = ext } } -# Process lines from config -# Also ignore comments and empty lines -action == "config" && (NF > 0) && (!/^;.*/) { - split($0, filter_kv, ": ") - split(filter_kv[1], filter_extensions, ",") - filter_cmd = filter_kv[2] - - for (i = 1; i <= length(filter_extensions); i++) { - filter_cmds[filter_extensions[i]] = filter_cmd - } - - next -} - # Process lines from meta files action == "meta" { split($0, kv, ": ") @@ -58,14 +41,14 @@ action != "meta" && helpers_loaded == "no" && helpers == "yes" { # Process lines from the page action == "page" { - if (!contents[main_content_type]) { - contents[main_content_type] = bind_data($0) + if (!contents[main]) { + contents[main] = bind_data($0) # save the extension for this content type # to find the appropriate filter to render it - content_extensions[main_content_type] = ext + filter_exts[main] = ext } else { - contents[main_content_type] = contents[main_content_type] "\n" bind_data($0) + contents[main] = contents[main] "\n" bind_data($0) } next } @@ -75,7 +58,7 @@ action == "layout" { # replace yield with rendered content if (match($0, /{{{yield}}}/)) { - sub(/{{{yield}}}/, render_content(main_content_type)) + sub(/{{{yield}}}/, render_content(main)) } if (layout == "") { @@ -89,14 +72,14 @@ END { if (layout != "") { print layout } else { - print render_content(main_content_type) + print render_content(main) } } function bind_data(txt, tag, key) { if (match(txt, /{{([^}]*)}}/)) { tag = substr(txt, RSTART, RLENGTH) - match(tag, /(\w|[?]).*[^}]/) + match(tag, /([[:alnum:]_]|[?]).*[^}]/) key = substr(tag, RSTART, RLENGTH) gsub(tag, data[key], txt) return bind_data(txt, data) @@ -105,14 +88,14 @@ function bind_data(txt, tag, key) { } } -function render_content(type, ext_key, content_extension, filter_cmd, txt) { +function render_content(type, ext_key, filter_ext, filter_cmd, txt) { ext_key = type "_ext" # Get the extension of the content type - content_extension = content_extensions[type] + filter_ext = filter_exts[type] # Get the appropriate filter command for this extension - filter_cmd = filter_cmds[content_extension] + filter_cmd = filter[filter_ext] # Get the text of the content for the given type txt = contents[type] @@ -125,6 +108,7 @@ function render_content(type, ext_key, content_extension, filter_cmd, txt) { } function run_filter(cmd, txt, rand_date, tmpfile, rendered_txt, date_cmd, markdown_cmd, line) { + # TODO use mktemp instead date_cmd = "date +%Y%m%d%H%M%S" date_cmd | getline rand_date close(date_cmd) diff --git a/lib/supported_extensions.awk b/lib/supported_extensions.awk deleted file mode 100644 index 04bedbe..0000000 --- a/lib/supported_extensions.awk +++ /dev/null @@ -1,22 +0,0 @@ -BEGIN { - extensions="md html" -} - -# Process lines from config -# Also ignore comments and empty lines -(NF > 0) && (!/^;.*/) { - split($0, filter_kv, ": ") - split(filter_kv[1], filter_extensions, ",") - - for (i = 1; i <= length(filter_extensions); i++) { - ext = filter_extensions[i] - if (!match(extensions, ext)) { - extensions = extensions " " ext - } - } - next -} - -END { - print extensions -}