I mailed the wrong version before... -Alex- ___________________________________________________________________ S. Alexander Jacobson i2x Media 1-212-697-0184 voice 1-212-697-1427 fax
#!/usr/bin/perl #Haskell Embed - Embed Haskell Computations in Your Documents #Copyright (c) 1998 Alex Jacobson All Rights Reserved #This code enables you to embed Haskell computations in your (HTML or XML) #documents. You put in code of the form <hseval haskell-function-call /> #and this code replaces it with the result. #It also removes the initial ">" from lit haskell. #In a cgi context, you put this script in your path and add # #!/usr/bin/perl -S hsembed.pl #to the top of your haskell script. #If you want to output PDF or Postscript, you can run your document #through this code and then through html2ps or html2pdf #outside of cgi context the file must be passed as an argument not as a pipe #you need to be executing from the directory in which the file resides #TODO #Enable this to work outside of cgi context #Make DOM visible to haskell code #TODO! we need to deal w/ multiple evals on the same line #TODO! support mode where output can be rerun by this script $sep="ABCDEFABCDEFAAAAABBBBDDDEEEGGGEGEGGGGEHAKJHAKJHKJAKJHKJHKJHAS"; #cgi standard intro $iscgi=$ENV{REQUEST_METHOD}; if ($iscgi) { print "content-type: text/html\n\n"; } if ($iscgi) { $moduleName=$ENV{SCRIPT_NAME}; $moduleName=substr($moduleName,1); #strip initial "/" } else { $moduleName=$ARGV[0]; } #need to write file into same place as module or we need # to debug hugs path stuff which is a pain if ($iscgi) { $infile=$ENV{SCRIPT_FILENAME}; #full path to file $dir =$infile; $dir=~s/(.*)\/(.*)/$1/ge; #use regex maxmunch to get path } else { $dir=`pwd`; chop($dir); $infile=$dir."/".$ARGV[0]; } $moduleName=~s/(.*)\.(.*)/$1/g; #get rid of file extension #we have the haskell file to evaluate $ename = $dir."/abc.lhs"; $debug=0; if ($debug) {print "iscgi=$iscgi infile=$infile moduleName= $moduleName dir=$dir ename=$ename\n";} #define disquote so that output strings are not enclosed in quotations $dquote = "> dquote x = if isString then reverse \$ tail \$ reverse \$ tail showed else showed > where > showed = show x > isString = case showed of [] -> False;('\"':xs)->True;otherwise->False "; #prepare the output file open (LHSFILE,">$ename"); print LHSFILE "> import $moduleName\n"; print LHSFILE "$dquote\n"; print LHSFILE "> main = do\n"; #process haskell module and generate the result values open (INFILE,$infile) || print "Can't open file!"; while(<INFILE>) { chop; $expr=$_; $expr=~s/.*\<hs.*\s(.*)\/\>.*/$1/g; if ($_ ne $expr) { $ostring = ">\t\tputStr \$ (dquote \$ $expr) ++\"$sep\" \n"; $result = print LHSFILE ($ostring) ; } } close (INFILE); close (LHSFILE); #now create an input stream to repackage this stuff back in open (CFILE,"runhugs $ename | "); @buffer=<CFILE>; $buffer=join("\n",@buffer); @lines = split ($sep,$buffer); #now writeouput w/ process information open (INFILE,$infile); $first=1; $iscomment=0; $i=0; while (<INFILE>) { if ($iscgi && $first) {$first=0;next;} #get rid of #!/bin... in cgi chop; $orig=$_; $repl = $lines[$i]; #REmove comments of the form <!r comment may contain newline /!r> # #support nesting comments # s/(.*)\<\!r\s.*\/\!r\>(.*)/$1.$2/ge; # $orig2=$_; # if (! $iscomment) { # s/(.*)\<\!r\s.*/$1/ge; # } else { # s/.*\/\!r\>(.*)/$1/ge; # } # if ($orig2 ne $_) {$iscomment=!$iscomment;} # above does not work for multiple comments on the same line #TODO! we need to deal w/ multiple evals on the same line #TODO! support mode where output can be rerun by this script s/(.*)\<hseval(.*)\/\>(.*)/$1.$repl.$3/ge; s/(.*)\<hsdemo(.*)\/\>(.*)/$1.$2." => ".$repl.$3/ge; if ($orig ne $_) {$i++; } s/^\>\s(.*)/$1/ge; print $_."\n"; } close (CFILE);