summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Filter
diff options
context:
space:
mode:
authorLaurentRDC <>2019-08-07 17:32:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2019-08-07 17:32:00 (GMT)
commit202fd079c256b36a0182282d1f05ff64e161650c (patch)
tree24235cf6783c041d7422554e64727668279a7854 /src/Text/Pandoc/Filter
parent3776ee96691a4874ed7a12fe6ab260983de62293 (diff)
version 2.1.5.02.1.5.0
Diffstat (limited to 'src/Text/Pandoc/Filter')
-rw-r--r--src/Text/Pandoc/Filter/Pyplot/Configuration.hs39
-rw-r--r--src/Text/Pandoc/Filter/Pyplot/FigureSpec.hs49
-rw-r--r--src/Text/Pandoc/Filter/Pyplot/Types.hs91
3 files changed, 105 insertions, 74 deletions
diff --git a/src/Text/Pandoc/Filter/Pyplot/Configuration.hs b/src/Text/Pandoc/Filter/Pyplot/Configuration.hs
index 0bc924d..ae2af6b 100644
--- a/src/Text/Pandoc/Filter/Pyplot/Configuration.hs
+++ b/src/Text/Pandoc/Filter/Pyplot/Configuration.hs
@@ -21,6 +21,8 @@ module Text.Pandoc.Filter.Pyplot.Configuration (
, includePathKey
, saveFormatKey
, withLinksKey
+ , isTightBboxKey
+ , isTransparentKey
) where
import Data.Maybe (fromMaybe)
@@ -34,25 +36,6 @@ import System.Directory (doesFileExist)
import Text.Pandoc.Filter.Pyplot.Types
--- | Keys that pandoc-pyplot will look for in code blocks. These are only exported for testing purposes.
-directoryKey, captionKey, dpiKey, includePathKey, saveFormatKey, withLinksKey :: String
-directoryKey = "directory"
-captionKey = "caption"
-dpiKey = "dpi"
-includePathKey = "include"
-saveFormatKey = "format"
-withLinksKey = "links"
-
--- | list of all keys related to pandoc-pyplot.
-inclusionKeys :: [String]
-inclusionKeys = [ directoryKey
- , captionKey
- , dpiKey
- , includePathKey
- , saveFormatKey
- , withLinksKey
- ]
-
-- A @Configuration@ cannot be directly created from a YAML file
-- for two reasons:
--
@@ -69,19 +52,23 @@ data ConfigPrecursor
, defaultWithLinks_ :: Bool
, defaultSaveFormat_ :: String
, defaultDPI_ :: Int
+ , tightBbox_ :: Bool
+ , transparent_ :: Bool
, interpreter_ :: String
, flags_ :: [String]
}
instance FromJSON ConfigPrecursor where
parseJSON (Object v) = ConfigPrecursor
- <$> v .:? (T.pack directoryKey) .!= (defaultDirectory def)
+ <$> v .:? (T.pack directoryKey) .!= (defaultDirectory def)
<*> v .:? (T.pack includePathKey)
- <*> v .:? (T.pack withLinksKey) .!= (defaultWithLinks def)
- <*> v .:? (T.pack saveFormatKey) .!= (extension $ defaultSaveFormat def)
- <*> v .:? (T.pack dpiKey) .!= (defaultDPI def)
- <*> v .:? "interpreter" .!= (interpreter def)
- <*> v .:? "flags" .!= (flags def)
+ <*> v .:? (T.pack withLinksKey) .!= (defaultWithLinks def)
+ <*> v .:? (T.pack saveFormatKey) .!= (extension $ defaultSaveFormat def)
+ <*> v .:? (T.pack dpiKey) .!= (defaultDPI def)
+ <*> v .:? (T.pack isTightBboxKey) .!= (isTightBbox def)
+ <*> v .:? (T.pack isTransparentKey) .!= (isTransparent def)
+ <*> v .:? "interpreter" .!= (interpreter def)
+ <*> v .:? "flags" .!= (flags def)
parseJSON _ = fail "Could not parse the configuration"
@@ -94,6 +81,8 @@ renderConfiguration prec = do
, defaultSaveFormat = saveFormat'
, defaultWithLinks = defaultWithLinks_ prec
, defaultDPI = defaultDPI_ prec
+ , isTightBbox = tightBbox_ prec
+ , isTransparent = transparent_ prec
, interpreter = interpreter_ prec
, flags = flags_ prec
}
diff --git a/src/Text/Pandoc/Filter/Pyplot/FigureSpec.hs b/src/Text/Pandoc/Filter/Pyplot/FigureSpec.hs
index 357d5a4..f7005e5 100644
--- a/src/Text/Pandoc/Filter/Pyplot/FigureSpec.hs
+++ b/src/Text/Pandoc/Filter/Pyplot/FigureSpec.hs
@@ -50,7 +50,6 @@ import Text.Pandoc.Options (ReaderOptions(..))
import Text.Pandoc.Readers (readMarkdown)
import Text.Pandoc.Filter.Pyplot.Types
-import Text.Pandoc.Filter.Pyplot.Configuration
-- | Determine inclusion specifications from Block attributes.
@@ -67,18 +66,21 @@ parseFigureSpec config (CodeBlock (id', cls, attrs) content)
figureSpec :: IO FigureSpec
figureSpec = do
includeScript <- fromMaybe (return $ defaultIncludeScript config) $ T.readFile <$> includePath
- let header = "# Generated by pandoc-pyplot " <> ((T.pack . showVersion) version)
- fullScript = mconcat $ intersperse "\n" [header, includeScript, T.pack content]
- caption' = Map.findWithDefault mempty captionKey attrs'
- format = fromMaybe (defaultSaveFormat config) $ join $ saveFormatFromString <$> Map.lookup saveFormatKey attrs'
- dir = makeValid $ Map.findWithDefault (defaultDirectory config) directoryKey attrs'
- dpi' = fromMaybe (defaultDPI config) $ read <$> Map.lookup dpiKey attrs'
- withLinks' = fromMaybe (defaultWithLinks config) $ readBool <$> Map.lookup withLinksKey attrs'
- blockAttrs' = (id', filter (/= "pyplot") cls, filteredAttrs)
- return $ FigureSpec caption' withLinks' fullScript format dir dpi' blockAttrs'
+ let header = "# Generated by pandoc-pyplot " <> ((T.pack . showVersion) version)
+ fullScript = mconcat $ intersperse "\n" [header, includeScript, T.pack content]
+ caption' = Map.findWithDefault mempty captionKey attrs'
+ format = fromMaybe (defaultSaveFormat config) $ join $ saveFormatFromString <$> Map.lookup saveFormatKey attrs'
+ dir = makeValid $ Map.findWithDefault (defaultDirectory config) directoryKey attrs'
+ dpi' = fromMaybe (defaultDPI config) $ read <$> Map.lookup dpiKey attrs'
+ withLinks' = fromMaybe (defaultWithLinks config) $ readBool <$> Map.lookup withLinksKey attrs'
+ tightBbox' = isTightBbox config
+ transparent' = isTransparent config
+ blockAttrs' = (id', filter (/= "pyplot") cls, filteredAttrs)
+ return $ FigureSpec caption' withLinks' fullScript format dir dpi' tightBbox' transparent' blockAttrs'
parseFigureSpec _ _ = return Nothing
+
-- | Convert a FigureSpec to a Pandoc block component
toImage :: FigureSpec -> Block
toImage spec = head . toList $ para $ imageWith attrs' target' "fig:" caption'
@@ -95,6 +97,7 @@ toImage spec = head . toList $ para $ imageWith attrs' target' "fig:" caption'
captionLinks = mconcat [" (", srcLink, ", ", hiresLink, ")"]
caption' = if withLinks' then captionText <> captionLinks else captionText
+
-- | Determine the path a figure should have.
figurePath :: FigureSpec -> FilePath
figurePath spec = directory spec </> stem spec
@@ -102,16 +105,19 @@ figurePath spec = directory spec </> stem spec
stem = flip addExtension ext . show . hash
ext = extension . saveFormat $ spec
+
-- | Determine the path to the source code that generated the figure.
sourceCodePath :: FigureSpec -> FilePath
sourceCodePath = flip replaceExtension ".txt" . figurePath
+
-- | The path to the high-resolution figure.
hiresFigurePath :: FigureSpec -> FilePath
hiresFigurePath spec = flip replaceExtension (".hires" <> ext) . figurePath $ spec
where
ext = extension . saveFormat $ spec
+
-- | Modify a Python plotting script to save the figure to a filename.
-- An additional file will also be captured.
addPlotCapture :: FigureSpec -- ^ Path where to save the figure
@@ -124,14 +130,20 @@ addPlotCapture spec =
, plotCapture (hiresFigurePath spec) (minimum [200, 2 * dpi spec])
]
where
- plotCapture fname' dpi' =
- mconcat
- [ "\nplt.savefig("
- , T.pack $ show fname' -- show is required for quotes
- , ", dpi="
- , T.pack $ show dpi'
- , ")"
- ]
+ tight' = tightBbox spec
+ transparent' = transparent spec
+ plotCapture fname' dpi' = mconcat $
+ [ "\nplt.savefig("
+ , T.pack $ show fname' -- show is required for quotes
+ , ", dpi="
+ , T.pack $ show dpi'
+ , ", transparent="
+ , T.pack $ show transparent'
+ , if tight'
+ then ", bbox_inches=\"tight\")"
+ else ")"
+ ]
+
-- | Reader options for captions.
readerOptions :: ReaderOptions
@@ -145,6 +157,7 @@ readerOptions = def
]
}
+
-- | Read a figure caption in Markdown format. LaTeX math @$...$@ is supported,
-- as are Markdown subscripts and superscripts.
captionReader :: String -> Maybe [Inline]
diff --git a/src/Text/Pandoc/Filter/Pyplot/Types.hs b/src/Text/Pandoc/Filter/Pyplot/Types.hs
index 1f1caaf..408cbde 100644
--- a/src/Text/Pandoc/Filter/Pyplot/Types.hs
+++ b/src/Text/Pandoc/Filter/Pyplot/Types.hs
@@ -1,5 +1,6 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE DeriveGeneric #-}
{-|
Module : Text.Pandoc.Filter.Pyplot.Types
Copyright : (c) Laurent P René de Cotret, 2019
@@ -15,14 +16,41 @@ module Text.Pandoc.Filter.Pyplot.Types where
import Data.Char (toLower)
import Data.Default.Class (Default, def)
-import Data.Hashable (Hashable, hashWithSalt)
+import Data.Hashable (Hashable)
import Data.Semigroup as Sem
-import Data.Text (Text)
+import Data.Text (Text, pack)
import Data.Yaml
+import GHC.Generics (Generic)
+
import Text.Pandoc.Definition (Attr)
+-- | Keys that pandoc-pyplot will look for in code blocks. These are only exported for testing purposes.
+directoryKey, captionKey, dpiKey, includePathKey, saveFormatKey, withLinksKey, isTightBboxKey, isTransparentKey :: String
+directoryKey = "directory"
+captionKey = "caption"
+dpiKey = "dpi"
+includePathKey = "include"
+saveFormatKey = "format"
+withLinksKey = "links"
+isTightBboxKey = "tight_bbox"
+isTransparentKey = "transparent"
+
+-- | list of all keys related to pandoc-pyplot that
+-- can be specified in source material.
+inclusionKeys :: [String]
+inclusionKeys = [ directoryKey
+ , captionKey
+ , dpiKey
+ , includePathKey
+ , saveFormatKey
+ , withLinksKey
+ , isTightBboxKey
+ , isTransparentKey
+ ]
+
+
-- | String representation of a Python script
type PythonScript = Text
@@ -73,7 +101,9 @@ data SaveFormat
| EPS
| GIF
| TIF
- deriving (Bounded, Enum, Eq, Show)
+ deriving (Bounded, Enum, Eq, Show, Generic)
+
+instance Hashable SaveFormat -- From Generic
-- | Parse an image save format string
--
@@ -125,6 +155,8 @@ data Configuration
, defaultWithLinks :: Bool -- ^ The default behavior of whether or not to include links to source code and high-res
, defaultSaveFormat :: SaveFormat -- ^ The default save format of generated figures.
, defaultDPI :: Int -- ^ The default dots-per-inch value for generated figures.
+ , isTightBbox :: Bool -- ^ Whether the figures should be saved with @bbox_inches="tight"@ or not. Useful for larger figures with subplots.
+ , isTransparent :: Bool -- ^ If True, figures will be saved with transparent background rather than solid color.
, interpreter :: String -- ^ The name of the interpreter to use to render figures.
, flags :: [String] -- ^ Command-line flags to be passed to the Python interpreger, e.g. ["-O", "-Wignore"]
}
@@ -137,22 +169,26 @@ instance Default Configuration where
, defaultWithLinks = True
, defaultSaveFormat = PNG
, defaultDPI = 80
+ , isTightBbox = False
+ , isTransparent = False
, interpreter = defaultPlatformInterpreter
, flags = mempty
}
instance ToJSON Configuration where
- toJSON (Configuration dir' _ withLinks' savefmt' dpi' interp' flags') =
+ toJSON (Configuration dir' _ withLinks' savefmt' dpi' tightbbox' transparent' interp' flags') =
-- We ignore the include script as we want to examplify that
-- this is for a filepath
- object [ "directory" .= dir'
- , "include" .= ("example.py" :: FilePath)
- , "links" .= withLinks'
- , "dpi" .= dpi'
- , "format" .= (toLower <$> show savefmt')
- , "interpreter" .= interp'
- , "flags" .= flags'
- ]
+ object [ pack directoryKey .= dir'
+ , pack includePathKey .= ("example.py" :: FilePath)
+ , pack withLinksKey .= withLinks'
+ , pack dpiKey .= dpi'
+ , pack saveFormatKey .= (toLower <$> show savefmt')
+ , pack isTightBboxKey .= tightbbox'
+ , pack isTransparentKey .= transparent'
+ , "interpreter" .= interp'
+ , "flags" .= flags'
+ ]
-- | Datatype containing all parameters required to run pandoc-pyplot.
@@ -160,22 +196,15 @@ instance ToJSON Configuration where
-- It is assumed that once a @FigureSpec@ has been created, no configuration
-- can overload it; hence, a @FigureSpec@ completely encodes a particular figure.
data FigureSpec = FigureSpec
- { caption :: String -- ^ Figure caption.
- , withLinks :: Bool -- ^ Append links to source code and high-dpi figure to caption
- , script :: PythonScript -- ^ Source code for the figure.
- , saveFormat :: SaveFormat -- ^ Save format of the figure
- , directory :: FilePath -- ^ Directory where to save the file
- , dpi :: Int -- ^ Dots-per-inch of figure
- , blockAttrs :: Attr -- ^ Attributes not related to @pandoc-pyplot@ will be propagated.
- }
-
-instance Hashable FigureSpec where
- hashWithSalt salt spec =
- -- Some things are not included in the hash because they do not affect the outcome
- -- of running scripts, e.g. whether links should be shown or not.
- hashWithSalt salt ( caption spec
- , script spec
- , fromEnum . saveFormat $ spec
- , directory spec, dpi spec
- , blockAttrs spec
- )
+ { caption :: String -- ^ Figure caption.
+ , withLinks :: Bool -- ^ Append links to source code and high-dpi figure to caption.
+ , script :: PythonScript -- ^ Source code for the figure.
+ , saveFormat :: SaveFormat -- ^ Save format of the figure.
+ , directory :: FilePath -- ^ Directory where to save the file.
+ , dpi :: Int -- ^ Dots-per-inch of figure.
+ , tightBbox :: Bool -- ^ Enforce tight bounding-box with @bbox_inches="tight"@.
+ , transparent :: Bool -- ^ Make figure background transparent.
+ , blockAttrs :: Attr -- ^ Attributes not related to @pandoc-pyplot@ will be propagated.
+ } deriving Generic
+
+instance Hashable FigureSpec -- From Generic