4 # Copyright 2022 - 2023 Paul Hänsch
6 # Permission to use, copy, modify, and/or distribute this software for any
7 # purpose with or without fee is hereby granted, provided that the above
8 # copyright notice and this permission notice appear in all copies.
10 # THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
16 # IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 function sh_escape(arg){
19 return "'" gensub(/'/, "'\"'\"'", "g", arg) "'";
22 function argsplit(line, args, LOCAL, c, n, ctx) {
25 while ( length(line) > 0 ) {
26 c = substr(line, 1, 1);
27 line = substr(line, 2);
29 if (c ~ /[ \t]/) ctx = "space";
30 else if (c ~ /\\/) { n++; ctx = "escbare"; }
31 else if (c ~ /"/) { n++; ctx = "dquot"; }
32 else if (c ~ /'/) { n++; ctx = "squot"; }
33 else { n++; args[n] = c; ctx = "bare"; }
34 else if (ctx == "bare")
35 if (c ~ /[ \t]/) ctx = "space";
36 else if (c ~ /\\/) ctx = "escbare";
37 else if (c ~ /"/) ctx = "dquot";
38 else if (c ~ /'/) ctx = "squot";
39 else args[n] = args[n] c;
40 else if (ctx == "dquot")
41 if (c ~ /"/) ctx = "bare";
42 else if (c ~ /\\/) ctx = "escdquot";
43 else args[n] = args[n] c;
44 else if (ctx == "squot")
45 if (c ~ /'/) ctx = "bare";
46 else args[n] = args[n] c;
47 else if (ctx == "escbare") {
51 else if (ctx == "escdquot") {
58 function HTML ( text ) {
59 gsub( /&/, "\\&", text );
60 gsub( /</, "\\<", text );
61 gsub( />/, "\\>", text );
62 gsub( /"/, "\\"", text );
63 gsub( /'/, "\\'", text );
64 gsub( /\\/, "\\\", text );
68 function macro(call, LOCAL, line, args) {
72 for (n = 1; n in args; n++) call = call sh_escape(args[n]) " ";
74 if (args[1] in MACROS) {
75 printf "%s", file | sh_escape(ENVIRON["MD_MACROS"]) "/" call;
76 close(sh_escape(ENVIRON["MD_MACROS"]) "/" call);
78 printf "%s", HTML("<<" call ">>");
82 function unhtml ( text ) {
83 gsub( /</, "<", text);
84 gsub( />/, ">", text);
85 gsub( /"/, "\"", text);
86 gsub( /'/, "'", text);
87 gsub( /\/, "\\", text);
88 gsub( /&/, "\\&", text);
92 function findmacro(line, LOCAL, st, len, pre, post) {
93 if ( match(line, /<code class="macro">[^\n]*<\/code>/) ) {
94 match(line, /<code class="macro">/); pre = substr( line, 1, RSTART - 1 );
95 line = substr( line, RSTART + RLENGTH);
96 match( line, /<\/code>/); post = substr(line, RSTART + RLENGTH);
97 line = substr(line, 1, RSTART - 1);
99 printf "%s", pre; macro( unhtml(line) ); findmacro( post );
106 if (ENVIRON["MD_MACROS"]) {
107 AllowMacros = "true";
108 "cd " sh_escape(ENVIRON["MD_MACROS"]) "; printf '%s/' *" |getline macro_list;
109 split(macro_list, MACROS, "/");
110 for (n in MACROS) { MACROS[MACROS[n]] = ""; delete MACROS[n]; }
113 file = ""; while ( getline ) { file = file $0 "\n"; }