/
tmpl.hs
76 lines (67 loc) · 2.27 KB
/
tmpl.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
{-# LANGUAGE OverloadedStrings #-}
module Main where
import System.Environment (getArgs)
import Control.Monad (when)
import qualified Data.ByteString.Lazy as S
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import qualified Data.Text.Lazy.Encoding as E
import System.Directory (doesFileExist)
import System.Exit (exitSuccess)
import Data.Text.Template
usage :: String
usage = unlines [
"tmpl -- simple string-template-interpolation"
,"\n"
,"Usage:"
,"\ttmpl var1=uno:var2=dos < myfile.tmpl > myfile.txt"
,"\ttmpl myfile.tmpl < vars.conf > myfile.txt"
,"\ttmpl myfile.tmpl vars.conf > myfile.txt"
,"\n"
,"Example:"
,"\techo 'The quick $color fox jumps over the $adj dog.' \\"
,"\t\t| tmpl color=brown:adj=lazy"
,"\n"
,"Author: Michel Kuhlmann 2013"
]
main :: IO ()
main = do
args <- getArgs
(tmpl,cntx) <-
case length args of
1 -> do
let f = head args
when (f == "-h" || f == "--help") (sequence_ [putStrLn usage, exitSuccess])
isFile <- doesFileExist f
if isFile
then do
cntx <- fmap (context . splitStr) TIO.getContents
tmpl <- TIO.readFile f
return (tmpl,cntx)
else do
let cntx = context . splitStr . T.pack $ f
tmpl <- TIO.getContents
return (tmpl,cntx)
2 -> do
let tmplF:cntxF:[] = args
existTmplF <- doesFileExist tmplF
existCntxF <- doesFileExist cntxF
when (not existTmplF || not existCntxF) (fail usage)
tmpl <- TIO.readFile tmplF
cntx <- fmap (context . splitStr) $ TIO.readFile cntxF
return (tmpl,cntx)
_ -> error usage
S.putStr $ E.encodeUtf8 $ substitute tmpl cntx
-- | Create 'Context' from association list.
context :: [(T.Text, T.Text)] -> Context
context assocs x = maybe err id . lookup x $ assocs
where err = error $ "Could not find key: " ++ T.unpack x
-- | First split Text on ':' or newline; second split on '='
splitStr :: T.Text -> [(T.Text, T.Text)]
splitStr s = map splitEq (T.split (\c -> c `elem` [':','\n'] ) s)
where
splitEq s = (k,v)
where
k:v:[] = T.split (== '=') s
--k:v:[] = map chomp $ T.split (== '=') s
--chomp = T.replace " " ""