yesod/yesod/Scaffolding/CodeGen.hs
Bryan Richter a0f8c45b4f Cleans up ends of scaffold files
Scaffolding.CodeGen.codegenDir no longer removes the final eol. Input files that
had extra eols have had them removed. With these changes, the generated files
are now more identical to the inputs:

    $ diff foo/LICENSE scaffold/LICENSE.cg
    4c4
    < Copyright 2012, foo. All rights reserved.
    ---
    > Copyright ~year~, ~name~. All rights reserved.

Additionally, initial commits of changes to a new project's files aren't
littered with "\ No newline at end of file". Maybe other people don't have this
problem, but vim auto-adds eols to files that lack them...

    commit ce34468190ea87b91eb3b1a9b7987f40d49cf97e
    Author: Bryan Richter <bryan.richter@gmail.com>
    Date:   Fri Jan 27 22:59:57 2012 -0800

        Adds newlines to files that need em.

     Foundation.hs                           |    2 +-
     Handler/Root.hs                         |    2 +-
     Import.hs                               |    2 +-
     config/models                           |    2 +-
     config/postgresql.yml                   |    2 +-
     config/settings.yml                     |    2 +-
     <and so on>
2012-01-31 11:32:06 -08:00

45 lines
1.3 KiB
Haskell

{-# LANGUAGE TemplateHaskell #-}
-- | A code generation template haskell. Everything is taken as literal text,
-- with ~var~ variable interpolation.
module Scaffolding.CodeGen (codegen, codegenDir) where
import Language.Haskell.TH.Syntax
import Text.ParserCombinators.Parsec
import qualified Data.ByteString.Lazy as L
import qualified Data.Text.Lazy as LT
import qualified Data.Text.Lazy.Encoding as LT
data Token = VarToken String | LitToken String | EmptyToken
codegenDir :: FilePath -> FilePath -> Q Exp
codegenDir dir fp = do
s' <- qRunIO $ L.readFile $ (dir ++ "/" ++ fp ++ ".cg")
let s = LT.unpack $ LT.decodeUtf8 s'
case parse (many parseToken) s s of
Left e -> error $ show e
Right tokens' -> do
let tokens'' = map toExp tokens'
concat' <- [|concat|]
return $ concat' `AppE` ListE tokens''
codegen :: FilePath -> Q Exp
codegen fp = codegenDir "scaffold" fp
toExp :: Token -> Exp
toExp (LitToken s) = LitE $ StringL s
toExp (VarToken s) = VarE $ mkName s
toExp EmptyToken = LitE $ StringL ""
parseToken :: Parser Token
parseToken =
parseVar <|> parseLit
where
parseVar = do
_ <- char '~'
s <- many alphaNum
_ <- char '~'
return $ if null s then EmptyToken else VarToken s
parseLit = do
s <- many1 $ noneOf "~"
return $ LitToken s