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);

Reply via email to