about summary refs log tree commit diff stats
path: root/et
blob: 19a8833813b92536fb80ec554d287e519640059e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/bin/sh
{ excitable="text" "exec" "awk" "-f" "$0" "$@"; } # -*- awk -*-
# usage: et <file> | sh

BEGIN {
	# Tuneables
	postproc = postproc ? postproc : "shexpand"
	bodyfunc = bodyfunc ? bodyfunc : "body"
	# Globals
	wrpfx = ";:"; shxpfx = "!shx!"; def_docend = "---end---"
	pretext = bodyfunc"(){\n"; posttext = "}\n"bodyfunc
	# Ask sed to do these b/c awk has no capture groups ;_;
	shellfix = "sed -E" \
		" -e 's/`/\\\\`/g'" \
		" -e 's/(^|[^\\$])\\$([^\\$]|$)/\\1\\\\$\\2/g'" \
		" -e 's/(^|[^\\$])\\$(\\$+)([^\\$]|$)/\\1\\2\\3/g'"
	shxwrap = " -e 's/^/"wrpfx"/'"
	htmlfix = "sed -E" \
		" -e 's#([^\\\\]|^)&#\\1\\&amp;#g'" \
		" -e 's#([^\\\\]|^)<#\\1\\&lt;#g'" \
		" -e 's#([^\\\\]|^)>#\\1\\&gt;#g'" \
		" -e 's#\\\\([&<>])#\\1#g'"
	true = 1 ; false = 0
	print "### excitable text ###"
	print "wrap()(sed \"s/^/$1/\");unwrap()(sed \"s/^$1//\")"
	print "shexpand()(eval"\
		" \"$(:;(echo 'cat<<.';sed 's/^/"shxpfx"/';echo .)"\
		"|unwrap "shxpfx")\")"
	print "shellfix()(" shellfix ")\nhtmlfix()(" htmlfix ")"
	print "postproc=" postproc
}

end[endn] && $0 == end[endn] {
	par = par "\n" end[endn--] "\n" ")"
	printpar()
	subdocp = false
	next
}

/\\$/ {
	getline nl
	sub(/\\$/,"")
	$0 = $0 " " nl
}

/^\.\.\./ {
	printpar()
	docp = !docp
	docend = $2 ? $2 : def_docend
	if (docp) print pretext "unwrap '" wrpfx "'" \
			  "<<'" docend "'|$postproc"
	else end_text()
	next
}

/^\.\./ && docp {
	subdocp = true
	end[++endn] = (match($0,"<<") ? substr($0,RSTART+RLENGTH) : "..")
	command = substr($0, 3, RSTART ? RSTART - 2 : length)
	$0 = "$$(" (command ? command : "cat") "<<" end[endn]
}

/^\./ && docp {
	specialp = 2
	gsub(/"/,"\\\\&")
	ln = "$$(" substr($1, 2)
	for (f=2;f<=NF;f++) ln = ln " \"" $f "\""
	ln = ln ")"
	$0 = ln
}

/^$/ {
	if (!par) next
	printpar()
}

{ par = par (par?"\n":"") $0 }
{ if (--specialp < 0) specialp = 0 }

END {
	if (par) printpar()
	if (docp) end_text()
}

function end_text() {
	print docend "\n" posttext
}

function printpar() {
	specialp = specialp || (match(par, /^[ 	]*</))
	if (docp) {
		if (!subdocp && !specialp) par = "<p>" par "</p>"
		shx = shellfix shxwrap
		print par | shx
		close(shx)
	} else print par
	par = ""
}