{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-} {-| Module : $header$ Copyright : (c) Laurent P René de Cotret, 2020 License : GNU GPL, version 2 or above Maintainer : laurent.decotret@outlook.com Stability : internal Portability : portable Rendering Bokeh code blocks -} module Text.Pandoc.Filter.Plot.Renderers.Bokeh ( bokehSupportedSaveFormats , bokehCommand , bokehCapture , bokehAvailable , bokehCheckIfShow ) where import Data.Monoid (Any(..)) import qualified Data.Text as T import Text.Pandoc.Filter.Plot.Renderers.Prelude bokehSupportedSaveFormats :: [SaveFormat] bokehSupportedSaveFormats = [PNG, SVG, HTML] bokehCommand :: OutputSpec -> PlotM Text bokehCommand OutputSpec{..} = do exe <- executable Bokeh return [st|#{exe} "#{oScriptPath}"|] bokehAvailable :: PlotM Bool bokehAvailable = do exe <- executable Bokeh commandSuccess [st|#{exe} -c "import bokeh; import selenium"|] -- | Check if `matplotlib.pyplot.show()` calls are present in the script, -- which would halt pandoc-plot bokehCheckIfShow :: Script -> CheckResult bokehCheckIfShow s = if getAny $ mconcat showPresent then CheckFailed "encountered a call to `bokeh.io.show`." else CheckPassed where showPresent = (\n -> Any (T.isInfixOf n s)) <$> [ "bokeh.io.show(" , "show(" ] bokehCapture :: FigureSpec -> FilePath -> Script bokehCapture FigureSpec{..} fname = [st| from bokeh.io import export_png, export_svgs, save from bokeh.models import Model from bokeh.resources import CDN # The heuristic to determine the current Model is to find all objects which are # at least subclasses of bokeh.models.Model, and then find the one which was # created last. This is a dirty hack, so if you're reading this, don't hesitate to # suggest something else. __current_model = [obj for obj in globals().values() if isinstance(obj, Model)][-1] #{write} |] where write = case saveFormat of HTML -> [st|save(__current_model, filename=r"#{fname}", resources=CDN)|] SVG -> [st|__current_model.output_backend="svg"; export_svgs(__current_model, filename=r"#{fname}")|] PNG -> [st|export_png(obj = __current_model, filename=r"#{fname}")|] fmt -> error $ "Save format not supported: " <> show fmt