#!/bin/awk -f
#!/opt/busybox/awk -f
-function macro(call, LOCAL, line, files, n, exec) {
- "cd " ENVIRON["MD_MACROS"] "; printf '%s/' *" |getline line;
- split(line, files, "/");
- for (n in files) { files[files[n]] = ""; delete files[n]; }
- delete files[""];
+# Copyright 2022 Paul Hänsch
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- split(call, exec);
+function sh_escape(arg){
+ return "'" gensub(/'/, "'\"'\"'", "g", arg) "'";
+}
+
+function argsplit(line, args, LOCAL, c, n, ctx) {
+ ctx="space"; n=0;
+
+ while ( length(line) > 0 ) {
+ c = substr(line, 1, 1);
+ line = substr(line, 2);
+ if (ctx == "space" )
+ if (c ~ /[ \t]/) ctx = "space";
+ else if (c ~ /\\/) { n++; ctx = "escbare"; }
+ else if (c ~ /"/) { n++; ctx = "dquot"; }
+ else if (c ~ /'/) { n++; ctx = "squot"; }
+ else { n++; args[n] = c; ctx = "bare"; }
+ else if (ctx == "bare")
+ if (c ~ /[ \t]/) ctx = "space";
+ else if (c ~ /\\/) ctx = "escbare";
+ else if (c ~ /"/) ctx = "dquot";
+ else if (c ~ /'/) ctx = "squot";
+ else args[n] = args[n] c;
+ else if (ctx == "dquot")
+ if (c ~ /"/) ctx = "bare";
+ else if (c ~ /\\/) ctx = "escdquot";
+ else args[n] = args[n] c;
+ else if (ctx == "squot")
+ if (c ~ /'/) ctx = "bare";
+ else args[n] = args[n] c;
+ else if (ctx == "escbare") {
+ args[n] = args[n] c;
+ ctx = "bare";
+ }
+ else if (ctx == "escdquot") {
+ args[n] = args[n] c;
+ ctx = "dquot";
+ }
+ }
+}
- if (exec[1] in files) {
+function macro(call, LOCAL, line, args) {
+ argsplit(call, args);
+ call="";
+
+ for (n = 1; n in args; n++) call = call sh_escape(args[n]) " ";
+
+ if (args[1] in MACROS) {
+ oldRS=RS; oldORS=ORS;
RS=""; ORS=""; line="";
- # TODO: proper shell-exec function with argument array
- "printf '%s' " line " | " ENVIRON["MD_MACROS"] "/" call | getline line;
+ "printf '%s' " sh_escape(file) " | " sh_escape(ENVIRON["MD_MACROS"]) "/" call | getline line;
+ RS=oldRS; ORS=oldORS;
return line;
} else {
return HTML("<<" call ">>");
}
BEGIN {
- if (ENVIRON["MD_MACROS"]) { AllowMacros = "true"; }
+ if (ENVIRON["MD_MACROS"]) {
+ AllowMacros = "true";
+ "cd " sh_escape(ENVIRON["MD_MACROS"]) "; printf '%s/' *" |getline macro_list;
+ split(macro_list, MACROS, "/");
+ for (n in MACROS) { MACROS[MACROS[n]] = ""; delete MACROS[n]; }
+ delete MACROS[""];
+ }
}