-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2svg.hs
138 lines (116 loc) · 3.27 KB
/
2svg.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import Data.Char
pageW = 1100
pageH = 1100
rectHeight = 20
rectWidth = 20
main = do
putStrLn svgHead
parseTiles 0
putStrLn svgFoot
parseTiles :: Int -> IO ()
parseTiles rowNum = do
rowBW <- removeEsc <$> getLine
-- let row' = filter isCodeChar row
when (length rowBW >= 2) $ do
putStrLn $ svgRow 0 rowNum rowBW
parseTiles $ rowNum + 1
svgHead :: String
svgHead =
"<svg xmlns=\"" ++ ns ++ "\"\n" ++
" xmlns:osb=\"" ++ osb_ns ++ "\"\n" ++
" version=\"1.1\" " ++
" width=\"" ++ show pageW ++ "\"" ++
" height=\"" ++ show pageH ++ "\"" ++
" ><defs>\n" ++ fillGrps ++ "\n</defs>\n<g id=\"g1\">"
where
ns = "http://www.w3.org/2000/svg"
osb_ns = "http://www.openswatchbook.org/uri/2009/osb"
svgFoot :: String
svgFoot =
"</g></svg>"
-- works w ESC[ codes from 00-99 ending w 'm'
removeEsc :: String -> String
removeEsc (a:b:c:d:xs)
| a == '\ESC' && b == '[' =
if d == 'm'
then removeEsc xs -- one figure code
else removeEsc $ drop 1 xs -- two figure code
| otherwise = a : removeEsc ( b:c:d:xs ) -- aproved char a
removeEsc str = str -- aprove all
type Pos = (Int,Int) -- x,y
type Color = Int
data Tile = Tile { cellSpan::Int, color::Color }
deriving (Show)
tile :: String -> Tile
tile [] = error "String illegal, empty!"
tile (x:[]) = error $ "Need 2 chars! Got '" ++ [x] ++ "'"
tile (x:xs) = Tile span' color'
where
span' = if x == 's' then 1 else 2
color' = if isDigit colorChar
then read [colorChar] :: Color
else error $ "Illegal color num '" ++ [colorChar] ++ "'"
colorChar = if x == 's' then head xs else xs!!2
tileCharLen :: Tile -> Int
tileCharLen (Tile 1 _ ) = 2
tileCharLen (Tile 2 _ ) = 4
tileCharLen _ = error "møkka tile"
svgRow :: Int -> Int -> String -> String
svgRow _ _ [] = "\n"
svgRow _ _ (x:[]) = error "crap in;" ++ [x]
svgRow xOffset rowN row =
r0 ++ nextCall
where
r0 = rect (rectX,rectY) (cellSpan t) (color t)
nextCall = svgRow nextOffset rowN ( drop charsUsed row )
nextOffset = cellSpan t + xOffset
rectX = xOffset * rectWidth
rectY = rowN * rectHeight
t = tile row
charsUsed = tileCharLen t
rect :: Pos -> Int -> Color -> String
rect pos wFactor color =
"<rect " ++
" class=\"swatch_" ++ show color ++ " spans_" ++ show wFactor ++ "\"" ++
" width=" ++ attr ( rectWidth * wFactor ) ++
" height=" ++ attr rectHeight ++
" x=" ++ attr (fst pos) ++
" y=" ++ attr (snd pos) ++
" style=\"" ++ (style color) ++ "\"" ++
" />\n"
attr :: Int -> String
attr n =
"\"" ++ show n ++ "\""
style :: Color -> String
style c =
"fill:url(#" ++ colorId c ++ ");" ++
"stroke:#999;"
fillGrps :: String
fillGrps =
concat $ map linearGradient [0..9]
linearGradient :: Color -> String
linearGradient c =
"<linearGradient" ++
" osb:paint=\"solid\" " ++
" id=\"" ++ colorId c ++ "\">\n" ++
stop c ++
"</linearGradient>\n"
stop :: Color -> String
stop c =
"<stop" ++
" offset=\"0\"" ++
" style=\"stop-opacity:1;" ++
"stop-color:#" ++ hexd c ++ "\" />"
colorId :: Color -> String
colorId c = "_c" ++ show c
hexd :: Color -> String
hexd c = case c of
0 -> "111"
1 -> "333"
2 -> "666"
3 -> "999"
4 -> "AAA"
5 -> "CCC"
6 -> "EEE"
7 -> "F4F4F4"
_ -> "A11"