import Control Monad import Data Char import Data List import System E

 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
import Control.Monad
import Data.Char
import Data.List
import System.Environment
data Range = LowOpen Double | Closed Double Double | HighOpen Double deriving Eq
instance Show Range where
show (LowOpen x) = "...-" ++ show x
show (Closed x y) = show x ++ "-" ++ show y
show (HighOpen x) = show x ++ "-..."
parseRange "_" x = LowOpen (read x)
parseRange x "_" = HighOpen (read x)
parseRange x y = Closed (read x) (read y)
data Table = Table {
file :: String, varname :: String,
mean :: Double, stddev :: Double,
frequencies :: [(Range, Double)]
} deriving Show
column t = map ($ t) [file, show . mean, show . stddev] ++ map (show . snd) (frequencies t)
parseRow :: String -> (Range, Double)
parseRow row =
let [start, "-", end, freq] = take 4 $ words row in
(parseRange start end, read freq)
parseTables _ [] = []
parseTables file (header:rows) =
let [var, s_mean, s_stddev] = take 3 $ words header
[mean, stddev] = map read [s_mean, s_stddev]
(dat, rest) = break (isLetter . head . dropWhile isSpace) rows
in Table file var mean stddev (map parseRow dat) : parseTables file rest
extractTables = tail . takeWhile (not . all isSpace) . dropWhile (not . isPrefixOf "TABLE") . lines
main = do
filelist <- getArgs
tables <- liftM concat $ forM filelist $ \filename ->
readFile filename >>= return . parseTables filename . extractTables
let vars = nub $ map varname tables
forM_ vars $ \var -> do
putStrLn $ "%%% " ++ var
let dat = filter ((== var) . varname) tables
let firstcol = ["source", "stddev", "mean"] ++ map (show . fst) (frequencies $ head dat)
let cols = firstcol : map column dat
putStr $ unlines $ map ((++ " \\\\") . concat . intersperse " & ") $ transpose cols