about summary refs log tree commit diff stats
path: root/subtext.awk
diff options
context:
space:
mode:
Diffstat (limited to 'subtext.awk')
-rw-r--r--subtext.awk81
1 files changed, 65 insertions, 16 deletions
diff --git a/subtext.awk b/subtext.awk index 09ec882..07dfb76 100644 --- a/subtext.awk +++ b/subtext.awk
@@ -9,7 +9,8 @@
9BEGIN { 9BEGIN {
10 ## Tuneables 10 ## Tuneables
11 dryrun = dryrun ? dryrun : 0 11 dryrun = dryrun ? dryrun : 0
12 sopath = sopath ? sopath : ".:" ENVIRON["HOME"] "/.subtext" 12 sopath = sopath ? sopath : "."
13 sofile = sofile ? sofile : ""
13 shxend = shxend ? shxend : "%%end" 14 shxend = shxend ? shxend : "%%end"
14 ## Shellfix: escape ` and $ in input 15 ## Shellfix: escape ` and $ in input
15 # Ask sed to do these b/c awk has no capture groups ;_; 16 # Ask sed to do these b/c awk has no capture groups ;_;
@@ -25,34 +26,60 @@ BEGIN {
25 $0 = $0 " " nl 26 $0 = $0 " " nl
26} 27}
27 28
28/^#so/ { # source a file 29### AWK layer
30
31/^%so/ { # source a file
29 pushpar() 32 pushpar()
30 source($2) 33 source($2)
31 next 34 next
32} 35}
33 36
37/^%/ { next } # comments
38
39### Shell layer
40
34/^#/ { # head lines 41/^#/ { # head lines
35 sub(/^#+[ ]*/,"") 42 sub(/^#+[ ]*/,"")
36 head = head (head?"\n":"") $0 43 head = head (head?"\n":"") $0
37 next 44 next
38} 45}
39 46
47### Text layer
48
49end[endn] && $0 == end[endn] {
50 par = par "\n" end[endn--] "\n)"
51 next
52}
53
40/^\.\./ { # block 54/^\.\./ { # block
41 body = body (body?"\n":"") \ 55 if (match($0, /[ ]*<<[ ]*/))
42 "$$(unquote + << .." \ 56 end[++endn] = substr($0, RSTART+RLENGTH)
43 (length>2 ? " | " substr($1,3) " " shquote(2) : "") \ 57 else
44 slurp("..") \ 58 end[++endn] = ".."
45 "..\n)" 59 $0 = substr($0, 3, RSTART?RSTART-3:length)
60 par = par (par?"\n":"") \
61 "$$(" ($1 ? $1 " " shquote(2) : "") " << " end[endn]
62 # par = par (par?"\n":"") \
63 # "$$(unquote + << .." \
64 # (length>2 ? " | " substr($1,3) " " shquote(2) : "") \
65 # slurp("..") \
66 # "..\n)"
46 next 67 next
47} 68}
48 69
70/^\.$/ { next } # continuation line
71
49/^\./ { # line 72/^\./ { # line
50 body = body (body?"\n":"") \ 73 par = par (body?"\n":"") \
51 "$$(" substr($1, 2) " " shquote(2) ")" 74 "$$(" substr($1, 2) " " shquote(2) ")"
52 next 75 next
53} 76}
54 77
55/^$/ { # line break 78/^\\/ { # special line escape
79 $0 = substr($0, 2)
80}
81
82/^$/ { # blank line
56 if (!pushpar()) next 83 if (!pushpar()) next
57} 84}
58 85
@@ -70,25 +97,45 @@ END {
70 printf "shexpand()(eval \"$(echo 'cat<<%s';cat;echo '%s')\")\n", \ 97 printf "shexpand()(eval \"$(echo 'cat<<%s';cat;echo '%s')\")\n", \
71 shxend, shxend 98 shxend, shxend
72 printf "shellfix()(%s)\n", shellfix 99 printf "shellfix()(%s)\n", shellfix
100 print "echo()(printf '%s\\n' \"$@\")"
101 print "handle_input()("\
102 "test -n \"$1\" && printf '%s' \"$*\";"\
103 "if read -r first_line;"\
104 "then echo \"$first_line\";cat;return 0;"\
105 "else echo;return 1;fi)"
73 printf "ST_SOPATH=%s\n", sopath 106 printf "ST_SOPATH=%s\n", sopath
107 if (sofile) source(sofile)
74 print "### head" 108 print "### head"
75 print head 109 print head
76 print "### body" 110 print "### body"
77 print "body(){ unquote : << \\_ | shexpand" 111 print "body(){ unquote : << \\_ | shexpand"
78 pushpar() 112 pushpar()
79 print body | (shellfix " -e 's/^/:/'") 113 shfq = shellfix " -e 's/^/:/'"
80 close(shellfix " -e 's/^/:/'") 114 print body | shfq
115 close(shfq)
81 print "_" 116 print "_"
82 print "}" 117 print "}"
83 if (!dryrun) print "body" 118 if (!dryrun) print "body"
84} 119}
85 120
86function shquote(begin, end, out) { 121function shquote(begin, end, quoted, out) {
87 if (!begin) begin = 1 122 if (!begin) begin = 1
88 if (!end) end = NF 123 if (!end) end = NF
89 for (i=begin; i<=NF; i++) { 124 for (i=begin; i<=NF; i++) {
90 gsub(/"/, "\\\"", $i) 125 if ($i ~ /^\$/) {
91 out = out (out?" ":"") "\"" $i "\"" 126 quoted = 1
127 out = out (out?" ":"") "\"" $i
128 continue
129 }
130 if (($i ~ /\)$/) && quoted) {
131 quoted = 0
132 out = out (out?" ":"") $i "\""
133 continue
134 }
135 if (!quoted) {
136 gsub(/"/, "\\\"", $i)
137 out = out (out?" ":"") "\"" $i "\""
138 } else out = out (out?" ":"") $i
92 } 139 }
93 return out 140 return out
94} 141}
@@ -104,8 +151,9 @@ function slurp(to, out, nl) {
104 151
105function pushpar() { 152function pushpar() {
106 if (!par) return 0 153 if (!par) return 0
107 if (!match(par, /^[ ]*</)) 154 if (!match(par, /^[ \t\n]*[<$]/)) {
108 par = "<p>" par "</p>" 155 par = "$$(p<<../p\n" par "\n../p\n)"
156 }
109 body = body (body?"\n":"") par 157 body = body (body?"\n":"") par
110 par = "" 158 par = ""
111 return 1 159 return 1
@@ -120,6 +168,7 @@ function source(name, found, sp) {
120 found = 1 168 found = 1
121 head = head (head?"\n":"") ln 169 head = head (head?"\n":"") ln
122 } 170 }
171 close(fn)
123 if (found) break 172 if (found) break
124 } 173 }
125 if (!found) { 174 if (!found) {