{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE UndecidableInstances #-}

module Ema.Route.Lib.Extra.PandocRoute (
  -- * Route
  PandocRoute (..),
  mkPandocRoute,

  -- * Model and Arg
  Model (..),
  Arg (..),

  -- * Looking up Pandoc values in model
  lookupPandocRoute,

  -- * Rendering
  PandocHtml (..),
  PandocError (..),
) where

import Control.Exception (throw, throwIO)
import Control.Monad.Logger (
  MonadLogger,
  MonadLoggerIO,
  logInfoNS,
 )
import Data.Default (Default (..))
import Data.List qualified as List
import Data.Map.Strict qualified as Map
import Data.SOP (I (I), NP (..))
import Data.Set qualified as Set
import Ema
import Ema.CLI qualified
import Ema.Route.Generic.TH
import Ema.Route.Lib.Extra.SlugRoute
import Generics.SOP qualified as SOP
import System.FilePath ((</>))
import System.UnionMount qualified as UnionMount
import Text.Pandoc (Pandoc, ReaderOptions, runIO)
import Text.Pandoc qualified as Pandoc
import Text.Pandoc.Sources (ToSources)
import UnliftIO (MonadUnliftIO)

-- | Represents the relative path to a file that pandoc can parse.
newtype PandocRoute = PandocRoute {PandocRoute -> SlugRoute Pandoc
unPandocRoute :: SlugRoute Pandoc}
  deriving stock (PandocRoute -> PandocRoute -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PandocRoute -> PandocRoute -> Bool
$c/= :: PandocRoute -> PandocRoute -> Bool
== :: PandocRoute -> PandocRoute -> Bool
$c== :: PandocRoute -> PandocRoute -> Bool
Eq, Eq PandocRoute
PandocRoute -> PandocRoute -> Bool
PandocRoute -> PandocRoute -> Ordering
PandocRoute -> PandocRoute -> PandocRoute
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PandocRoute -> PandocRoute -> PandocRoute
$cmin :: PandocRoute -> PandocRoute -> PandocRoute
max :: PandocRoute -> PandocRoute -> PandocRoute
$cmax :: PandocRoute -> PandocRoute -> PandocRoute
>= :: PandocRoute -> PandocRoute -> Bool
$c>= :: PandocRoute -> PandocRoute -> Bool
> :: PandocRoute -> PandocRoute -> Bool
$c> :: PandocRoute -> PandocRoute -> Bool
<= :: PandocRoute -> PandocRoute -> Bool
$c<= :: PandocRoute -> PandocRoute -> Bool
< :: PandocRoute -> PandocRoute -> Bool
$c< :: PandocRoute -> PandocRoute -> Bool
compare :: PandocRoute -> PandocRoute -> Ordering
$ccompare :: PandocRoute -> PandocRoute -> Ordering
Ord, Int -> PandocRoute -> ShowS
[PandocRoute] -> ShowS
PandocRoute -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PandocRoute] -> ShowS
$cshowList :: [PandocRoute] -> ShowS
show :: PandocRoute -> String
$cshow :: PandocRoute -> String
showsPrec :: Int -> PandocRoute -> ShowS
$cshowsPrec :: Int -> PandocRoute -> ShowS
Show, forall x. Rep PandocRoute x -> PandocRoute
forall x. PandocRoute -> Rep PandocRoute x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PandocRoute x -> PandocRoute
$cfrom :: forall x. PandocRoute -> Rep PandocRoute x
Generic)
  deriving anyclass (All @[Type] (SListI @Type) (Code PandocRoute)
Rep PandocRoute -> PandocRoute
PandocRoute -> Rep PandocRoute
forall a.
All @[Type] (SListI @Type) (Code a)
-> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep PandocRoute -> PandocRoute
$cto :: Rep PandocRoute -> PandocRoute
from :: PandocRoute -> Rep PandocRoute
$cfrom :: PandocRoute -> Rep PandocRoute
SOP.Generic, Generic PandocRoute
forall a.
Generic a
-> (forall (proxy :: Type -> Type).
    proxy a -> DatatypeInfo (Code a))
-> HasDatatypeInfo a
forall (proxy :: Type -> Type).
proxy PandocRoute -> DatatypeInfo (Code PandocRoute)
datatypeInfo :: forall (proxy :: Type -> Type).
proxy PandocRoute -> DatatypeInfo (Code PandocRoute)
$cdatatypeInfo :: forall (proxy :: Type -> Type).
proxy PandocRoute -> DatatypeInfo (Code PandocRoute)
SOP.HasDatatypeInfo)
  deriving
    (forall {k} (r :: k). HasSubRoutes @k r
HasSubRoutes, RouteModel PandocRoute -> [PandocRoute]
RouteModel PandocRoute -> Prism_ String PandocRoute
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel PandocRoute -> [PandocRoute]
$crouteUniverse :: RouteModel PandocRoute -> [PandocRoute]
routePrism :: RouteModel PandocRoute -> Prism_ String PandocRoute
$croutePrism :: RouteModel PandocRoute -> Prism_ String PandocRoute
IsRoute)
    via ( GenericRoute
            PandocRoute
            '[ WithModel Model
             , WithSubRoutes
                '[ SlugRoute Pandoc
                 ]
             ]
        )

