pencil-1.0.0: src/Pencil/Config.hs
{-|
Pencil Config.
-}
module Pencil.Config
( Config(..)
, defaultConfig
, getSourceDir , setSourceDir
, getOutputDir , setOutputDir
, getEnv , setEnv , updateEnv
, getDisplayValue , setDisplayValue
, getSassOptions , setSassOptions
, getPandocReaderOptions , setPandocReaderOptions
, getPandocWriterOptions , setPandocWriterOptions
)where
import Data.Default (Default)
import Pencil.Env.Internal
import Text.Pandoc.Extensions (disableExtension, Extension(..))
import Text.Sass.Options (defaultSassOptions)
import qualified Data.HashMap.Strict as H
import qualified Data.Text as T
import qualified Text.Pandoc as P
import qualified Text.Pandoc.Highlighting
import qualified Text.Sass as Sass
-- | The main @Config@ needed to build your website. Your app's @Config@ is
-- passed into the 'Pencil.App.PencilApp' monad transformer.
--
-- Use 'defaultConfig' as a starting point, along with the config-modification
-- helpers such as 'setSourceDir'.
--
data Config = Config
{ configSourceDir :: FilePath
, configOutputDir :: FilePath
, configEnv :: Env
, configDisplayValue :: Value -> T.Text
, configSassOptions :: Sass.SassOptions
, configPandocReaderOptions :: P.ReaderOptions
, configPandocWriterOptions :: P.WriterOptions
}
-- 'Data.Default.Default' instance for 'Config'.
instance Default Config where
def = defaultConfig
-- | This default @Config@ gives you everything you need to start.
--
-- Default values:
--
-- @
-- Config
-- { 'configSourceDir' = "site/"
-- , 'configOutputDir' = "out/"
-- , 'configEnv' = HashMap.empty
-- , 'configDisplayValue' = 'toText'
-- , 'configSassOptions' = Text.Sass.Options.defaultSassOptions
-- , 'configPandocReaderOptions' = Text.Pandoc.def {
-- Text.Pandoc.readerExtensions = 'Text.Pandoc.Extensions.disableExtension' 'Text.Pandoc.Extensions.Ext_tex_math_dollars' ('Text.Pandoc.Extensions.getDefaultExtensions' "markdown")
-- }
-- , 'configPandocWriterOptions' = Text.Pandoc.def { Text.Pandoc.writerHighlightStyle = Just Text.Pandoc.Highlighting.monochrome }
-- , 'configDisplayValue = 'toText'
-- }
-- @
--
-- @Ext_tex_math_dollars@ is disabled because it messes with parsing template
-- variable directives. If you want TeX math, the better option is drop in a
-- JavaScript library like KaTeX (https://katex.org).
--
defaultConfig :: Config
defaultConfig = Config
{ configSourceDir = "site/"
, configOutputDir = "out/"
, configEnv = H.empty
, configSassOptions = Text.Sass.Options.defaultSassOptions
-- For markdown reader. We use getDefaultExtensions "markdown" here to get default Markdown extensions.
-- See
-- https://hackage.haskell.org/package/pandoc/docs/Text-Pandoc-Extensions.html#v:getDefaultExtensions
--
-- Ext_text_math_dollars is disabled because it messes with variable
-- directives. For example, this renders weird (as of Pandoc 2.7.2):
-- > **${name}** and **${age}**
, configPandocReaderOptions = P.def {
P.readerExtensions = disableExtension Ext_tex_math_dollars (P.getDefaultExtensions "markdown")
}
, configPandocWriterOptions = P.def {
P.writerHighlightStyle = Just Text.Pandoc.Highlighting.monochrome
}
, configDisplayValue = toText
}
-- | Gets the source directory of your web page source files.
getSourceDir :: Config -> FilePath
getSourceDir = configSourceDir
-- | Sets the source directory of your web page source files.
setSourceDir :: FilePath -> Config -> Config
setSourceDir fp c = c { configSourceDir = fp }
-- | Gets the output directory of your rendered web pages.
getOutputDir :: Config -> FilePath
getOutputDir = configOutputDir
-- | Sets the output directory of your rendered web pages.
setOutputDir :: FilePath -> Config -> Config
setOutputDir fp c = c { configOutputDir = fp }
-- | Gets environment of the @Config@, which is what the @PencilApp@ monad
-- transformer uses. This is where variables are set for rendering template
-- directives.
getEnv :: Config -> Env
getEnv = configEnv
-- | Sets the current environment. You may also want to look at 'Pencil.App.withEnv' if you
-- want to 'Pencil.Content.render' things in a modified environment.
setEnv :: Env -> Config -> Config
setEnv env c = c { configEnv = env }
-- | Updates the Env inside the 'Config'.
updateEnv :: (Env -> Env) -> Config -> Config
updateEnv f c = c { configEnv = f (getEnv c) }
-- | Gets the 'Sass.SassOptions' for rendering Sass/Scss files.
getSassOptions :: Config -> Sass.SassOptions
getSassOptions = configSassOptions
-- | Sets the 'Sass.SassOptions' for rendering Sass/Scss files.
setSassOptions :: Sass.SassOptions -> Config -> Config
setSassOptions env c = c { configSassOptions = env }
-- | Gets the 'Text.Pandoc.ReaderOptions' for reading files that use Pandoc.
-- Supported formats:
--
-- * Markdown
-- * Open a GitHub issue if you'd like to see more options!
--
getPandocReaderOptions :: Config -> P.ReaderOptions
getPandocReaderOptions = configPandocReaderOptions
-- | Sets the 'Text.Pandoc.ReaderOptions'. For example, you may want to enable
-- some Pandoc extensions like 'Text.Pandoc.Extensions.Ext_literate_haskell':
--
-- @
-- setPandocReaderOptions
-- (Text.Pandoc.def { 'Text.Pandoc.Options.readerExtensions' = extensionsFromList [Ext_literate_haskell] })
-- config
-- @
setPandocReaderOptions :: P.ReaderOptions -> Config -> Config
setPandocReaderOptions o c = c { configPandocReaderOptions = o }
-- | Gets the 'Text.Pandoc.WriterOptions' for rendering files that use Pandoc.
getPandocWriterOptions :: Config -> P.WriterOptions
getPandocWriterOptions = configPandocWriterOptions
-- | Sets the 'Text.Pandoc.WriterOptions'.
setPandocWriterOptions :: P.WriterOptions -> Config -> Config
setPandocWriterOptions o c = c { configPandocWriterOptions = o }
-- | Gets the function that renders 'Value' to text.
getDisplayValue :: Config -> Value -> T.Text
getDisplayValue = configDisplayValue
-- | Sets the function that renders 'Value' to text. Overwrite this with your
-- own function if you would like to change how certain 'Value's are rendered
-- (e.g. 'Pencil.Env.Internal.VDateTime').
--
-- @
-- myRender :: Value -> T.Text
-- myRender (VDateTime dt) = 'T.pack' $ 'TF.formatTime' 'TF.defaultTimeLocale' "%e %B %Y" dt
-- myRender t = 'toText' t
--
-- ...
--
-- setDisplayValue myRender config
-- @
--
-- In the above example, we change the @VDateTime@ rendering to show @25
-- December 2017@. Leave everything else unchanged.
--
setDisplayValue :: (Value -> T.Text) -> Config -> Config
setDisplayValue f c = c { configDisplayValue = f }