{-# LANGUAGE OverloadedStrings #-}
module Text.Pandoc.Filter.Pyplot.FigureSpec
( FigureSpec(..)
, SaveFormat(..)
, saveFormatFromString
, toImage
, sourceCodePath
, figurePath
, addPlotCapture
, extension
) where
import Control.Monad (join)
import Data.Hashable (hash)
import Data.Maybe (fromMaybe)
import Data.Monoid ((<>))
import qualified Data.Text as T
import System.FilePath (FilePath, addExtension,
replaceExtension, (</>))
import Text.Pandoc.Definition
import Text.Pandoc.Builder (imageWith, link, para, fromList, toList)
import Text.Pandoc.Class (runPure)
import Text.Pandoc.Extensions (extensionsFromList, Extension(..))
import Text.Pandoc.Options (def, ReaderOptions(..))
import Text.Pandoc.Readers (readMarkdown)
import Text.Pandoc.Filter.Pyplot.Types
readerOptions :: ReaderOptions
readerOptions = def
{readerExtensions =
extensionsFromList
[ Ext_tex_math_dollars
, Ext_superscript
, Ext_subscript
]
}
captionReader :: String -> Maybe [Inline]
captionReader t = either (const Nothing) (Just . extractFromBlocks) $ runPure $ readMarkdown' (T.pack t)
where
readMarkdown' = readMarkdown readerOptions
extractFromBlocks (Pandoc _ blocks) = mconcat $ extractInlines <$> blocks
extractInlines (Plain inlines) = inlines
extractInlines (Para inlines) = inlines
extractInlines (LineBlock multiinlines) = join multiinlines
extractInlines _ = []
toImage :: FigureSpec -> Block
toImage spec = head . toList $ para $ imageWith attrs' target' "fig:" caption'
where
attrs' = blockAttrs spec
target' = figurePath spec
srcLink = link (replaceExtension target' ".txt") mempty "Source code"
hiresLink = link (hiresFigurePath spec) mempty "high res."
captionText = fromList $ fromMaybe mempty (captionReader $ caption spec)
captionLinks = mconcat [" (", srcLink, ", ", hiresLink, ")"]
caption' = captionText <> captionLinks
figurePath :: FigureSpec -> FilePath
figurePath spec = directory spec </> stem spec
where
stem = flip addExtension ext . show . hash
ext = extension . saveFormat $ spec
sourceCodePath :: FigureSpec -> FilePath
sourceCodePath = flip replaceExtension ".txt" . figurePath
hiresFigurePath :: FigureSpec -> FilePath
hiresFigurePath spec = flip replaceExtension (".hires" <> ext) . figurePath $ spec
where
ext = extension . saveFormat $ spec
addPlotCapture :: FigureSpec
-> PythonScript
addPlotCapture spec =
mconcat
[ script spec
, "\nimport matplotlib.pyplot as plt"
, plotCapture (figurePath spec) (dpi spec)
, plotCapture (hiresFigurePath spec) (minimum [200, 2 * dpi spec])
]
where
plotCapture fname' dpi' =
mconcat
[ "\nplt.savefig("
, T.pack $ show fname'
, ", dpi="
, T.pack $ show dpi'
, ")"
]