aboutsummaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Templates.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text/Pandoc/Templates.hs')
-rw-r--r--src/Text/Pandoc/Templates.hs61
1 files changed, 58 insertions, 3 deletions
diff --git a/src/Text/Pandoc/Templates.hs b/src/Text/Pandoc/Templates.hs
index 8d92e306b..daf9c02fb 100644
--- a/src/Text/Pandoc/Templates.hs
+++ b/src/Text/Pandoc/Templates.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE OverloadedStrings #-}
@@ -14,18 +15,61 @@ Utility functions for working with pandoc templates.
-}
module Text.Pandoc.Templates ( Template
+ , WithDefaultPartials(..)
+ , WithPartials(..)
, compileTemplate
, renderTemplate
+ , getTemplate
, getDefaultTemplate
+ , compileDefaultTemplate
) where
import Prelude
import System.FilePath ((<.>), (</>))
-import Text.DocTemplates (Template, compileTemplate, renderTemplate)
-import Text.Pandoc.Class (PandocMonad, readDataFile)
+import Text.DocTemplates (Template, TemplateMonad(..), compileTemplate, renderTemplate)
+import Text.Pandoc.Class (PandocMonad, readDataFile, fetchItem,
+ CommonState(..), getCommonState, modifyCommonState)
import qualified Text.Pandoc.UTF8 as UTF8
+import Control.Monad.Except (catchError, throwError)
import Data.Text (Text)
import qualified Data.Text as T
+import Text.Pandoc.Error
+
+-- | Wrap a Monad in this if you want partials to
+-- be taken only from the default data files.
+newtype WithDefaultPartials m a = WithDefaultPartials { runWithDefaultPartials :: m a }
+ deriving (Functor, Applicative, Monad)
+
+-- | Wrap a Monad in this if you want partials to
+-- be looked for locally (or, when the main template
+-- is at a URL, via HTTP), falling back to default data files.
+newtype WithPartials m a = WithPartials { runWithPartials :: m a }
+ deriving (Functor, Applicative, Monad)
+
+instance PandocMonad m => TemplateMonad (WithDefaultPartials m) where
+ getPartial fp = WithDefaultPartials $
+ UTF8.toText <$> readDataFile fp
+
+instance PandocMonad m => TemplateMonad (WithPartials m) where
+ getPartial fp = WithPartials $ getTemplate fp
+
+-- | Retrieve text for a template.
+getTemplate :: PandocMonad m => FilePath -> m Text
+getTemplate tp = UTF8.toText <$>
+ ((do surl <- stSourceURL <$> getCommonState
+ -- we don't want to look for templates remotely
+ -- unless the full URL is specified:
+ modifyCommonState $ \st -> st{
+ stSourceURL = Nothing }
+ (bs, _) <- fetchItem $ T.pack tp
+ modifyCommonState $ \st -> st{
+ stSourceURL = surl }
+ return bs)
+ `catchError`
+ (\e -> case e of
+ PandocResourceNotFound _ ->
+ readDataFile ("templates" </> tp)
+ _ -> throwError e))
-- | Get default template for the specified writer.
getDefaultTemplate :: PandocMonad m
@@ -55,4 +99,15 @@ getDefaultTemplate writer = do
let fname = "templates" </> "default" <.> T.unpack format
UTF8.toText <$> readDataFile fname
-
+-- | Get and compile default template for the specified writer.
+-- Raise an error on compilation failure.
+compileDefaultTemplate :: PandocMonad m
+ => Text
+ -> m (Template Text)
+compileDefaultTemplate writer = do
+ res <- getDefaultTemplate writer >>=
+ runWithDefaultPartials .
+ compileTemplate ("templates/default." <> T.unpack writer)
+ case res of
+ Left e -> throwError $ PandocTemplateError (T.pack e)
+ Right t -> return t