85 lines
3.4 KiB
Haskell
85 lines
3.4 KiB
Haskell
{-# LANGUAGE DeriveDataTypeable #-}
|
|
module Main where
|
|
|
|
import Data.Either (lefts, rights)
|
|
import Data.List (intersect, intercalate)
|
|
import Data.Maybe (fromMaybe)
|
|
import Data.Version (showVersion)
|
|
import System.Console.CmdArgs
|
|
import System.Exit
|
|
import System.FilePath
|
|
import Text.Blaze.Html.Renderer.String (renderHtml)
|
|
|
|
import qualified Text.Jasmine as JS
|
|
import qualified Data.ByteString.Lazy.Char8 as BS
|
|
|
|
import Ast
|
|
import Initialize
|
|
import CompileToJS
|
|
import GenerateHtml
|
|
import Paths_Elm
|
|
|
|
data ELM =
|
|
ELM { make :: Bool
|
|
, files :: [FilePath]
|
|
, runtime :: Maybe FilePath
|
|
, separate_js :: Bool
|
|
, only_js :: Bool
|
|
, import_js :: [FilePath]
|
|
, generate_noscript :: Bool
|
|
, minify :: Bool
|
|
, output_directory :: Maybe FilePath
|
|
}
|
|
deriving (Data,Typeable,Show,Eq)
|
|
|
|
elm = ELM { make = False &= help "automatically compile dependencies."
|
|
, files = def &= args &= typ "FILES"
|
|
, runtime = Nothing &= typFile &=
|
|
help "Specify a custom location for Elm's runtime system."
|
|
, separate_js = False &= help "Compile to separate HTML and JS files."
|
|
, only_js = False &= help "Compile only to JavaScript."
|
|
, import_js = [] &= typFile &= help "Include a JavaScript file before the body of the Elm program. Can be used many times. Files will be included in the given order."
|
|
, generate_noscript = True &= help "Add generated <noscript> tag to HTML output."
|
|
, minify = False &= help "Minify generated JavaScript"
|
|
, output_directory = Nothing &= typFile &= help "Output files to directory specified. Defaults to the location of original file."
|
|
} &=
|
|
help "Compile Elm programs to HTML, CSS, and JavaScript." &=
|
|
summary ("The Elm Compiler " ++ showVersion version ++ ", (c) Evan Czaplicki")
|
|
|
|
main = do
|
|
args <- cmdArgs elm
|
|
mini <- getDataFileName "elm-runtime.js"
|
|
compileArgs mini args
|
|
|
|
compileArgs mini (ELM _ [] _ _ _ _ _ _ _) =
|
|
putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
|
|
compileArgs mini (ELM make files rtLoc split only js nscrpt isMini outputDir) =
|
|
mapM_ (fileTo isMini make what js nscrpt outputDir loc) files
|
|
where loc = fromMaybe mini rtLoc
|
|
what | only = JS
|
|
| split = Split
|
|
| otherwise = HTML
|
|
|
|
data What = JS | HTML | Split
|
|
|
|
fileTo isMini make what jsFiles noscript outputDir rtLoc file = do
|
|
let jsStyle = if isMini then Minified else Readable
|
|
formatJS = if isMini then BS.unpack . JS.minify . BS.pack else id
|
|
ems <- if make then build file else do src <- readFile file
|
|
return (fmap (:[]) (buildFromSource src))
|
|
jss <- concat `fmap` mapM readFile jsFiles
|
|
case ems of
|
|
Left err -> do putStrLn $ "Error while compiling " ++ file ++ ":\n" ++ err
|
|
exitFailure
|
|
Right ms ->
|
|
let path = fromMaybe "" outputDir </> file
|
|
js = replaceExtension path ".js"
|
|
html = replaceExtension path ".html"
|
|
txt = jss ++ concatMap jsModule ms
|
|
in case what of
|
|
JS -> writeFile js (formatJS txt)
|
|
HTML -> writeFile html . renderHtml $
|
|
modulesToHtml jsStyle "" rtLoc jss noscript ms
|
|
Split ->
|
|
do writeFile html . renderHtml $ linkedHtml rtLoc js ms
|
|
writeFile js (formatJS txt)
|