#!/usr/bin/awk -f # # Copyright (C) 2001-2005 by Oliver Fromme # # BSD-style copyright and standard disclaimer apply. # # This is a small tool that enables embedding awk in HTML. # To use it, put these lines in your apache configuration # (or in a .htaccess file): # # Action hawk-parsed /URL/path/to/hawk.cgi # AddHandler hawk-parsed .hawk # AddType text/html .hawk # # The above options have to be in effect for all directories # that contain .hawk files. The hawk.cgi CGI script should # be placed in a directory where CGI execution has been # enabled, for example using these configuration lines: # # Options +ExecCGI # Addhandler cgi-script .cgi # # If it doesn't work, check all pathnames and make sure # that executing CGIs has been enabled in the global config. # Check the server's error log file for details. # Note that hawk itself is written in awk. It requires an # awk version that supports ENVIRON, such as gnu awk or # Solaris nawk. # # If you don't want to generate the HTML output dynamically, # you can also re-built .html files from .hawk files if # neccessary, and then serve those .html files statically. # You can easily write a Makefile to do that job, with # rules like this: # # foobar.html: foobar.hawk # hawk < $? > $@ # # The actual awk commands are embedded using ``<%...%>'', # with a few specials: # - ``<%?'' is a shortcut for ``<%printf"%s",''. So, to # print a variable, you can simply say ``<%?foo%>''. # - ``<%!'' causes this embedded section (up to the # closing ``%>'') to be put at the outmost awk level. # This is necessary for awk function declarations. # (Actually, it is exactly the same as ``<%}...BEGIN{%>''.) # - ``<%#filename%>'' includes the specified file. # The included file will be parsed as hawk input as well, # and you can even nest them. This is useful to load # function libraries and predefined variables. If the # filename is not absolute (i.e. the first character is # not a "/"), then it is relative to the current directory # (when hawk is used as a filter) or to the directory # containing the .hawk input file (when used as a CGI from # apache). # You can change all of these character sequences below. # # All awk variables beginning with two underscores are # reserved for internal use. The following are predefined: # __INPUTFILE well, you guess it -- the .hawk input file # (/dev/stdin if hawk doesn't run as CGI) # __INPUTDIR the directory in which __INPUTFILE resides # ($CWD if hawk doesn't run as CGI). # __MYURL the complete URL of the .hawk file # (undefined if hawk doesn't run as CGI). # # To debug your .hawk pages, you can also simply pipe them # into this script (on stdin). The result will be printed # on stdout. # # Simple example (all whitespace within <%...%> is optional): # # # <% title = "*** Hello World! ***"; %> # <%?title%> # #

<%?title%>

#

<% # for (i = length(title); i > 0; i--) # printf "%c", substr(title, i, 1); # %>

#

# It's now <%system("date")%>, and I'm # running on a nice <%system("uname -rs")%>. #

#

# <% for (i = 1; i <= 10; i++) print "moo"; %> #

# # BEGIN { awk = "/usr/bin/awk -f -"; # awk = "/bin/cat"; # for debugging intro = "<%"; extro = "%>"; incld = "<%#"; declr = "<%!"; inprt = "<%?"; inexp = "<%printf\"%s\","; inawk = 0; outer = 0; print "BEGIN{" | awk; __ARGC = ARGC; for (i = 0; i < ARGC; i++) __ARGV[i] = ARGV[i]; ARGC = 1; if (inputfile = ENVIRON["PATH_TRANSLATED"]) { # We're run from Apache as "action" handler ... apache = 1; if (!(myurl = ENVIRON["REDIRECT_URL"])) myurl = ENVIRON["REQUEST_URI"]; port = ENVIRON["SERVER_PORT"]; if (port && port != "80") port = ":" port; else port = ""; myurl = "http://" ENVIRON["SERVER_NAME"] port myurl; if (inputfile ~ /\.hawk\/$/) { myurl = substr(myurl, 1, length(myurl) - 1); print "print \"Status: 301 Moved Permanently\";" | awk; print "print \"Location: " myurl "\";" | awk; print "print \"Content-Type: text/plain\\n\";" | awk; print "print \"301 Moved Permanently\";" | awk; print "print \"Please use the following URL:\";" | awk; print "print \"" myurl "\";" | awk; exit 1; } if ((getline cmd 0) parseline($0); t = substr(t, p + length(extro)); continue; } if (p = index(t, declr)) { t = substr(t, 1, p - 1) intro "\n}\n" \ substr(t, p + length(inprt)); outer = 1; } if (p = index(t, inprt)) t = substr(t, 1, p - 1) inexp \ substr(t, p + length(inprt)); if (!(p = index(t, intro))) { printf "print \"%s\";\n", quote(t) | awk; return; } if (q = quote(substr(t, 1, p - 1))) printf "printf \"%%s\", \"%s\";", q | awk; t = substr(t, p + length(intro)); } inawk = !inawk; } } { parseline($0); } #--