2012-06-14 08:43:04 +00:00
{- # LANGUAGE DeriveDataTypeable # -}
2012-04-19 06:32:10 +00:00
module Main where
2012-06-14 08:43:04 +00:00
import Data.Either ( lefts , rights )
2013-04-03 07:32:21 +00:00
import Data.List ( intersect , intercalate , lookup )
2012-06-14 08:43:04 +00:00
import Data.Maybe ( fromMaybe )
2012-10-03 07:17:09 +00:00
import Data.Version ( showVersion )
2012-06-14 08:43:04 +00:00
import System.Console.CmdArgs
2013-03-14 08:04:51 +00:00
import System.Exit
2012-11-25 22:08:10 +00:00
import System.FilePath
2012-06-14 08:43:04 +00:00
import Text.Blaze.Html.Renderer.String ( renderHtml )
2012-09-11 09:53:45 +00:00
import qualified Text.Jasmine as JS
import qualified Data.ByteString.Lazy.Char8 as BS
2012-06-14 08:43:04 +00:00
import Ast
import Initialize
2012-05-29 18:25:43 +00:00
import CompileToJS
import GenerateHtml
2013-04-04 08:09:35 +00:00
import qualified Libraries as Libraries
2012-06-14 08:43:04 +00:00
import Paths_Elm
data ELM =
ELM { make :: Bool
, files :: [ FilePath ]
, runtime :: Maybe FilePath
2012-06-14 10:02:33 +00:00
, separate_js :: Bool
, only_js :: Bool
2012-06-28 08:52:47 +00:00
, import_js :: [ FilePath ]
2013-04-01 08:05:41 +00:00
, no_prelude :: Bool
, noscript :: Bool
2012-09-11 09:53:45 +00:00
, minify :: Bool
2012-11-25 15:17:40 +00:00
, output_directory :: Maybe FilePath
2012-06-14 08:43:04 +00:00
}
deriving ( Data , Typeable , Show , Eq )
elm = ELM { make = False &= help " automatically compile dependencies. "
, files = def &= args &= typ " FILES "
2012-06-28 08:52:47 +00:00
, runtime = Nothing &= typFile &=
2012-06-14 08:43:04 +00:00
help " Specify a custom location for Elm's runtime system. "
2012-06-14 10:02:33 +00:00
, separate_js = False &= help " Compile to separate HTML and JS files. "
, only_js = False &= help " Compile only to JavaScript. "
2012-06-28 08:52:47 +00:00
, 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. "
2013-04-01 08:05:41 +00:00
, no_prelude = False &= help " Do not import Prelude by default, used only when compiling standard libraries. "
, noscript = True &= help " Add generated <noscript> tag to HTML output. "
2012-09-11 09:53:45 +00:00
, minify = False &= help " Minify generated JavaScript "
2012-11-25 15:17:40 +00:00
, output_directory = Nothing &= typFile &= help " Output files to directory specified. Defaults to the location of original file. "
2012-06-14 08:43:04 +00:00
} &=
help " Compile Elm programs to HTML, CSS, and JavaScript. " &=
2012-10-03 07:17:09 +00:00
summary ( " The Elm Compiler " ++ showVersion version ++ " , (c) Evan Czaplicki " )
2012-04-19 06:32:10 +00:00
2012-06-14 08:43:04 +00:00
main = do
args <- cmdArgs elm
2013-03-12 07:48:11 +00:00
mini <- getDataFileName " elm-runtime.js "
2012-06-14 08:43:04 +00:00
compileArgs mini args
2013-04-01 08:05:41 +00:00
compileArgs mini flags =
case files flags of
[] -> putStrLn " Usage: elm [OPTIONS] [FILES] \ n For more help: elm --help "
fs -> mapM_ ( fileTo flags what loc ) fs
where loc = fromMaybe mini ( runtime flags )
what | only_js flags = JS
| separate_js flags = Split
| otherwise = HTML
2012-06-14 08:43:04 +00:00
2012-06-14 10:02:33 +00:00
data What = JS | HTML | Split
2013-04-01 08:05:41 +00:00
fileTo flags what rtLoc file = do
let jsStyle = if minify flags then Minified else Readable
formatJS = if minify flags then BS . unpack . JS . minify . BS . pack else id
2013-04-08 08:48:30 +00:00
prelude = not ( no_prelude flags )
ems <- if make flags then build prelude file
2013-04-01 08:05:41 +00:00
else do src <- readFile file
2013-04-08 08:48:30 +00:00
return ( fmap ( : [] ) ( buildFromSource prelude src ) )
2013-04-01 08:05:41 +00:00
jss <- concat ` fmap ` mapM readFile ( import_js flags )
2012-06-14 08:43:04 +00:00
case ems of
2013-03-14 08:04:51 +00:00
Left err -> do putStrLn $ " Error while compiling " ++ file ++ " : \ n " ++ err
exitFailure
2013-04-01 08:05:41 +00:00
Right ms' ->
let path = fromMaybe " " ( output_directory flags ) </> file
2012-11-25 22:08:10 +00:00
js = replaceExtension path " .js "
html = replaceExtension path " .html "
2013-04-04 17:37:43 +00:00
ms = if no_prelude flags then ms' else map Libraries . addPrelude ms'
2013-02-27 07:33:47 +00:00
txt = jss ++ concatMap jsModule ms
2012-11-29 06:16:08 +00:00
in case what of
2013-02-08 09:33:21 +00:00
JS -> writeFile js ( formatJS txt )
HTML -> writeFile html . renderHtml $
2013-04-01 08:05:41 +00:00
modulesToHtml jsStyle " " rtLoc jss ( noscript flags ) ms
2013-02-08 09:33:21 +00:00
Split ->
2013-02-27 07:33:47 +00:00
do writeFile html . renderHtml $ linkedHtml rtLoc js ms
2013-02-08 09:33:21 +00:00
writeFile js ( formatJS txt )