module Language.Drasil.Generate (
dumpTo, dumpEverything,
typeCheckSI,
gen, genDot, genCode,
DocType(..), DocSpec(DocSpec), Format(TeX, HTML, JSON), DocChoices(DC),
docChoices) where
import System.IO (hClose, hPutStrLn, openFile, IOMode(WriteMode))
import Text.PrettyPrint.HughesPJ (Doc, render)
import Prelude hiding (id)
import System.Directory (createDirectoryIfMissing, getCurrentDirectory,
setCurrentDirectory)
import Data.Time.Clock (getCurrentTime, utctDay)
import Data.Time.Calendar (showGregorian)
import Build.Drasil (genMake)
import Language.Drasil
import Drasil.DocLang (mkGraphInfo)
import SysInfo.Drasil (SystemInformation)
import Language.Drasil.Printers (DocType(SRS, Website, Jupyter), Format(TeX, HTML, JSON),
makeCSS, genHTML, genTeX, genJSON, PrintingInformation, outputDot)
import Language.Drasil.Code (generator, generateCode, Choices(..), CodeSpec(..),
Lang(..), getSampleData, readWithDataDesc, sampleInputDD,
unPP, unJP, unCSP, unCPPP, unSP)
import Language.Drasil.Output.Formats(Filename, DocSpec(DocSpec), DocChoices(DC))
import Language.Drasil.TypeCheck
import Language.Drasil.Dump
import GOOL.Drasil (unJC, unPC, unCSC, unCPPC, unSC)
gen :: DocSpec -> Document -> PrintingInformation -> IO ()
gen :: DocSpec -> Document -> PrintingInformation -> IO ()
gen DocSpec
ds Document
fn PrintingInformation
sm = PrintingInformation -> DocSpec -> Document -> IO ()
prnt PrintingInformation
sm DocSpec
ds Document
fn
prnt :: PrintingInformation -> DocSpec -> Document -> IO ()
prnt :: PrintingInformation -> DocSpec -> Document -> IO ()
prnt PrintingInformation
sm (DocSpec (DC DocType
Jupyter [Format]
_) Filename
fn) Document
body =
do Document
-> PrintingInformation -> Filename -> DocType -> Format -> IO ()
prntDoc Document
body PrintingInformation
sm Filename
fn DocType
Jupyter Format
JSON
prnt PrintingInformation
sm (DocSpec (DC DocType
dtype [Format]
fmts) Filename
fn) Document
body =
do forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Document
-> PrintingInformation -> Filename -> DocType -> Format -> IO ()
prntDoc Document
body PrintingInformation
sm Filename
fn DocType
dtype) [Format]
fmts
prntDoc :: Document -> PrintingInformation -> String -> DocType -> Format -> IO ()
prntDoc :: Document
-> PrintingInformation -> Filename -> DocType -> Format -> IO ()
prntDoc Document
d PrintingInformation
pinfo Filename
fn DocType
Jupyter Format
_ = DocType
-> Filename
-> Filename
-> Format
-> Document
-> PrintingInformation
-> IO ()
prntDoc' DocType
Jupyter Filename
"Jupyter" Filename
fn Format
JSON Document
d PrintingInformation
pinfo
prntDoc Document
d PrintingInformation
pinfo Filename
fn DocType
dtype Format
fmt =
case Format
fmt of
Format
HTML -> do DocType
-> Filename
-> Filename
-> Format
-> Document
-> PrintingInformation
-> IO ()
prntDoc' DocType
dtype (forall a. Show a => a -> Filename
show DocType
dtype forall a. [a] -> [a] -> [a]
++ Filename
"/HTML") Filename
fn Format
HTML Document
d PrintingInformation
pinfo
DocType -> Filename -> Document -> IO ()
prntCSS DocType
dtype Filename
fn Document
d
Format
TeX -> do DocType
-> Filename
-> Filename
-> Format
-> Document
-> PrintingInformation
-> IO ()
prntDoc' DocType
dtype (forall a. Show a => a -> Filename
show DocType
dtype forall a. [a] -> [a] -> [a]
++ Filename
"/PDF") Filename
fn Format
TeX Document
d PrintingInformation
pinfo
DocSpec -> IO ()
prntMake forall a b. (a -> b) -> a -> b
$ DocChoices -> Filename -> DocSpec
DocSpec (DocType -> [Format] -> DocChoices
DC DocType
dtype []) Filename
fn
Format
JSON -> do DocType
-> Filename
-> Filename
-> Format
-> Document
-> PrintingInformation
-> IO ()
prntDoc' DocType
dtype (forall a. Show a => a -> Filename
show DocType
dtype forall a. [a] -> [a] -> [a]
++ Filename
"/JSON") Filename
fn Format
JSON Document
d PrintingInformation
pinfo
Format
_ -> forall a. Monoid a => a
mempty
prntDoc' :: DocType -> String -> String -> Format -> Document -> PrintingInformation -> IO ()
prntDoc' :: DocType
-> Filename
-> Filename
-> Format
-> Document
-> PrintingInformation
-> IO ()
prntDoc' DocType
dt Filename
dt' Filename
fn Format
format Document
body' PrintingInformation
sm = do
Bool -> Filename -> IO ()
createDirectoryIfMissing Bool
True Filename
dt'
Handle
outh <- Filename -> IOMode -> IO Handle
openFile (Filename
dt' forall a. [a] -> [a] -> [a]
++ Filename
"/" forall a. [a] -> [a] -> [a]
++ Filename
fn forall a. [a] -> [a] -> [a]
++ Format -> Filename
getExt Format
format) IOMode
WriteMode
Handle -> Filename -> IO ()
hPutStrLn Handle
outh forall a b. (a -> b) -> a -> b
$ Doc -> Filename
render forall a b. (a -> b) -> a -> b
$ PrintingInformation
-> DocType -> Format -> Filename -> Document -> Doc
writeDoc PrintingInformation
sm DocType
dt Format
format Filename
fn Document
body'
Handle -> IO ()
hClose Handle
outh
where getExt :: Format -> Filename
getExt Format
TeX = Filename
".tex"
getExt Format
HTML = Filename
".html"
getExt Format
JSON = Filename
".ipynb"
getExt Format
_ = forall a. HasCallStack => Filename -> a
error Filename
"We can only write in TeX, HTML and Jupyter Notebook (for now)."
prntMake :: DocSpec -> IO ()
prntMake :: DocSpec -> IO ()
prntMake ds :: DocSpec
ds@(DocSpec (DC DocType
dt [Format]
_) Filename
_) =
do Handle
outh <- Filename -> IOMode -> IO Handle
openFile (forall a. Show a => a -> Filename
show DocType
dt forall a. [a] -> [a] -> [a]
++ Filename
"/PDF/Makefile") IOMode
WriteMode
Handle -> Filename -> IO ()
hPutStrLn Handle
outh forall a b. (a -> b) -> a -> b
$ Doc -> Filename
render forall a b. (a -> b) -> a -> b
$ forall c. RuleTransformer c => [c] -> Doc
genMake [DocSpec
ds]
Handle -> IO ()
hClose Handle
outh
prntCSS :: DocType -> String -> Document -> IO ()
prntCSS :: DocType -> Filename -> Document -> IO ()
prntCSS DocType
docType Filename
fn Document
body = do
Handle
outh2 <- Filename -> IOMode -> IO Handle
openFile (forall a. Show a => a -> Filename
getFD DocType
docType forall a. [a] -> [a] -> [a]
++ Filename
fn forall a. [a] -> [a] -> [a]
++ Filename
".css") IOMode
WriteMode
Handle -> Filename -> IO ()
hPutStrLn Handle
outh2 forall a b. (a -> b) -> a -> b
$ Doc -> Filename
render (Document -> Doc
makeCSS Document
body)
Handle -> IO ()
hClose Handle
outh2
where
getFD :: a -> Filename
getFD a
dtype = forall a. Show a => a -> Filename
show a
dtype forall a. [a] -> [a] -> [a]
++ Filename
"/HTML/"
writeDoc :: PrintingInformation -> DocType -> Format -> Filename -> Document -> Doc
writeDoc :: PrintingInformation
-> DocType -> Format -> Filename -> Document -> Doc
writeDoc PrintingInformation
s DocType
_ Format
TeX Filename
_ Document
doc = Document -> PrintingInformation -> Doc
genTeX Document
doc PrintingInformation
s
writeDoc PrintingInformation
s DocType
_ Format
HTML Filename
fn Document
doc = PrintingInformation -> Filename -> Document -> Doc
genHTML PrintingInformation
s Filename
fn Document
doc
writeDoc PrintingInformation
s DocType
dt Format
JSON Filename
_ Document
doc = PrintingInformation -> DocType -> Document -> Doc
genJSON PrintingInformation
s DocType
dt Document
doc
writeDoc PrintingInformation
_ DocType
_ Format
_ Filename
_ Document
_ = forall a. HasCallStack => Filename -> a
error Filename
"we can only write TeX/HTML/JSON (for now)"
genDot :: SystemInformation -> IO ()
genDot :: SystemInformation -> IO ()
genDot SystemInformation
si = do
Filename
workingDir <- IO Filename
getCurrentDirectory
let gi :: GraphInfo
gi = SystemInformation -> GraphInfo
mkGraphInfo SystemInformation
si
Filename -> GraphInfo -> IO ()
outputDot Filename
"TraceyGraph" GraphInfo
gi
Filename -> IO ()
setCurrentDirectory Filename
workingDir
genCode :: Choices -> CodeSpec -> IO ()
genCode :: Choices -> CodeSpec -> IO ()
genCode Choices
chs CodeSpec
spec = do
Filename
workingDir <- IO Filename
getCurrentDirectory
UTCTime
time <- IO UTCTime
getCurrentTime
[Expr]
sampData <- forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return []) (\Filename
sd -> Filename -> DataDesc' -> IO [Expr]
readWithDataDesc Filename
sd forall a b. (a -> b) -> a -> b
$ [CodeVarChunk] -> DataDesc'
sampleInputDD
(CodeSpec -> [CodeVarChunk]
extInputs CodeSpec
spec)) (Choices -> Maybe Filename
getSampleData Choices
chs)
Bool -> Filename -> IO ()
createDirectoryIfMissing Bool
False Filename
"src"
Filename -> IO ()
setCurrentDirectory Filename
"src"
let genLangCode :: Lang -> IO ()
genLangCode Lang
Java = forall {progRepr :: * -> *} {packRepr :: * -> *}.
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> IO ()
genCall Lang
Java forall a. JavaCode a -> a
unJC forall a. JavaProject a -> a
unJP
genLangCode Lang
Python = forall {progRepr :: * -> *} {packRepr :: * -> *}.
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> IO ()
genCall Lang
Python forall a. PythonCode a -> a
unPC forall a. PythonProject a -> a
unPP
genLangCode Lang
CSharp = forall {progRepr :: * -> *} {packRepr :: * -> *}.
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> IO ()
genCall Lang
CSharp forall a. CSharpCode a -> a
unCSC forall a. CSharpProject a -> a
unCSP
genLangCode Lang
Cpp = forall {progRepr :: * -> *} {packRepr :: * -> *}.
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> IO ()
genCall Lang
Cpp forall a. CppCode CppSrcCode CppHdrCode a -> a
unCPPC forall a. CppProject a -> a
unCPPP
genLangCode Lang
Swift = forall {progRepr :: * -> *} {packRepr :: * -> *}.
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> IO ()
genCall Lang
Swift forall a. SwiftCode a -> a
unSC forall a. SwiftProject a -> a
unSP
genCall :: Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> IO ()
genCall Lang
lng progRepr (Program progRepr) -> ProgData
unProgRepr packRepr (Package packRepr) -> PackData
unPackRepr = forall (progRepr :: * -> *) (packRepr :: * -> *).
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> DrasilState
-> IO ()
generateCode Lang
lng progRepr (Program progRepr) -> ProgData
unProgRepr
packRepr (Package packRepr) -> PackData
unPackRepr forall a b. (a -> b) -> a -> b
$ Lang -> Filename -> [Expr] -> Choices -> CodeSpec -> DrasilState
generator Lang
lng (Day -> Filename
showGregorian forall a b. (a -> b) -> a -> b
$ UTCTime -> Day
utctDay UTCTime
time) [Expr]
sampData Choices
chs CodeSpec
spec
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Lang -> IO ()
genLangCode (Choices -> [Lang]
lang Choices
chs)
Filename -> IO ()
setCurrentDirectory Filename
workingDir
docChoices :: DocType -> [Format] -> DocChoices
docChoices :: DocType -> [Format] -> DocChoices
docChoices = DocType -> [Format] -> DocChoices
DC