diagrams-haddock 0.1.2.0 → 0.2
raw patch · 4 files changed
+118/−31 lines, 4 filesdep +base64-bytestringPVP ok
version bump matches the API change (PVP)
Dependencies added: base64-bytestring
API changes (from Hackage documentation)
- Diagrams.Haddock: compileDiagram :: Bool -> FilePath -> FilePath -> Set String -> [CodeBlock] -> DiagramURL -> IO (DiagramURL, Bool)
+ Diagrams.Haddock: compileDiagram :: Bool -> Bool -> FilePath -> FilePath -> FilePath -> Set String -> [CodeBlock] -> DiagramURL -> IO (DiagramURL, Bool)
- Diagrams.Haddock: compileDiagrams :: Bool -> FilePath -> FilePath -> Set String -> [CodeBlock] -> [Either String DiagramURL] -> IO ([Either String DiagramURL], Bool)
+ Diagrams.Haddock: compileDiagrams :: Bool -> Bool -> FilePath -> FilePath -> FilePath -> Set String -> [CodeBlock] -> [Either String DiagramURL] -> IO ([Either String DiagramURL], Bool)
- Diagrams.Haddock: processHaddockDiagrams :: Bool -> FilePath -> FilePath -> FilePath -> IO [String]
+ Diagrams.Haddock: processHaddockDiagrams :: Bool -> Bool -> FilePath -> FilePath -> FilePath -> IO [String]
- Diagrams.Haddock: processHaddockDiagrams' :: CpphsOptions -> Bool -> FilePath -> FilePath -> FilePath -> IO [String]
+ Diagrams.Haddock: processHaddockDiagrams' :: CpphsOptions -> Bool -> Bool -> FilePath -> FilePath -> FilePath -> IO [String]
Files
- README.md +46/−11
- diagrams-haddock.cabal +3/−2
- src/Diagrams/Haddock.hs +43/−14
- tools/diagrams-haddock.hs +26/−4
README.md view
@@ -96,7 +96,7 @@ -- -- as illustrated below: ----- <<dummy#diagram=algoIllustration&width=400>>+-- <<#diagram=algoIllustration&width=400>> -- -- > algoIllustration = ... ```@@ -113,13 +113,13 @@ -- -- Here is a blue circle: ----- <<dummy#diagram=blueC&width=200>>+-- <<#diagram=blueC&width=200>> -- -- > blueC = circle 1 # makeitblue -- -- And here is a blue square: ----- <<dummy#diagram=blueS&width=200>>+-- <<#diagram=blueS&width=200>> -- -- > blueS = square 1 # makeitblue ```@@ -168,8 +168,12 @@ * `-d`, `--distdir`: When building diagrams for a cabal package, this is the directory in which `diagrams-haddock` should look for the- `setup-config` file (*i.e.* the output of `cabal configure`). The- default is `dist`.+ `setup-config` file (*i.e.* the output of `cabal configure`). An+ explicit value for this flag takes precedence; next,+ `diagrams-haddock` checks whether there is an active+ [hsenv](http://hackage.haskell.org/package/hsenv) environment, and+ if so uses `dist_<hsenv name>`; otherwise, it defaults to using+ `dist`. * `-i`, `--includedirs`: `diagrams-haddock` does its best to process files with CPP directives, even extracting information about where@@ -181,23 +185,54 @@ * `--cppdefines`: likewise, this option allows you to specify additional names that should be `#define`d when CPP is run. +* `--dataURIs`: embed the generated SVG images directly in the source+ code with [data URIs](http://en.wikipedia.org/wiki/Data_URI_scheme)+ (the default is to generate external SVG files and link to them).+ See the section below for a discussion of the tradeoffs involved.+ * `-q`, `--quiet`: `diagrams-haddock` normally prints some logging information to indicate what it is doing; this option silences the output. ## Workflow and Cabal setup -The recommended workflow for using `diagrams-haddock` is as follows:+There are two ways one may include generated SVG images with your+documentation: as data URIs, or as external images. The two options+are discussed below, along with pros and cons of each. Note that in+either case, consumers of your library (including Hackage itself) do+*not* need to have `diagrams-haddock` installed in order to build your+documentation. +### Using data URIs++If you pass the `--dataURIs` option to `diagrams-haddock`, any+generated images will be embedded directly in your source file (and+hence also in the HTML ultimately produced by `haddock`) as+[data URIs](http://en.wikipedia.org/wiki/Data_URI_scheme). To use+this method,+ 1. Include inline diagrams code and URLs in your source code.+2. Run `diagrams-haddock --dataURIs`.+3. Commit the resulting URL changes to your source files.++The benefit of this scheme is that there are no extra files to deal+with, and no need to alter your `.cabal` file in any way. The+downside is that it significantly bloats your source code, and may+make it extremely inconvenient to edit without some sort of tool+support (*e.g.* an editor that can "collapse" certain sections of the+source file).++### Using external images++By default, `diagrams-haddock` generates external SVG image files. This+makes for a much less invasive changes to your source files, but+requires some extra work to manage the extra files. To use this method,++1. Include inline diagrams code and URLs in your source code. 2. Run `diagrams-haddock`.-3. Commit the resulting URL changes and produced SVG files.+3. Commit the resulting URL changes to your source files *and* the produced SVG files. 4. Arrange to have the SVG files installed along with your package's Haddock documentation (more on this below).--The point is that consumers of your library (such as Hackage) do not-need to have `diagrams-haddock` installed in order to build your-documentation. The generated SVG files need to be copied alongside the generated Haddock documentation. There are two good ways to accomplish this:
diagrams-haddock.cabal view
@@ -1,5 +1,5 @@ name: diagrams-haddock-version: 0.1.2.0+version: 0.2 synopsis: Preprocessor for embedding diagrams in Haddock documentation description: diagrams-haddock is a tool for compiling embedded inline diagrams code in Haddock documentation, for an@@ -51,7 +51,8 @@ cpphs >= 1.15, cautious-file >= 1.0 && < 1.1, uniplate >= 1.6 && < 1.7,- text >= 0.11 && < 0.12+ text >= 0.11 && < 0.12,+ base64-bytestring >= 1 && < 1.1 hs-source-dirs: src other-extensions: TemplateHaskell default-language: Haskell2010
src/Diagrams/Haddock.hs view
@@ -75,7 +75,9 @@ import Control.Arrow (first, (&&&), (***)) import Control.Lens hiding ((<.>)) import Control.Monad.Writer+import qualified Data.ByteString.Base64.Lazy as BS64 import qualified Data.ByteString.Lazy as BS+import qualified Data.ByteString.Lazy.Char8 as BS8 import Data.Char (isSpace) import Data.Either (lefts, rights) import Data.Function (on)@@ -96,7 +98,9 @@ import System.Directory (copyFile, createDirectoryIfMissing, doesFileExist)-import System.FilePath ((<.>), (</>))+import System.FilePath (dropExtension, normalise,+ splitDirectories, (<.>),+ (</>)) import qualified System.IO as IO import qualified System.IO.Cautious as Cautiously import qualified System.IO.Strict as Strict@@ -410,26 +414,30 @@ -- If for some reason you would like this scheme to be more -- flexible/configurable, feel free to file a feature request. compileDiagram :: Bool -- ^ @True@ = quiet+ -> Bool -- ^ @True@ = generate data URIs -> FilePath -- ^ cache directory -> FilePath -- ^ output directory+ -> FilePath -- ^ file being processed -> S.Set String -- ^ diagrams referenced from URLs -> [CodeBlock] -> DiagramURL -> IO (DiagramURL, Bool)-compileDiagram quiet cacheDir outputDir ds code url+compileDiagram quiet dataURIs cacheDir outputDir file ds code url -- See https://github.com/diagrams/diagrams-haddock/issues/7 . | (url ^. diagramName) `S.notMember` ds = return (url, False) -- The normal case. | otherwise = do- createDirectoryIfMissing True outputDir createDirectoryIfMissing True cacheDir+ when (not dataURIs) $ createDirectoryIfMissing True outputDir - let outFile = outputDir </> (url ^. diagramName) <.> "svg"+ let outFile = outputDir </> (munge file ++ "_" ++ (url ^. diagramName)) <.> "svg" + munge = intercalate "_" . splitDirectories . normalise . dropExtension+ w = read <$> M.lookup "width" (url ^. diagramOpts) h = read <$> M.lookup "height" (url ^. diagramOpts) oldURL = (url, False)- newURL = (url & diagramURL .~ outFile, outFile /= url^.diagramURL)+ newURL content = (url & diagramURL .~ content, content /= url^.diagramURL) neededCode = transitiveClosure (url ^. diagramName) code @@ -457,31 +465,42 @@ putStrLn (ppInterpError ierr) return oldURL Skipped hash -> do- copyFile (mkCached hash) outFile+ let cached = mkCached hash+ when (not dataURIs) $ copyFile cached outFile logStrLn ""- return newURL+ if dataURIs+ then do+ svgBS <- BS.readFile cached+ return (newURL (mkDataURI svgBS))+ else return (newURL outFile) OK hash svg -> do let cached = mkCached hash- BS.writeFile cached (renderSvg svg)- copyFile cached outFile+ svgBS = renderSvg svg+ BS.writeFile cached svgBS+ url' <- if dataURIs+ then return (newURL (mkDataURI svgBS))+ else (copyFile cached outFile >> return (newURL outFile)) logStrLn "compiled."- return newURL+ return url' where mkCached base = cacheDir </> base <.> "svg" logStr = when (not quiet) . putStr logStrLn = when (not quiet) . putStrLn+ mkDataURI svg = "data:image/svg+xml;base64," ++ BS8.unpack (BS64.encode svg) -- | Compile all the diagrams referenced in an entire module. compileDiagrams :: Bool -- ^ @True@ = quiet+ -> Bool -- ^ @True@ = generate data URIs -> FilePath -- ^ cache directory -> FilePath -- ^ output directory+ -> FilePath -- ^ file being processed -> S.Set String -- ^ diagram names referenced from URLs -> [CodeBlock] -> [Either String DiagramURL] -> IO ([Either String DiagramURL], Bool)-compileDiagrams quiet cacheDir outputDir ds cs urls = do+compileDiagrams quiet dataURIs cacheDir outputDir file ds cs urls = do urls' <- urls & (traverse . _Right)- %%~ compileDiagram quiet cacheDir outputDir ds cs+ %%~ compileDiagram quiet dataURIs cacheDir outputDir file ds cs let changed = orOf (traverse . _Right . _2) urls' return (urls' & (traverse . _Right) %~ fst, changed) @@ -495,6 +514,7 @@ -- Returns a list of warnings and/or errors. processHaddockDiagrams :: Bool -- ^ quiet+ -> Bool -- ^ generate data URIs? -> FilePath -- ^ cache directory -> FilePath -- ^ output directory -> FilePath -- ^ file to be processed@@ -508,11 +528,12 @@ processHaddockDiagrams' :: CpphsOptions -- ^ Options for cpphs -> Bool -- ^ quiet+ -> Bool -- ^ generate data URIs? -> FilePath -- ^ cache directory -> FilePath -- ^ output directory -> FilePath -- ^ file to be processed -> IO [String]-processHaddockDiagrams' opts quiet cacheDir outputDir file = do+processHaddockDiagrams' opts quiet dataURIs cacheDir outputDir file = do e <- doesFileExist file case e of False -> return ["Error: " ++ file ++ " not found."]@@ -529,7 +550,15 @@ Left _ -> error "This case can never happen; see prop_parseDiagramURLs_succeeds" Right urls -> do- (urls', changed) <- compileDiagrams quiet cacheDir outputDir ds cs urls+ (urls', changed) <- compileDiagrams+ quiet+ dataURIs+ cacheDir+ outputDir+ file+ ds+ cs+ urls let src' = displayDiagramURLs urls' -- See https://github.com/diagrams/diagrams-haddock/issues/8:
tools/diagrams-haddock.hs view
@@ -8,6 +8,7 @@ import Diagrams.Haddock import System.Console.CmdArgs import System.Directory+import System.Environment (getEnvironment) import System.FilePath ((<.>), (</>)) import Distribution.ModuleName (toFilePath)@@ -22,9 +23,10 @@ data DiagramsHaddock = DiagramsHaddock { quiet :: Bool+ , dataURIs :: Bool , cacheDir :: FilePath , outputDir :: FilePath- , distDir :: FilePath+ , distDir :: Maybe FilePath , includeDirs :: [FilePath] , cppDefines :: [String] , targets :: [FilePath]@@ -37,10 +39,15 @@ { quiet = False &= help "Suppress normal logging output" + , dataURIs = False+ &= help "Generate embedded data URIs instead of external SVGs"+ &= name "dataURIs"+ , cacheDir = ".diagrams-cache" &= typDir &= help "Directory for storing cached diagrams (default: .diagrams-cache)"+ &= name "c" , outputDir = "diagrams"@@ -48,9 +55,10 @@ &= help "Directory to output compiled diagrams (default: diagrams)" , distDir- = "dist"+ = def &= typDir &= help "Directory in which to look for setup-config (default: dist)"+ &= name "d" , includeDirs = []@@ -102,6 +110,17 @@ -- or any unexported modules. processCabalPackage :: DiagramsHaddock -> FilePath -> IO () processCabalPackage opts dir = do+ mhsenv <- getHsenv+ let fullDistDir = dir </> case (distDir opts, mhsenv) of+ -- command-line arg trumps all+ (Just d, _) -> d++ -- next, look for active hsenv+ (Nothing, Just hsenv) -> "dist_" ++ hsenv++ -- otherwise, default to "dist"+ _ -> "dist"+ mlbi <- maybeGetPersistBuildConfig fullDistDir case mlbi of Nothing -> putStrLn $@@ -121,7 +140,10 @@ cabalDefines = parseCabalDefines defines mapM_ (tryProcessFile opts' cabalDefines dir srcDirs) . map toFilePath . P.exposedModules $ lib - where fullDistDir = dir </> distDir opts+getHsenv :: IO (Maybe String)+getHsenv = do+ env <- getEnvironment+ return $ lookup "HSENV_NAME" env -- | Use @cpphs@'s options parser to handle the options from cabal. parseCabalDefines :: [String] -> [(String,String)]@@ -149,7 +171,7 @@ -- | Process a single file with diagrams-haddock. processFile :: DiagramsHaddock -> [(String,String)] -> FilePath -> IO () processFile opts defines file = do- errs <- processHaddockDiagrams' cpphsOpts (quiet opts) (cacheDir opts) (outputDir opts) file+ errs <- processHaddockDiagrams' cpphsOpts (quiet opts) (dataURIs opts) (cacheDir opts) (outputDir opts) file case errs of [] -> return () _ -> putStrLn $ intercalate "\n" errs