diagrams-builder 0.6.0.4 → 0.7.0.0
raw patch · 11 files changed
+206/−83 lines, 11 filesdep +JuicyPixelsdep +diagrams-rasterificdep +lucid-svgdep −blaze-svgdep ~basedep ~diagrams-cairodep ~diagrams-libnew-component:exe:diagrams-builder-rasterific
Dependencies added: JuicyPixels, diagrams-rasterific, lucid-svg
Dependencies removed: blaze-svg
Dependency ranges changed: base, diagrams-cairo, diagrams-lib, diagrams-postscript, diagrams-svg, exceptions, lens
Files
- CHANGES.markdown +11/−2
- LICENSE +7/−1
- diagrams-builder.cabal +49/−17
- latex/diagrams-latex.sty +5/−1
- src/Diagrams/Builder.hs +47/−38
- src/Diagrams/Builder/Modules.hs +3/−2
- src/Diagrams/Builder/Opts.hs +16/−16
- src/tools/diagrams-builder-cairo.hs +1/−1
- src/tools/diagrams-builder-ps.hs +1/−1
- src/tools/diagrams-builder-rasterific.hs +61/−0
- src/tools/diagrams-builder-svg.hs +5/−4
CHANGES.markdown view
@@ -1,7 +1,16 @@+0.7 (19 April 2015)+-------------------++- Update to `diagrams-lib-1.3`.+- Add `diagrams-rasterific` support.+- Add support for `DIAGRAMS_SANDBOX` environment variable.+- Allow `exceptions-0.8`+- Fix `diagrams-latex` directory creation on Windows+ 0.6.0.4 (2 April 2015) ---------------------- - - allow `lens-4.9`+- allow `lens-4.9` 0.6.0.3 (13 Jan 2015) ---------------------@@ -18,7 +27,7 @@ ------------------------ - Allow lens-4.4- + 0.6 (5 June 2014) -----------------
LICENSE view
@@ -1,6 +1,12 @@-Copyright (c) 2012-2013 diagrams-builder team:+Copyright (c) 2012-2015 diagrams-builder team: + Daniel Bergey <bergey@alum.mit.edu>+ Jeroen Bransen <J.Bransen@uu.nl>+ Christopher Chalmers <c.chalmers@me.com>+ Anthony Cowley <acowley@gmail.com>+ Yiding Jia <yiding@fb.com> Jeffrey Rosenbluth <jeffrey.rosenbluth@gmail.com>+ Ryan Yates <fryguybob@gmail.com> Brent Yorgey <byorgey@gmail.com> All rights reserved.
diagrams-builder.cabal view
@@ -1,5 +1,5 @@ name: diagrams-builder-version: 0.6.0.4+version: 0.7.0.0 synopsis: hint-based build service for the diagrams graphics EDSL. description: @diagrams-builder@ provides backend-agnostic tools for@@ -14,13 +14,14 @@ plugin for @BlogLiterately@) to compile diagrams embedded in Markdown-formatted blog posts. .- Executables specific to the cairo, SVG, and postscript+ Executables specific to the cairo, SVG, postscript,+ and rasterific backends are included (more executables specific to other backends may be included in the future). All take an input file and an expression to render, and output an image file. If you want these executables you must explicitly enable the- @-fcairo@, @-fsvg@, or @-fps@ flags.+ @-fcairo@, @-fsvg@, @-fpostscript@, or @-frasterific@ flags. . A LaTeX package, @diagrams-latex.sty@, is also provided in the @latex/@ directory of the source@@ -36,7 +37,7 @@ category: Graphics build-type: Simple cabal-version: >=1.10-tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.3+tested-with: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.1 bug-reports: https://github.com/diagrams/diagrams-builder/issues Source-repository head type: git@@ -47,9 +48,9 @@ Diagrams.Builder.Opts Diagrams.Builder.Modules Diagrams.Builder.CmdLine- build-depends: base >=4.2 && < 4.8,+ build-depends: base >=4.2 && < 4.9, mtl >= 2.1 && < 2.3,- diagrams-lib >= 1.2 && < 1.3,+ diagrams-lib >= 1.3 && < 1.4, hint >= 0.4 && < 0.5, directory, filepath,@@ -59,7 +60,7 @@ cmdargs >= 0.6 && < 0.11, lens >= 4.0 && < 4.10, hashable >= 1.1 && < 1.3,- exceptions >= 0.3 && < 0.7+ exceptions >= 0.3 && < 0.9 hs-source-dirs: src default-language: Haskell2010 other-extensions: StandaloneDeriving,@@ -82,6 +83,16 @@ default: False manual: True +flag postscript+ description: install postscript-specific builder tool+ default: False+ manual: True++flag rasterific+ description: install rasterific-specific builder tool+ default: False+ manual: True+ executable diagrams-builder-cairo main-is: diagrams-builder-cairo.hs hs-source-dirs: src/tools@@ -97,10 +108,10 @@ filepath, directory, diagrams-builder,- diagrams-lib >= 0.6 && < 1.3,- diagrams-cairo >= 0.6 && < 1.3,+ diagrams-lib >= 1.3 && < 1.4,+ diagrams-cairo >= 1.3 && < 1.4, cmdargs >= 0.6 && < 0.11,- lens >= 3.8 && < 4.10+ lens >= 4.0 && < 4.10 executable diagrams-builder-svg main-is: diagrams-builder-svg.hs@@ -117,9 +128,9 @@ filepath, directory, diagrams-builder,- diagrams-lib >= 0.6 && < 1.3,- diagrams-svg >= 0.8.0.1 && < 1.2,- blaze-svg >= 0.3.3 && < 0.4,+ diagrams-lib >= 0.6 && < 1.4,+ diagrams-svg >= 0.8.0.1 && < 1.4,+ lucid-svg, bytestring >= 0.9.2 && < 0.11, cmdargs >= 0.6 && < 0.11 @@ -130,15 +141,36 @@ other-extensions: DeriveDataTypeable RecordWildCards - if !flag(ps)+ if !flag(ps) && !flag(postscript) buildable: False - if flag(ps)+ if flag(ps) || flag(postscript) build-depends: base >= 4 && < 5, filepath, directory, diagrams-builder,- diagrams-lib >= 0.6 && < 1.3,- diagrams-postscript >= 0.6 && < 1.2,+ diagrams-lib >= 0.6 && < 1.4,+ diagrams-postscript >= 0.6 && < 1.4, cmdargs >= 0.6 && < 0.11, lens >= 3.8 && < 4.10++executable diagrams-builder-rasterific+ main-is: diagrams-builder-rasterific.hs+ hs-source-dirs: src/tools+ default-language: Haskell2010+ other-extensions: DeriveDataTypeable+ RecordWildCards++ if !flag(rasterific)+ buildable: False++ if flag(rasterific)+ build-depends: base >= 4 && < 5,+ filepath,+ directory,+ diagrams-builder,+ diagrams-lib >= 0.6 && < 1.4,+ diagrams-rasterific >= 1.3 && < 1.4,+ cmdargs >= 0.6 && < 0.11,+ lens >= 3.8 && < 4.10,+ JuicyPixels >= 3.1.5 && < 3.3
latex/diagrams-latex.sty view
@@ -208,7 +208,11 @@ \ifdtt@ForceShellEscape \dtt@ShellEscapetrue \fi- \immediate\write18{mkdir -p \dtt@outputdir}+ \ifwindows+ \immediate\write18{if not exist \dtt@outputdir\space mkdir \dtt@outputdir}+ \else+ \immediate\write18{mkdir -p \dtt@outputdir}+ \fi \xdef\diagramslatexCutFile{\dtt@figname.hs} \diagramslatexverbatimwrite{\diagramslatexCutFile}} {\enddiagramslatexverbatimwrite%
src/Diagrams/Builder.hs view
@@ -1,9 +1,9 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-}-{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -----------------------------------------------------------------------------@@ -43,15 +43,14 @@ ) where -import Control.Lens ((^.)) import Control.Monad (guard, mplus, mzero)-import Control.Monad.Catch (catchAll)+import Control.Monad.Catch (MonadMask, catchAll) import Control.Monad.Trans.Maybe (MaybeT, runMaybeT) import Data.Data import Data.Hashable (Hashable (..)) import Data.List (foldl', nub) import Data.List.Split (splitOn)-import Data.Maybe (catMaybes, fromMaybe)+import Data.Maybe (catMaybes) import System.Directory (doesFileExist, getTemporaryDirectory, removeFile)@@ -67,9 +66,8 @@ import Diagrams.Builder.CmdLine import Diagrams.Builder.Modules import Diagrams.Builder.Opts-import Diagrams.Prelude hiding ((<.>))+import Diagrams.Prelude import Language.Haskell.Interpreter.Unsafe (unsafeRunInterpreterWithArgs)-import System.Environment (getEnvironment) deriving instance Typeable Any @@ -106,30 +104,36 @@ ] ++ imps -getHsenvArgv :: IO [String]-getHsenvArgv = do- env <- getEnvironment- return $ case (lookup "HSENV" env) of- Nothing -> []- _ -> hsenvArgv- where hsenvArgv = words $ fromMaybe "" (lookup "PACKAGE_DB_FOR_GHC" env)+-- | Run an interpretor using sandbox from 'findSandbox'.+runSandboxInterpreter :: (MonadMask m, MonadIO m, Functor m)+ => InterpreterT m a -> m (Either InterpreterError a)+runSandboxInterpreter i = do+ mSandbox <- liftIO $ findSandbox []+ case mSandbox of+ Just sandbox -> let args = ["-package-db", sandbox]+ in unsafeRunInterpreterWithArgs args i+ Nothing -> runInterpreter i -- | Interpret a diagram expression based on the contents of a given -- source file, using some backend to produce a result. The--- expression can be of type @Diagram b v@ or @IO (Diagram b v)@.+-- expression can be of type @Diagram b v n@ or @IO (Diagram b v n)@. interpretDiagram- :: forall b v.- ( Typeable b, Typeable v, Data v, Data (Scalar v)- , InnerSpace v, OrderedField (Scalar v), Backend b v+ :: forall b v n.+ ( Typeable b+#if __GLASGOW_HASKELL__ > 707+ , Typeable v+#else+ , Typeable1 v+#endif+ , HasLinearMap v, Data (v n), Data n+ , Metric v, OrderedField n, Backend b v n )- => BuildOpts b v+ => BuildOpts b v n -> FilePath- -> IO (Either InterpreterError (Result b v))+ -> IO (Either InterpreterError (Result b v n)) interpretDiagram bopts m = do - -- use an hsenv sandbox, if one is enabled.- args <- liftIO getHsenvArgv- unsafeRunInterpreterWithArgs args $ do+ runSandboxInterpreter $ do setDiagramImports m (bopts ^. imports) let dexp = bopts ^. diaExpr@@ -138,7 +142,7 @@ -- b v and IO (Diagram b v). Take whichever one typechecks, -- running the IO action in the second case to produce a -- diagram.- d <- interpret dexp (as :: Diagram b v) `catchAll` const (interpret dexp (as :: IO (Diagram b v)) >>= liftIO)+ d <- interpret dexp (as :: QDiagram b v n Any) `catchAll` const (interpret dexp (as :: IO (QDiagram b v n Any)) >>= liftIO) -- Finally, call renderDia. return $ renderDia (backendToken bopts) (bopts ^. backendOpts) ((bopts ^. postProcess) d)@@ -155,14 +159,14 @@ ------------------------------------------------------------ -- | Potential results of a dynamic diagram building operation.-data BuildResult b v =- ParseErr String -- ^ Parsing of the code failed.- | InterpErr InterpreterError -- ^ Interpreting the code- -- failed. See 'ppInterpError'.- | Skipped Hash -- ^ This diagram did not need to be- -- regenerated; includes the hash.- | OK Hash (Result b v) -- ^ A successful build, yielding the- -- hash and a backend-specific result.+data BuildResult b v n =+ ParseErr String -- ^ Parsing of the code failed.+ | InterpErr InterpreterError -- ^ Interpreting the code+ -- failed. See 'ppInterpError'.+ | Skipped Hash -- ^ This diagram did not need to be+ -- regenerated; includes the hash.+ | OK Hash (Result b v n) -- ^ A successful build, yielding the+ -- hash and a backend-specific result. -- | Build a diagram by writing the given source code to a temporary -- module and interpreting the given expression, which can be of@@ -170,11 +174,17 @@ -- parse error if the source does not parse, an interpreter error, -- or the final result. buildDiagram- :: ( Typeable b, Typeable v, Data v, Data (Scalar v)- , InnerSpace v, OrderedField (Scalar v), Backend b v- , Hashable (Options b v)+ :: ( Typeable b, Data (v n), Data n+ , Metric v, HasLinearMap v+#if __GLASGOW_HASKELL__ > 707+ , Typeable v+#else+ , Typeable1 v+#endif+ , OrderedField n, Backend b v n+ , Hashable (Options b v n) )- => BuildOpts b v -> IO (BuildResult b v)+ => BuildOpts b v n -> IO (BuildResult b v n) buildDiagram bopts = do let bopts' = bopts & snippets %~ map unLit@@ -194,7 +204,7 @@ Nothing -> return $ Skipped diaHash Just upd -> do tmpDir <- getTemporaryDirectory- (tmp, h) <- openTempFile tmpDir ("Diagram.hs")+ (tmp, h) <- openTempFile tmpDir "Diagram.hs" let m' = replaceModuleName (takeBaseName tmp) m hPutStr h (prettyPrint m') hClose h@@ -211,8 +221,7 @@ hashLocalImports :: [ImportDecl] -> IO Hash hashLocalImports = fmap (foldl' hashWithSalt 0 . catMaybes)- . mapM getLocalSource- . map (foldr1 (</>) . splitOn "." . getModuleName . importModule)+ . mapM (getLocalSource . foldr1 (</>) . splitOn "." . getModuleName . importModule) -- | Given a relative path with no extension, like -- @\"Foo\/Bar\/Baz\"@, check whether such a file exists with either
src/Diagrams/Builder/Modules.hs view
@@ -35,7 +35,7 @@ -- Returns the updated module, or an error message if parsing -- failed. createModule :: Maybe String -- ^ Module name to use- -> BuildOpts b v+ -> BuildOpts b v n -> Either String Module createModule nm opts = do ms <- mapM doModuleParse (opts ^. snippets)@@ -93,7 +93,7 @@ where addImport imp is | any ((==imp) . getModuleName . importModule) is = is | otherwise = ImportDecl noLoc (ModuleName imp) False False False- Nothing Nothing Nothing : is+ Nothing Nothing Nothing : is -- | Combine two modules into one, with a left bias in the case of -- things that can't be sensibly combined (/e.g./ the module name).@@ -125,3 +125,4 @@ -- | Convert a @ModuleName@ to a @String@. getModuleName :: ModuleName -> String getModuleName (ModuleName n) = n+
src/Diagrams/Builder/Opts.hs view
@@ -34,7 +34,7 @@ import System.FilePath (takeBaseName) import Text.Printf -import Diagrams.Prelude (Diagram, Options)+import Diagrams.Prelude (QDiagram, Options, Any) -- | Synonym for more perspicuous types. --@@ -56,19 +56,19 @@ -- & imports .~ [\"Foo.Bar\", \"Baz.Quux\"] -- & diaExpr .~ \"square 6 # fc green\" -- @-data BuildOpts b v+data BuildOpts b v n = BuildOpts { backendToken :: b -- ^ Backend token- , vectorToken :: v+ , vectorToken :: v n -- ^ Dummy vector argument to fix the vector space type- , _backendOpts :: Options b v+ , _backendOpts :: Options b v n , _snippets :: [String] , _pragmas :: [String] , _imports :: [String]- , _decideRegen :: Hash -> IO (Maybe (Options b v -> Options b v))+ , _decideRegen :: Hash -> IO (Maybe (Options b v n -> Options b v n)) , _diaExpr :: String- , _postProcess :: Diagram b v -> Diagram b v+ , _postProcess :: QDiagram b v n Any -> QDiagram b v n Any } makeLensesWith (lensRules & generateSignatures .~ False) ''BuildOpts@@ -86,26 +86,26 @@ -- * the diagram expression @circle 1@ -- -- * no postprocessing-mkBuildOpts :: b -> v -> Options b v -> BuildOpts b v+mkBuildOpts :: b -> v n -> Options b v n -> BuildOpts b v n mkBuildOpts b v opts = BuildOpts b v opts [] [] [] alwaysRegenerate "circle 1" id -- | Backend-specific options to use.-backendOpts :: Lens' (BuildOpts b v) (Options b v)+backendOpts :: Lens' (BuildOpts b v n) (Options b v n) -- | Source code snippets. Each should be a syntactically valid -- Haskell module. They will be combined intelligently, /i.e./ -- not just pasted together textually but combining pragmas, -- imports, /etc./ separately.-snippets :: Lens' (BuildOpts b v) [String]+snippets :: Lens' (BuildOpts b v n) [String] -- | Extra @LANGUAGE@ pragmas to use (@NoMonomorphismRestriction@ -- is automatically enabled.)-pragmas :: Lens' (BuildOpts b v) [String]+pragmas :: Lens' (BuildOpts b v n) [String] -- | Additional module imports (note that "Diagrams.Prelude" is -- automatically imported).-imports :: Lens' (BuildOpts b v) [String]+imports :: Lens' (BuildOpts b v n) [String] -- | A function to decide whether a particular diagram needs to be -- regenerated. It will be passed a hash of the final assembled@@ -127,13 +127,13 @@ -- and always decides to regenerate the diagram; -- 'hashedRegenerate' creates a hash of the diagram source and -- looks for a file with that name in a given directory.-decideRegen :: Lens' (BuildOpts b v) (Hash -> IO (Maybe (Options b v -> Options b v)))+decideRegen :: Lens' (BuildOpts b v n) (Hash -> IO (Maybe (Options b v n -> Options b v n))) -- | The diagram expression to interpret. All the given import sand -- snippets will be in scope, with the given LANGUAGE pragmas--- enabled. The expression may have either of the types @Diagram b--- v@ or @IO (Diagram b v)@.-diaExpr :: Lens' (BuildOpts b v) String+-- enabled. The expression may have either of the types @Diagram b@+-- or @IO (Diagram b)@.+diaExpr :: Lens' (BuildOpts b v n) String -- | A function to apply to the interpreted diagram prior to -- rendering. For example, you might wish to apply @pad 1.1@@ -141,7 +141,7 @@ -- string expression to be interpreted, since it gives better -- typechecking, and works no matter whether the expression -- represents a diagram or an IO action.-postProcess :: Lens' (BuildOpts b v) (Diagram b v -> Diagram b v)+postProcess :: Lens' (BuildOpts b v n) (QDiagram b v n Any -> QDiagram b v n Any) -- | Convenience function suitable to be given as the final argument -- to 'buildDiagram'. It implements the simple policy of always
src/tools/diagrams-builder-cairo.hs view
@@ -29,7 +29,7 @@ createDirectoryIfMissing True dir - let bopts = mkBuildOpts Cairo zeroV (CairoOptions outFile (mkSizeSpec width height) fmt False)+ let bopts = mkBuildOpts Cairo zero (CairoOptions outFile (mkSizeSpec2D width height) fmt False) & snippets .~ [f] & imports .~ [ "Diagrams.Backend.Cairo" ] & diaExpr .~ expr
src/tools/diagrams-builder-ps.hs view
@@ -19,7 +19,7 @@ createDirectoryIfMissing True dir - let bopts = mkBuildOpts Postscript zeroV (PostscriptOptions outFile (mkSizeSpec width height) EPS)+ let bopts = mkBuildOpts Postscript zero (PostscriptOptions outFile (mkSizeSpec2D width height) EPS) & snippets .~ [f] & imports .~ [ "Diagrams.Backend.Postscript" ] & diaExpr .~ expr
+ src/tools/diagrams-builder-rasterific.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE RecordWildCards #-}++module Main where+import qualified Codec.Picture as J+import Diagrams.Backend.Rasterific+import Diagrams.Prelude hiding (height, width)++import Diagrams.Builder++import System.Directory (copyFile,+ createDirectoryIfMissing)+import qualified System.FilePath as FP++import System.Console.CmdArgs++compileExample :: Build -> IO ()+compileExample (Build{..}) = do+ let ext = FP.takeExtension outFile+ save = case ext of+ ".png" -> J.savePngImage+ ".jpg" -> J.saveJpgImage 100+ ".bmp" -> J.saveBmpImage+ ".gif" -> (either error id .) . J.saveGifImage+ ".tiff" -> J.saveTiffImage+ _ -> J.savePngImage+ f <- readFile srcFile++ createDirectoryIfMissing True dir++ let w = fmap realToFrac width+ h = fmap realToFrac height+ bopts = mkBuildOpts Rasterific zero (RasterificOptions (mkSizeSpec2D w h))+ & snippets .~ [f]+ & imports .~ [ "Diagrams.Backend.Rasterific" ]+ & diaExpr .~ expr+ & decideRegen .~ (hashedRegenerate (\_ opts -> opts) dir)++ res <- buildDiagram bopts+ case res of+ ParseErr err -> putStrLn ("Parse error in " ++ srcFile) >> putStrLn err+ InterpErr ierr -> putStrLn ("Error while compiling " ++ srcFile) >>+ putStrLn (ppInterpError ierr)+ Skipped hash -> copyFile (mkFile (hashToHexStr hash) ext) outFile+ OK hash img -> let cached = mkFile (hashToHexStr hash) ext+ in do save cached (J.ImageRGBA8 img)+ copyFile cached outFile+ where+ mkFile base ext = dir FP.</> base FP.<.> ext++build :: Build+build =+ defaultBuildOpts+ { outFile = "out.png" &= typFile &= help "Output file (default: \"out.png\")" }+ &= summary "The diagrams-builder-rasterific program, for dynamically rendering diagrams using the rasterific backend. Give it a source file and an expression to render (which may refer to things declared in the source file), and it outputs an image, using hashing to avoid rerendering images unnecessarily.\n\nIf you have installed the diagrams-lib and diagrams-rasterific packages in a sandbox, set the environment variable DIAGRAMS_SANDBOX to that directory so the builder can compile your diagram. For example, \"export DIAGRAMS_SANDBOX=~/diagrams/.cabal-sandbox\". If you have package databases for multiple versions of GHC in that sandbox, you will need to set the full path to the package database (it ends in \".conf.d\")."+ &= program "diagrams-builder-rasterific"++main :: IO ()+main = do+ opts <- cmdArgs build+ compileExample opts
src/tools/diagrams-builder-svg.hs view
@@ -1,26 +1,27 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-} module Main where import Diagrams.Backend.SVG import Diagrams.Builder import Diagrams.Prelude hiding (height, width)+import Lucid.Svg import qualified Data.ByteString.Lazy as BS import System.Console.CmdArgs import System.Directory (copyFile, createDirectoryIfMissing) import qualified System.FilePath as FP-import Text.Blaze.Svg.Renderer.Utf8 (renderSvg) compileExample :: Build -> IO () compileExample (Build{..}) = do- f <- readFile srcFile+ f <- readFile srcFile createDirectoryIfMissing True dir - let bopts = mkBuildOpts SVG zeroV (SVGOptions (mkSizeSpec width height) Nothing)+ let bopts = mkBuildOpts SVG zero (SVGOptions (mkSizeSpec2D width height) [] "" ) & snippets .~ [f] & imports .~ [ "Diagrams.Backend.SVG" ] & diaExpr .~ expr@@ -34,7 +35,7 @@ putStrLn (ppInterpError ierr) Skipped hash -> copyFile (mkFile (hashToHexStr hash)) outFile OK hash svg -> do let cached = mkFile (hashToHexStr hash)- BS.writeFile cached (renderSvg svg)+ renderToFile cached svg copyFile cached outFile where mkFile base = dir FP.</> base FP.<.> "svg"