{-# LANGUAGE OverloadedStrings #-} {-| Module : Text.Pandoc.Filter.Pyplot.Configuration Copyright : (c) Laurent P René de Cotret, 2019 License : MIT Maintainer : laurent.decotret@outlook.com Stability : internal Portability : portable Configuration for pandoc-pyplot -} module Text.Pandoc.Filter.Pyplot.Configuration ( configuration -- * For testing and internal purposes only , inclusionKeys , directoryKey , captionKey , dpiKey , includePathKey , saveFormatKey ) where import Data.Maybe (fromMaybe) import Data.Default.Class (def) import qualified Data.Text as T import qualified Data.Text.IO as T import Data.Yaml import Data.Yaml.Config (loadYamlSettings, ignoreEnv) 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 :: String directoryKey = "directory" captionKey = "caption" dpiKey = "dpi" includePathKey = "include" saveFormatKey = "format" -- | list of all keys related to pandoc-pyplot. inclusionKeys :: [String] inclusionKeys = [ directoryKey , captionKey , dpiKey , includePathKey , saveFormatKey ] -- A @Configuration@ cannot be directly created from a YAML file -- for two reasons: -- -- * we want to store an include script. However, it makes more sense to -- specify the script path in a YAML file. -- * Save format is best specified by a string, and this must be parsed later -- -- Therefore, we have another type, ConfigPrecursor, which CAN be created directly from -- a YAML file. data ConfigPrecursor = ConfigPrecursor { defaultDirectory_ :: FilePath , defaultIncludePath_ :: Maybe FilePath , defaultSaveFormat_ :: String , defaultDPI_ :: Int , interpreter_ :: String , flags_ :: [String] } instance FromJSON ConfigPrecursor where parseJSON (Object v) = ConfigPrecursor <$> v .:? (T.pack directoryKey) .!= (defaultDirectory def) <*> v .:? (T.pack includePathKey) <*> v .:? (T.pack saveFormatKey) .!= (extension $ defaultSaveFormat def) <*> v .:? (T.pack dpiKey) .!= (defaultDPI def) <*> v .:? "interpreter" .!= (interpreter def) <*> v .:? "flags" .!= (flags def) parseJSON _ = fail "Could not parse the configuration" renderConfiguration :: ConfigPrecursor -> IO Configuration renderConfiguration prec = do includeScript <- fromMaybe mempty $ T.readFile <$> defaultIncludePath_ prec let saveFormat' = fromMaybe (defaultSaveFormat def) $ saveFormatFromString $ defaultSaveFormat_ prec return $ Configuration { defaultDirectory = defaultDirectory_ prec , defaultIncludeScript = includeScript , defaultSaveFormat = saveFormat' , defaultDPI = defaultDPI_ prec , interpreter = interpreter_ prec , flags = flags_ prec } -- | Building configuration from a YAML file. The -- keys are exactly the same as for Markdown code blocks. -- -- If a key is either not present or unreadable, its value will be set -- to the default value. -- -- @since 2.1.0.0 configuration :: FilePath -> IO Configuration configuration fp = loadYamlSettings [fp] [] ignoreEnv >>= renderConfiguration