instance HasSubModels PandocRoute where
  subModels :: RouteModel PandocRoute
-> NP @Type I (MultiModel (SubRoutes @Type PandocRoute))
subModels RouteModel PandocRoute
m = forall a. a -> I a
I (forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
Map.mapKeys PandocRoute -> SlugRoute Pandoc
unPandocRoute forall a b. (a -> b) -> a -> b
$ Model -> Map PandocRoute Pandoc
modelPandocs RouteModel PandocRoute
m) forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall {k} (a :: k -> Type). NP @k a ('[] @k)
Nil

instance IsString PandocRoute where
  fromString :: String -> PandocRoute
fromString String
fp = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a t. (HasCallStack, IsText t) => t -> a
error forall a b. (a -> b) -> a -> b
$ Text
"Bad path: " forall a. Semigroup a => a -> a -> a
<> forall a. ToText a => a -> Text
toText String
fp) forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ String -> Maybe (String, PandocRoute)
mkPandocRoute String
fp

mkPandocRoute :: FilePath -> Maybe (String, PandocRoute)
mkPandocRoute :: String -> Maybe (String, PandocRoute)
mkPandocRoute String
fp = do
  (String
ext, SlugRoute Pandoc
r) <- forall a. String -> Maybe (String, SlugRoute a)
mkSlugRoute String
fp
  forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (String
ext, SlugRoute Pandoc -> PandocRoute
PandocRoute SlugRoute Pandoc
r)

data Model = Model
  { Model -> Arg
modelArg :: Arg
  , Model -> Map PandocRoute Pandoc
modelPandocs :: Map PandocRoute Pandoc
  }
  deriving stock (forall x. Rep Model x -> Model
forall x. Model -> Rep Model x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Model x -> Model
$cfrom :: forall x. Model -> Rep Model x
Generic)

lookupPandocRoute :: Model -> PandocRoute -> Maybe (Pandoc, Pandoc -> PandocHtml)
lookupPandocRoute :: Model -> PandocRoute -> Maybe (Pandoc, Pandoc -> PandocHtml)
lookupPandocRoute Model
model PandocRoute
r = do
  Pandoc
pandoc <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup PandocRoute
r forall a b. (a -> b) -> a -> b
$ Model -> Map PandocRoute Pandoc
modelPandocs Model
model
  let render :: Pandoc -> PandocHtml
render = Text -> PandocHtml
PandocHtml forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => WriterOptions -> Pandoc -> Text
renderHtml (Arg -> WriterOptions
argWriterOpts forall a b. (a -> b) -> a -> b
$ Model -> Arg
modelArg Model
model)
  forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Pandoc
pandoc, Pandoc -> PandocHtml
render)
  where
    renderHtml :: HasCallStack => Pandoc.WriterOptions -> Pandoc -> Text
    renderHtml :: HasCallStack => WriterOptions -> Pandoc -> Text
renderHtml WriterOptions
writerSettings Pandoc
pandoc =
      forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a e. Exception e => e -> a
throw forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> PandocError
PandocError_RenderError forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. (Show a, IsString b) => a -> b
show) forall a. a -> a
id forall a b. (a -> b) -> a -> b
$
        forall a. PandocPure a -> Either PandocError a
Pandoc.runPure forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
Pandoc.writeHtml5String WriterOptions
writerSettings Pandoc
pandoc

data Arg = Arg
  { -- Base directory
    Arg -> String
argBaseDir :: FilePath
  , -- Pandoc reader formats supported, as file extension; eg: '.md'
    Arg -> Set String
argFormats :: Set String
  , Arg -> ReaderOptions
argReaderOpts :: Pandoc.ReaderOptions
  , Arg -> WriterOptions
argWriterOpts :: Pandoc.WriterOptions
  }
  deriving stock (forall x. Rep Arg x -> Arg
forall x. Arg -> Rep Arg x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Arg x -> Arg
$cfrom :: forall x. Arg -> Rep Arg x
Generic)

