#!/usr/local/bin/runhugs module Main(main) where import System(getArgs) import IO(hClose,hPutStr,hGetContents, stdin,stdout,openFile,IOMode,Handle,ReadMode,WriteMode) toHtmlVer = "2html.3 Time-stamp: <1997-10-27 09:16:24 peter>" {- Simple program to read a half file on stdin and write an html representation on output. If there is an argument, it is used for the title of the HTML file, else the string "stdin" is used. The processing treats single line comments specially. Comments may not be nested. Stolen from a demo program in the hugs documentation. Note the first line! So one can use hugs like perl, or bash. The line is even acceptable to the Hugs interpreter! -} -- import System(getArgs) -- import IO(hClose,hPutStr,hGetContents, -- stdin,stdout,openFile,IOMode,Handle,ReadMode,WriteMode) main = let fromHandle = stdin toHandle = stdout in do args <- getArgs let name = case args of { [] -> "stdin" ; a:args -> a } -- do (name,fromHandle) <- getAndOpenFile "Copy from: " ReadMode -- (junk,toHandle) <- getAndOpenFile "Copy to: " WriteMode contents <- hGetContents fromHandle hPutStr toHandle (code_start name ++ code (\x->x) contents) hClose toHandle -- putStr "Done." {- unused -} getAndOpenFile :: String -> IOMode -> IO (String,Handle) getAndOpenFile prompt mode = do putStr prompt name <- getLine catch (do { h <- openFile name mode ; return (name,h) }) (\_ -> do putStr ("Cannot open "++ name ++ "\n") error "abandoned" getAndOpenFile prompt mode) code_start name = html_header name -- ++ "
" code_end = -- "" ++ html_trailer code_to_comm = "{-" comm_to_code = "
-}" oner_start = "{-" oner_end = "-}" block_start = code_to_comm block_end = comm_to_code html_header name = "\n\n\n" ++ "\n" ++ str' ++ "\n" ++ name ++ " \n\n\n" ++ ("\n") ++ "" html_trailer = "" ++ "\n\n\n\n" {- I can't see color with lynx so these are probably crazy. -} oner_color = "#FF00FF" bgcolor = "#FFFFFF" {- the state machine -} code b cs = case cs of "" -> pcode (b cs) ++ code_end [c] -> pcode (b cs) ++ code_end ('{':'-':cs') -> pcode (b "") ++ comm (\x->x) cs' (c1:c2:cs') -> code (b . (c1 :)) (c2:cs') comm b cs = case cs of "" -> error "end of file in comment" [c] -> error "end of file in comment" ('-':'}':cs') -> pcomm (b "") ++ code (\x->x) cs' (c1:c2:cs') -> comm (b . (c1 :)) (c2:cs' ) pcode str = str -- "" ++ str ++ "" pcomm str = if '\n' `elem` str then let ls = lines str blank l = strip l == "" paras ls = if (null ls) then [] else let (bef,aft) = break blank ls (jnk,aft') = break (not . blank) aft in bef : paras aft' strip = dropWhile (\c -> c ==' ' || c == '\t') indentation = length . takeWhile (\c -> c ==' ') layp = concat . map (\l -> l++" \n") layps = concat . map (\p -> p++"\n") str' = layps (map layp (paras ls)) in "{-
-}\n" else "{- " ++ str ++ "-}" {- END -} data Memory = Leaf String | Fork (Char -> Memory) contents :: (String -> String) -> Memory -> [(String,String)] contents a t = case t of Leaf v -> [(a "",v)] Fork phi -> concat [ contents (a . (c:)) (phi c) | c <- "abcdefghijklmnopqrstuvwxyz" ] write addr val t = case addr of "" -> Leaf val (c:cs) -> case t of Leaf str -> write addr val (Fork ( \c -> t )) Fork phi -> let t' = write cs val (phi c) in Fork (\ c' -> if c == c' then t' else phi c' ) {- experiments -} reada b addr t = case t of Leaf val -> (b "",val) -- return address used Fork phi -> case addr of "" -> reada b " " t (c:cs) -> reada (b . (c:)) cs (phi c) tree = (foldr (\(addr,val) t -> write addr val t) (Leaf "") . reverse ) [("foo","bar"),("ab","ba"),("a","a"),("b","b"),("ab","ba")] prefix "" str = 0 == 0 prefix (c:cs) "" = 0 == 1 prefix (c:cs) (d:ds) = if (c == d) then prefix cs ds else 0 == 2 blank l = let (n,rest) = indent l in rest == "" eat = eat' . map indent . filter (not . blank) eat' [] = [] -- eat' ((i,l):ls) = let e = (i:l) indent line = indent' 0 line where indent' n (' ':cs) = indent' (n+1) cs indent' n ('\t':cs) = indent' (8*(1+n/8)) cs indent' n str = (n,str) {- return the pieces of a string, where str is the separator -} pieces :: String -> String -> [ String ] pieces sep str = case sep of "" -> let x = "":x in x (c:_) -> pieces1 str (\x->x) where pieces1 str b = case str of "" -> [b ""] _ -> let (bef,aft) = break (c ==) str in case aft of "" -> [b bef] _:aft' -> if sep `prefix` aft then let str' = drop (length sep) aft in (b bef: pieces1 str' (\x->x)) else pieces1 aft' (b . (bef++) . (c:)) mybreak p str = mybreak1 str (\x -> x) where mybreak1 str b = case str of "" -> [b ""] (c:cs) -> if p c then (b "":mybreak1 cs (\x->x)) else mybreak1 cs (b . (c:)) sb p = sb1 (\x->x) where sb1 b str = if (p str) then [(b "",str)] else case str of "" -> [] (c:cs) -> sb1 (b . (c:)) cs {- experiments upto c "" = ("","") upto c (ch:str) = upto1 c (ch:) str where upto1 c b "" = (b "","") upto1 c b (ch:str') = if (c == ch) then ( b "", str ) else upto1 c (b . (ch:)) str' seq' p q str = let { (a,str') = p str ; (b,str'') = q str' } in (a++b,str'') empty "" = 0 == 0 empty (c:cs) = 0 == 1 upto' "" str = "" upto' (c:cs) "" = "" upto' (c:cs) (d:ds) = if c == d then if prefix cs ds then "" else d:upto' (c:cs) ds else d : upto' (c:cs) ds un a = \s -> (a,s) bi p f = \s-> let { (a,s') = p s } in f a s' {-\ script = cd `bi` \cod -> rep (co `bi` \ com -> cd `bi` \ cod -> un (comm++fs) ) `bi` \rest -> un (cod++rest) cd = \ str -> let x = upto "{-" str str' = drop (length x) str in (x,str') co = \str -> let y = upto "-}" str str' = dtrop (length y) str in (y,str') rep p = \str -> case str of "" -> ("","") (c:cs) -> -} -}