-
Notifications
You must be signed in to change notification settings - Fork 0
/
Iseq.hs
82 lines (59 loc) · 2.34 KB
/
Iseq.hs
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{-# OPTIONS_GHC -Wall #-}
module Iseq where
import Utils
data Iseq = INil
| IStr String
| IAppend Iseq Iseq
| IIndent Iseq
| INewline
deriving (Show)
iNil :: Iseq -- The empty iseq
iNil = INil
iIsNil :: Iseq -> Bool
iIsNil INil = True
iIsNil _ = False
iStr :: String -> Iseq -- Turn a string into an iseq
iStr = iInterleave iNewline . map mkIStr . split '\n'
where mkIStr "" = iNil
mkIStr str = IStr str
iAppend :: Iseq -> Iseq -> Iseq -- Append two iseqs
iAppend = IAppend
iNewline :: Iseq -- New line with indentation
iNewline = INewline
iIndent :: Iseq -> Iseq -- Indent an iseq
iIndent s = IIndent s
iDisplay :: Iseq -> String -- Turn an iseq into a string
iDisplay s = flatten 0 [(s, 0)]
iConcat :: [Iseq] -> Iseq
iConcat xs = foldr iAppend iNil xs
iNum :: Int -> Iseq
iNum n = iStr (show n)
iFWNum :: Int -> Int -> Iseq
iFWNum width n = iStr (space (width - length digits) ++ digits)
where digits = (show n)
iLayn :: [Iseq] -> Iseq
iLayn xs = iConcat (map layItem (zip [1..] xs))
where layItem (n, s) = iConcat [ iFWNum 4 n, iStr ") ", iIndent s, iNewline ]
iInterleave :: Iseq -> [Iseq] -> Iseq
iInterleave _ [] = iNil
iInterleave _ [x] = x
iInterleave sep (x:xs) = x `iAppend` sep `iAppend` iInterleave sep xs
iSplitView :: [Iseq] -> Iseq
iSplitView = iInterleave iNewline . map cf . eqlzLineSz . eqlzLineCount . toStringLines
where cf = iInterleave (iStr " | ") . map iStr -- concat function
toStringLines = map (split '\n' . iDisplay)
padWith x n xs = xs ++ replicate (n - length xs) x
maxLines = maximum . map length
maxLinesLength = map (maximum . map length)
eqlzLineCount views = map (padWith "" (maxLines views)) views
eqlzLineSz views = zipNWith (zipWith (padWith ' ') (maxLinesLength views)) views
flatten :: Int -> [(Iseq, Int)] -> String
flatten _ [] = ""
flatten col ((INil, _): seqs) = flatten col seqs
flatten col ((IStr s, _): seqs) = s ++ flatten (col + length s) seqs
flatten col (((IAppend s1 s2), indent): seqs)
= flatten col ((s1, indent) : (s2, indent) : seqs)
flatten col ((IIndent s, _) : seqs)
= flatten col ((s, col) : seqs)
flatten _ ((INewline, indent) : seqs)
= '\n' : (space indent) ++ (flatten indent seqs)