instance Default Arg where
  def :: Arg
def = String -> Set String -> ReaderOptions -> WriterOptions -> Arg
Arg String
"." Set String
formats ReaderOptions
defaultReaderOpts WriterOptions
defaultWriterOpts
    where
      formats :: Set String
formats = forall a. Ord a => [a] -> Set a
Set.fromList [String]
knownPandocFormats
      defaultReaderOpts :: ReaderOptions
defaultReaderOpts = forall a. Default a => a
def {readerExtensions :: Extensions
Pandoc.readerExtensions = Extensions
exts}
      defaultWriterOpts :: WriterOptions
defaultWriterOpts = forall a. Default a => a
def {writerExtensions :: Extensions
Pandoc.writerExtensions = Extensions
exts}
      exts :: Pandoc.Extensions
      exts :: Extensions
exts =
        -- Sensible defaults for Markdown and others
        Extensions
Pandoc.pandocExtensions forall a. Semigroup a => a -> a -> a
<> [Extension] -> Extensions
Pandoc.extensionsFromList [Extension
Pandoc.Ext_attributes]

instance EmaSite PandocRoute where
  type SiteArg PandocRoute = Arg

  -- Returns the `Pandoc` AST along with the function that renders it to HTML.
  type SiteOutput PandocRoute = (Pandoc, Pandoc -> PandocHtml)

  siteInput :: forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLoggerIO m) =>
Some @Type Action
-> SiteArg PandocRoute -> m (Dynamic m (RouteModel PandocRoute))
siteInput Some @Type Action
_ SiteArg PandocRoute
arg = do
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Arg -> Map PandocRoute Pandoc -> Model
Model SiteArg PandocRoute
arg) forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLogger m, MonadLoggerIO m) =>
String
-> Set String
-> ReaderOptions
-> m (Dynamic m (Map PandocRoute Pandoc))
pandocFilesDyn (Arg -> String
argBaseDir SiteArg PandocRoute
arg) (Arg -> Set String
argFormats SiteArg PandocRoute
arg) (Arg -> ReaderOptions
argReaderOpts SiteArg PandocRoute
arg)
  siteOutput :: forall (m :: Type -> Type).
(MonadIO m, MonadLoggerIO m) =>
Prism' String PandocRoute
-> RouteModel PandocRoute
-> PandocRoute
-> m (SiteOutput PandocRoute)
siteOutput Prism' String PandocRoute
_rp RouteModel PandocRoute
model PandocRoute
r = do
    forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => e -> IO a
throwIO forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocError_Missing forall a b. (a -> b) -> a -> b
$ forall b a. (Show a, IsString b) => a -> b
show PandocRoute
r) forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Model -> PandocRoute -> Maybe (Pandoc, Pandoc -> PandocHtml)
lookupPandocRoute RouteModel PandocRoute
model PandocRoute
r

pandocFilesDyn ::
  forall m.
  (MonadIO m, MonadUnliftIO m, MonadLogger m, MonadLoggerIO m) =>
  FilePath ->
  Set String ->
  ReaderOptions ->
  m (Dynamic m (Map PandocRoute Pandoc))
pandocFilesDyn :: forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLogger m, MonadLoggerIO m) =>
String
-> Set String
-> ReaderOptions
-> m (Dynamic m (Map PandocRoute Pandoc))
pandocFilesDyn String
baseDir Set String
formats ReaderOptions
readerOpts = do
  let pats :: [((), String)]
pats =
        forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList Set String
formats forall (f :: Type -> Type) a b. Functor f => f a -> (a -> b) -> f b
<&> \String
ext ->
          ((), String
"**/*" forall a. Semigroup a => a -> a -> a
<> String
ext)
      ignorePats :: [String]
ignorePats = [String
".*"]
      model0 :: Map PandocRoute Pandoc
model0 = forall a. Monoid a => a
mempty
  forall (m :: Type -> Type) a.
(a, (a -> m ()) -> m ()) -> Dynamic m a
Dynamic forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall model (m :: Type -> Type) b.
(MonadIO m, MonadUnliftIO m, MonadLogger m, Show b, Ord b) =>
String
-> [(b, String)]
-> [String]
-> model
-> (b -> String -> FileAction () -> m (model -> model))
-> m (model, (model -> m ()) -> m ())
UnionMount.mount String
baseDir [((), String)]
pats [String]
ignorePats Map PandocRoute Pandoc
model0 (forall a b. a -> b -> a
const (MonadIO m, MonadLogger m, MonadLoggerIO m) =>
String
-> FileAction ()
-> m (Map PandocRoute Pandoc -> Map PandocRoute Pandoc)
handleUpdate)
  where
    -- Take the file that got changed and update our in-memory `Model` accordingly.
    handleUpdate ::
      (MonadIO m, MonadLogger m, MonadLoggerIO m) =>
      FilePath ->
      UnionMount.FileAction () ->
      m (Map PandocRoute Pandoc -> Map PandocRoute Pandoc)
    handleUpdate :: (MonadIO m, MonadLogger m, MonadLoggerIO m) =>
String
-> FileAction ()
-> m (Map PandocRoute Pandoc -> Map PandocRoute Pandoc)
handleUpdate String
fp = \case
      UnionMount.Refresh RefreshAction
_ ()
_ -> do
        Maybe (PandocRoute, Pandoc)
mData <- (MonadIO m, MonadLogger m, MonadLoggerIO m) =>
String -> m (Maybe (PandocRoute, Pandoc))
readSource String
fp
        forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert) Maybe (PandocRoute, Pandoc)
mData
      FileAction ()
UnionMount.Delete ->
        forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id (forall k a. Ord k => k -> Map k a -> Map k a
Map.delete forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) forall a b. (a -> b) -> a -> b
$ String -> Maybe (String, PandocRoute)
mkPandocRoute String
fp
    readSource :: (MonadIO m, MonadLogger m, MonadLoggerIO m) => FilePath -> m (Maybe (PandocRoute, Pandoc))
    readSource :: (MonadIO m, MonadLogger m, MonadLoggerIO m) =>
String -> m (Maybe (PandocRoute, Pandoc))
readSource String
fp = forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT forall a b. (a -> b) -> a -> b
$ do
      (String
ext, PandocRoute
r :: PandocRoute) <- forall (m :: Type -> Type) a.
Applicative m =>
Maybe a -> MaybeT m a
hoistMaybe (String -> Maybe (String, PandocRoute)
mkPandocRoute String
fp)
      forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ String
ext forall a. Ord a => a -> Set a -> Bool
`Set.member` Set String
formats
      forall (m :: Type -> Type). MonadLogger m => Text -> m ()
log forall a b. (a -> b) -> a -> b
$ Text
"Reading " forall a. Semigroup a => a -> a -> a
<> forall a. ToText a => a -> Text
toText String
fp
      Text
s :: Text <- forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type). MonadIO m => String -> m ByteString
readFileBS forall a b. (a -> b) -> a -> b
$ String
baseDir String -> ShowS
</> String
fp
      forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO (forall a. PandocIO a -> IO (Either PandocError a)
runIO forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> String -> a -> m Pandoc
readPandocSource ReaderOptions
readerOpts String
ext Text
s) forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left PandocError
err -> forall (m :: Type -> Type) a.
(MonadLoggerIO m, MonadFail m) =>
Text -> Text -> m a
Ema.CLI.crash Text
"PandocRoute" forall a b. (a -> b) -> a -> b
$ forall b a. (Show a, IsString b) => a -> b
show PandocError
err
        Right Pandoc
doc -> do
          forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (PandocRoute
r, Pandoc
doc)

log :: MonadLogger m => Text -> m ()
log :: forall (m :: Type -> Type). MonadLogger m => Text -> m ()
log = forall (m :: Type -> Type). MonadLogger m => Text -> Text -> m ()
logInfoNS Text
"PandocRoute"

data PandocError
  = PandocError_Missing Text
  | PandocError_RenderError Text
  deriving stock (PandocError -> PandocError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PandocError -> PandocError -> Bool
$c/= :: PandocError -> PandocError -> Bool
== :: PandocError -> PandocError -> Bool
$c== :: PandocError -> PandocError -> Bool
Eq, Int -> PandocError -> ShowS
[PandocError] -> ShowS
PandocError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PandocError] -> ShowS
$cshowList :: [PandocError] -> ShowS
show :: PandocError -> String
$cshow :: PandocError -> String
showsPrec :: Int -> PandocError -> ShowS
$cshowsPrec :: Int -> PandocError -> ShowS
Show)
  deriving anyclass (Show PandocError
Typeable @Type PandocError
SomeException -> Maybe PandocError
PandocError -> String
PandocError -> SomeException
forall e.
Typeable @Type e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: PandocError -> String
$cdisplayException :: PandocError -> String
fromException :: SomeException -> Maybe PandocError
$cfromException :: SomeException -> Maybe PandocError
toException :: PandocError -> SomeException
$ctoException :: PandocError -> SomeException
Exception)

newtype PandocHtml = PandocHtml {PandocHtml -> Text
unPandocHtml :: Text}
  deriving stock (PandocHtml -> PandocHtml -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PandocHtml -> PandocHtml -> Bool
$c/= :: PandocHtml -> PandocHtml -> Bool
== :: PandocHtml -> PandocHtml -> Bool
$c== :: PandocHtml -> PandocHtml -> Bool
Eq, forall x. Rep PandocHtml x -> PandocHtml
forall x. PandocHtml -> Rep PandocHtml x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PandocHtml x -> PandocHtml
$cfrom :: forall x. PandocHtml -> Rep PandocHtml x
Generic)

-- Pandoc reader abstraction
--
-- TODO: Can we refactor this using,
-- https://github.com/jgm/pandoc/blob/16f0316fbaa4d667ba40772969ab8e28fea6a493/src/Text/Pandoc/App/FormatHeuristics.hs#L36

knownPandocFormats :: [String]
knownPandocFormats :: [String]
knownPandocFormats = [String
".md", String
".org"]

formatFromExt :: String -> Text
formatFromExt :: String -> Text
formatFromExt = \case
  String
".md" -> Text
"markdown"
  String
".org" -> Text
"org"
  String
ext -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> UnsupportedPandocFormat
UnsupportedPandocFormat String
ext

readPandocSource ::
  forall m a.
  (Pandoc.PandocMonad m, ToSources a) =>
  ReaderOptions ->
  [Char] ->
  a ->
  m Pandoc
readPandocSource :: forall (m :: Type -> Type) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> String -> a -> m Pandoc
readPandocSource ReaderOptions
readerOpts String
ext a
s =
  case forall a b. Eq a => a -> [(a, b)] -> Maybe b
List.lookup (String -> Text
formatFromExt String
ext) forall (m :: Type -> Type). PandocMonad m => [(Text, Reader m)]
Pandoc.readers of
    Just (Pandoc.TextReader forall a. ToSources a => ReaderOptions -> a -> m Pandoc
f) -> forall a. ToSources a => ReaderOptions -> a -> m Pandoc
f ReaderOptions
readerOpts a
s
    Maybe (Reader m)
_ -> forall a e. Exception e => e -> a
throw forall a b. (a -> b) -> a -> b
$ String -> UnsupportedPandocFormat
UnsupportedPandocFormat String
ext

data UnsupportedPandocFormat = UnsupportedPandocFormat String
  deriving stock (UnsupportedPandocFormat -> UnsupportedPandocFormat -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnsupportedPandocFormat -> UnsupportedPandocFormat -> Bool
$c/= :: UnsupportedPandocFormat -> UnsupportedPandocFormat -> Bool
== :: UnsupportedPandocFormat -> UnsupportedPandocFormat -> Bool
$c== :: UnsupportedPandocFormat -> UnsupportedPandocFormat -> Bool
Eq, Int -> UnsupportedPandocFormat -> ShowS
[UnsupportedPandocFormat] -> ShowS
UnsupportedPandocFormat -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UnsupportedPandocFormat] -> ShowS
$cshowList :: [UnsupportedPandocFormat] -> ShowS
show :: UnsupportedPandocFormat -> String
$cshow :: UnsupportedPandocFormat -> String
showsPrec :: Int -> UnsupportedPandocFormat -> ShowS
$cshowsPrec :: Int -> UnsupportedPandocFormat -> ShowS
Show)
  deriving anyclass (Show UnsupportedPandocFormat
Typeable @Type UnsupportedPandocFormat
SomeException -> Maybe UnsupportedPandocFormat
UnsupportedPandocFormat -> String
UnsupportedPandocFormat -> SomeException
forall e.
Typeable @Type e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: UnsupportedPandocFormat -> String
$cdisplayException :: UnsupportedPandocFormat -> String
fromException :: SomeException -> Maybe UnsupportedPandocFormat
$cfromException :: SomeException -> Maybe UnsupportedPandocFormat
toException :: UnsupportedPandocFormat -> SomeException
$ctoException :: UnsupportedPandocFormat -> SomeException
Exception)