{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE NoImplicitPrelude #-}
{- |
Module      : Text.Pandoc.Lua.Filter
Copyright   : © 2012–2019 John MacFarlane,
              © 2017-2019 Albert Krewinkel
License     : GNU GPL, version 2 or above
Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
Stability   : alpha

Types and functions for running Lua filters.
-}
module Text.Pandoc.Lua.Filter ( LuaFilterFunction
                              , LuaFilter
                              , runFilterFile
                              , tryFilter
                              , runFilterFunction
                              , walkMWithLuaFilter
                              , walkInlines
                              , walkBlocks
                              , blockElementNames
                              , inlineElementNames
                              , module Text.Pandoc.Lua.Walk
                              ) where
import Prelude
import Control.Monad (mplus, (>=>))
import Control.Monad.Catch (finally)
import Data.Data (Data, DataType, dataTypeConstrs, dataTypeName, dataTypeOf,
                  showConstr, toConstr, tyconUQname)
import Data.Foldable (foldrM)
import Data.Map (Map)
import Foreign.Lua (Lua, Peekable, Pushable)
import Text.Pandoc.Definition
import Text.Pandoc.Lua.Marshaling ()
import Text.Pandoc.Lua.Walk (SingletonsList (..))
import Text.Pandoc.Walk (Walkable (walkM))

import qualified Data.Map.Strict as Map
import qualified Foreign.Lua as Lua
import qualified Text.Pandoc.Lua.Util as LuaUtil

-- | Transform document using the filter defined in the given file.
runFilterFile :: FilePath -> Pandoc -> Lua Pandoc
runFilterFile :: FilePath -> Pandoc -> Lua Pandoc
runFilterFile filterPath :: FilePath
filterPath doc :: Pandoc
doc = do
  StackIndex
top <- Lua StackIndex
Lua.gettop
  Status
stat <- FilePath -> Lua Status
LuaUtil.dofileWithTraceback FilePath
filterPath
  if Status
stat Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
/= Status
Lua.OK
    then Lua Pandoc
forall a. Lua a
Lua.throwTopMessage
    else do
      StackIndex
newtop <- Lua StackIndex
Lua.gettop
      -- Use the returned filters, or the implicitly defined global
      -- filter if nothing was returned.
      [LuaFilter]
luaFilters <- if StackIndex
newtop StackIndex -> StackIndex -> StackIndex
forall a. Num a => a -> a -> a
- StackIndex
top StackIndex -> StackIndex -> Bool
forall a. Ord a => a -> a -> Bool
>= 1
                    then StackIndex -> Lua [LuaFilter]
forall a. Peekable a => StackIndex -> Lua a
Lua.peek StackIndex
Lua.stackTop
                    else Lua ()
Lua.pushglobaltable Lua () -> Lua [LuaFilter] -> Lua [LuaFilter]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (LuaFilter -> [LuaFilter]) -> Lua LuaFilter -> Lua [LuaFilter]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (LuaFilter -> [LuaFilter] -> [LuaFilter]
forall a. a -> [a] -> [a]
:[]) Lua LuaFilter
forall a. Peekable a => Lua a
Lua.popValue
      [LuaFilter] -> Pandoc -> Lua Pandoc
runAll [LuaFilter]
luaFilters Pandoc
doc

runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc
runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc
runAll = (LuaFilter -> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc)
-> (Pandoc -> Lua Pandoc) -> [LuaFilter] -> Pandoc -> Lua Pandoc
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Pandoc -> Lua Pandoc)
-> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
(>=>) ((Pandoc -> Lua Pandoc)
 -> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc)
-> (LuaFilter -> Pandoc -> Lua Pandoc)
-> LuaFilter
-> (Pandoc -> Lua Pandoc)
-> Pandoc
-> Lua Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LuaFilter -> Pandoc -> Lua Pandoc
walkMWithLuaFilter) Pandoc -> Lua Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return

-- | Filter function stored in the registry
newtype LuaFilterFunction = LuaFilterFunction Lua.Reference

-- | Collection of filter functions (at most one function per element
-- constructor)
newtype LuaFilter = LuaFilter (Map String LuaFilterFunction)

instance Peekable LuaFilter where
  peek :: StackIndex -> Lua LuaFilter
peek idx :: StackIndex
idx = do
    let constrs :: [FilePath]
constrs = FilePath
metaFilterName
                FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: [FilePath]
pandocFilterNames
                [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
++ [FilePath]
blockElementNames
                [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
++ [FilePath]
inlineElementNames
    let go :: FilePath
-> Map FilePath LuaFilterFunction
-> Lua (Map FilePath LuaFilterFunction)
go constr :: FilePath
constr acc :: Map FilePath LuaFilterFunction
acc = do
          StackIndex -> FilePath -> Lua ()
Lua.getfield StackIndex
idx FilePath
constr
          Maybe LuaFilterFunction
filterFn <- Lua (Maybe LuaFilterFunction)
registerFilterFunction
          Map FilePath LuaFilterFunction
-> Lua (Map FilePath LuaFilterFunction)
forall (m :: * -> *) a. Monad m => a -> m a
return (Map FilePath LuaFilterFunction
 -> Lua (Map FilePath LuaFilterFunction))
-> Map FilePath LuaFilterFunction
-> Lua (Map FilePath LuaFilterFunction)
forall a b. (a -> b) -> a -> b
$ case Maybe LuaFilterFunction
filterFn of
            Nothing -> Map FilePath LuaFilterFunction
acc
            Just fn :: LuaFilterFunction
fn -> FilePath
-> LuaFilterFunction
-> Map FilePath LuaFilterFunction
-> Map FilePath LuaFilterFunction
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert FilePath
constr LuaFilterFunction
fn Map FilePath LuaFilterFunction
acc
    Map FilePath LuaFilterFunction -> LuaFilter
LuaFilter (Map FilePath LuaFilterFunction -> LuaFilter)
-> Lua (Map FilePath LuaFilterFunction) -> Lua LuaFilter
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (FilePath
 -> Map FilePath LuaFilterFunction
 -> Lua (Map FilePath LuaFilterFunction))
-> Map FilePath LuaFilterFunction
-> [FilePath]
-> Lua (Map FilePath LuaFilterFunction)
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> b -> m b) -> b -> t a -> m b
foldrM FilePath
-> Map FilePath LuaFilterFunction
-> Lua (Map FilePath LuaFilterFunction)
go Map FilePath LuaFilterFunction
forall k a. Map k a
Map.empty [FilePath]
constrs

-- | Register the function at the top of the stack as a filter function in the
-- registry.
registerFilterFunction :: Lua (Maybe LuaFilterFunction)
registerFilterFunction :: Lua (Maybe LuaFilterFunction)
registerFilterFunction = do
  Bool
isFn <- StackIndex -> Lua Bool
Lua.isfunction StackIndex
Lua.stackTop
  if Bool
isFn
    then LuaFilterFunction -> Maybe LuaFilterFunction
forall a. a -> Maybe a
Just (LuaFilterFunction -> Maybe LuaFilterFunction)
-> (Reference -> LuaFilterFunction)
-> Reference
-> Maybe LuaFilterFunction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference -> LuaFilterFunction
LuaFilterFunction (Reference -> Maybe LuaFilterFunction)
-> Lua Reference -> Lua (Maybe LuaFilterFunction)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> Lua Reference
Lua.ref StackIndex
Lua.registryindex
    else Maybe LuaFilterFunction
forall a. Maybe a
Nothing Maybe LuaFilterFunction -> Lua () -> Lua (Maybe LuaFilterFunction)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ StackIndex -> Lua ()
Lua.pop 1

-- | Retrieve filter function from registry and push it to the top of the stack.
pushFilterFunction :: LuaFilterFunction -> Lua ()
pushFilterFunction :: LuaFilterFunction -> Lua ()
pushFilterFunction (LuaFilterFunction fnRef :: Reference
fnRef) =
  StackIndex -> Reference -> Lua ()
Lua.getref StackIndex
Lua.registryindex Reference
fnRef

-- | Fetch either a list of elements from the stack. If there is a single
-- element instead of a list, fetch that element as a singleton list. If the top
-- of the stack is nil, return the default element that was passed to this
-- function. If none of these apply, raise an error.
elementOrList :: Peekable a => a -> Lua [a]
elementOrList :: a -> Lua [a]
elementOrList x :: a
x = do
  let topOfStack :: StackIndex
topOfStack = StackIndex
Lua.stackTop
  Bool
elementUnchanged <- StackIndex -> Lua Bool
Lua.isnil StackIndex
topOfStack
  if Bool
elementUnchanged
    then [a
x] [a] -> Lua () -> Lua [a]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ StackIndex -> Lua ()
Lua.pop 1
    else do
       Either FilePath a
mbres <- StackIndex -> Lua (Either FilePath a)
forall a. Peekable a => StackIndex -> Lua (Either FilePath a)
Lua.peekEither StackIndex
topOfStack
       case Either FilePath a
mbres of
         Right res :: a
res -> [a
res] [a] -> Lua () -> Lua [a]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ StackIndex -> Lua ()
Lua.pop 1
         Left _    -> StackIndex -> Lua [a]
forall a. Peekable a => StackIndex -> Lua [a]
Lua.peekList StackIndex
topOfStack Lua [a] -> Lua () -> Lua [a]
forall (m :: * -> *) a b. MonadMask m => m a -> m b -> m a
`finally` StackIndex -> Lua ()
Lua.pop 1

-- | Try running a filter for the given element
tryFilter :: (Data a, Peekable a, Pushable a)
          => LuaFilter -> a -> Lua [a]
tryFilter :: LuaFilter -> a -> Lua [a]
tryFilter (LuaFilter fnMap :: Map FilePath LuaFilterFunction
fnMap) x :: a
x =
  let filterFnName :: FilePath
filterFnName = Constr -> FilePath
showConstr (a -> Constr
forall a. Data a => a -> Constr
toConstr a
x)
      catchAllName :: FilePath
catchAllName = FilePath -> FilePath
tyconUQname (FilePath -> FilePath) -> FilePath -> FilePath
forall a b. (a -> b) -> a -> b
$ DataType -> FilePath
dataTypeName (a -> DataType
forall a. Data a => a -> DataType
dataTypeOf a
x)
  in
  case FilePath
-> Map FilePath LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
filterFnName Map FilePath LuaFilterFunction
fnMap Maybe LuaFilterFunction
-> Maybe LuaFilterFunction -> Maybe LuaFilterFunction
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` FilePath
-> Map FilePath LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
catchAllName Map FilePath LuaFilterFunction
fnMap of
    Just fn :: LuaFilterFunction
fn -> LuaFilterFunction -> a -> Lua ()
forall a. Pushable a => LuaFilterFunction -> a -> Lua ()
runFilterFunction LuaFilterFunction
fn a
x Lua () -> Lua [a] -> Lua [a]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> a -> Lua [a]
forall a. Peekable a => a -> Lua [a]
elementOrList a
x
    Nothing -> [a] -> Lua [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [a
x]

-- | Apply filter on a sequence of AST elements.
runOnSequence :: (Data a, Peekable a, Pushable a)
              => LuaFilter -> SingletonsList a -> Lua (SingletonsList a)
runOnSequence :: LuaFilter -> SingletonsList a -> Lua (SingletonsList a)
runOnSequence lf :: LuaFilter
lf (SingletonsList xs :: [a]
xs) =
  [a] -> SingletonsList a
forall a. [a] -> SingletonsList a
SingletonsList ([a] -> SingletonsList a) -> Lua [a] -> Lua (SingletonsList a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> Lua [a]) -> [a] -> Lua [a]
forall (m :: * -> *) a. Monad m => (a -> m [a]) -> [a] -> m [a]
mconcatMapM (LuaFilter -> a -> Lua [a]
forall a.
(Data a, Peekable a, Pushable a) =>
LuaFilter -> a -> Lua [a]
tryFilter LuaFilter
lf) [a]
xs

-- | Push a value to the stack via a lua filter function. The filter function is
-- called with given element as argument and is expected to return an element.
-- Alternatively, the function can return nothing or nil, in which case the
-- element is left unchanged.
runFilterFunction :: Pushable a => LuaFilterFunction -> a -> Lua ()
runFilterFunction :: LuaFilterFunction -> a -> Lua ()
runFilterFunction lf :: LuaFilterFunction
lf x :: a
x = do
  LuaFilterFunction -> Lua ()
pushFilterFunction LuaFilterFunction
lf
  a -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push a
x
  NumArgs -> NumResults -> Lua ()
LuaUtil.callWithTraceback 1 1

walkMWithLuaFilter :: LuaFilter -> Pandoc -> Lua Pandoc
walkMWithLuaFilter :: LuaFilter -> Pandoc -> Lua Pandoc
walkMWithLuaFilter f :: LuaFilter
f =
  LuaFilter -> Pandoc -> Lua Pandoc
forall a.
Walkable (SingletonsList Inline) a =>
LuaFilter -> a -> Lua a
walkInlines LuaFilter
f (Pandoc -> Lua Pandoc)
-> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> Lua Pandoc
forall a.
Walkable (SingletonsList Block) a =>
LuaFilter -> a -> Lua a
walkBlocks LuaFilter
f (Pandoc -> Lua Pandoc)
-> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> Lua Pandoc
walkMeta LuaFilter
f (Pandoc -> Lua Pandoc)
-> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> Lua Pandoc
walkPandoc LuaFilter
f

mconcatMapM :: (Monad m) => (a -> m [a]) -> [a] -> m [a]
mconcatMapM :: (a -> m [a]) -> [a] -> m [a]
mconcatMapM f :: a -> m [a]
f = ([[a]] -> [a]) -> m [[a]] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[a]] -> [a]
forall a. Monoid a => [a] -> a
mconcat (m [[a]] -> m [a]) -> ([a] -> m [[a]]) -> [a] -> m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m [a]) -> [a] -> m [[a]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m [a]
f

hasOneOf :: LuaFilter -> [String] -> Bool
hasOneOf :: LuaFilter -> [FilePath] -> Bool
hasOneOf (LuaFilter fnMap :: Map FilePath LuaFilterFunction
fnMap) = (FilePath -> Bool) -> [FilePath] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\k :: FilePath
k -> FilePath -> Map FilePath LuaFilterFunction -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.member FilePath
k Map FilePath LuaFilterFunction
fnMap)

walkInlines :: Walkable (SingletonsList Inline) a => LuaFilter -> a -> Lua a
walkInlines :: LuaFilter -> a -> Lua a
walkInlines lf :: LuaFilter
lf =
  let f :: SingletonsList Inline -> Lua (SingletonsList Inline)
      f :: SingletonsList Inline -> Lua (SingletonsList Inline)
f = LuaFilter -> SingletonsList Inline -> Lua (SingletonsList Inline)
forall a.
(Data a, Peekable a, Pushable a) =>
LuaFilter -> SingletonsList a -> Lua (SingletonsList a)
runOnSequence LuaFilter
lf
  in if LuaFilter
lf LuaFilter -> [FilePath] -> Bool
`hasOneOf` [FilePath]
inlineElementNames
     then (SingletonsList Inline -> Lua (SingletonsList Inline))
-> a -> Lua a
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM SingletonsList Inline -> Lua (SingletonsList Inline)
f
     else a -> Lua a
forall (m :: * -> *) a. Monad m => a -> m a
return

walkBlocks :: Walkable (SingletonsList Block) a => LuaFilter -> a -> Lua a
walkBlocks :: LuaFilter -> a -> Lua a
walkBlocks lf :: LuaFilter
lf =
  let f :: SingletonsList Block -> Lua (SingletonsList Block)
      f :: SingletonsList Block -> Lua (SingletonsList Block)
f = LuaFilter -> SingletonsList Block -> Lua (SingletonsList Block)
forall a.
(Data a, Peekable a, Pushable a) =>
LuaFilter -> SingletonsList a -> Lua (SingletonsList a)
runOnSequence LuaFilter
lf
  in if LuaFilter
lf LuaFilter -> [FilePath] -> Bool
`hasOneOf` [FilePath]
blockElementNames
     then (SingletonsList Block -> Lua (SingletonsList Block)) -> a -> Lua a
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM SingletonsList Block -> Lua (SingletonsList Block)
f
     else a -> Lua a
forall (m :: * -> *) a. Monad m => a -> m a
return

walkMeta :: LuaFilter -> Pandoc -> Lua Pandoc
walkMeta :: LuaFilter -> Pandoc -> Lua Pandoc
walkMeta (LuaFilter fnMap :: Map FilePath LuaFilterFunction
fnMap) =
  case FilePath
-> Map FilePath LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup "Meta" Map FilePath LuaFilterFunction
fnMap of
    Just fn :: LuaFilterFunction
fn -> (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM (\(Pandoc meta :: Meta
meta blocks :: [Block]
blocks) -> do
                         Meta
meta' <- LuaFilterFunction -> Meta -> Lua ()
forall a. Pushable a => LuaFilterFunction -> a -> Lua ()
runFilterFunction LuaFilterFunction
fn Meta
meta Lua () -> Lua Meta -> Lua Meta
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Meta -> Lua Meta
forall a. Peekable a => a -> Lua a
singleElement Meta
meta
                         Pandoc -> Lua Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> Lua Pandoc) -> Pandoc -> Lua Pandoc
forall a b. (a -> b) -> a -> b
$ Meta -> [Block] -> Pandoc
Pandoc Meta
meta' [Block]
blocks)
    Nothing -> Pandoc -> Lua Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return

walkPandoc :: LuaFilter -> Pandoc -> Lua Pandoc
walkPandoc :: LuaFilter -> Pandoc -> Lua Pandoc
walkPandoc (LuaFilter fnMap :: Map FilePath LuaFilterFunction
fnMap) =
  case (Maybe LuaFilterFunction
 -> Maybe LuaFilterFunction -> Maybe LuaFilterFunction)
-> Maybe LuaFilterFunction
-> [Maybe LuaFilterFunction]
-> Maybe LuaFilterFunction
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Maybe LuaFilterFunction
-> Maybe LuaFilterFunction -> Maybe LuaFilterFunction
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus Maybe LuaFilterFunction
forall a. Maybe a
Nothing ((FilePath -> Maybe LuaFilterFunction)
-> [FilePath] -> [Maybe LuaFilterFunction]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
-> Map FilePath LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map FilePath LuaFilterFunction
fnMap) [FilePath]
pandocFilterNames) of
    Just fn :: LuaFilterFunction
fn -> \x :: Pandoc
x -> LuaFilterFunction -> Pandoc -> Lua ()
forall a. Pushable a => LuaFilterFunction -> a -> Lua ()
runFilterFunction LuaFilterFunction
fn Pandoc
x Lua () -> Lua Pandoc -> Lua Pandoc
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Pandoc -> Lua Pandoc
forall a. Peekable a => a -> Lua a
singleElement Pandoc
x
    Nothing -> Pandoc -> Lua Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return

constructorsFor :: DataType -> [String]
constructorsFor :: DataType -> [FilePath]
constructorsFor x :: DataType
x = (Constr -> FilePath) -> [Constr] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map Constr -> FilePath
forall a. Show a => a -> FilePath
show (DataType -> [Constr]
dataTypeConstrs DataType
x)

inlineElementNames :: [String]
inlineElementNames :: [FilePath]
inlineElementNames = "Inline" FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: DataType -> [FilePath]
constructorsFor (Inline -> DataType
forall a. Data a => a -> DataType
dataTypeOf (Text -> Inline
Str Text
forall a. Monoid a => a
mempty))

blockElementNames :: [String]
blockElementNames :: [FilePath]
blockElementNames = "Block" FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: DataType -> [FilePath]
constructorsFor (Block -> DataType
forall a. Data a => a -> DataType
dataTypeOf ([Inline] -> Block
Para []))

metaFilterName :: String
metaFilterName :: FilePath
metaFilterName = "Meta"

pandocFilterNames :: [String]
pandocFilterNames :: [FilePath]
pandocFilterNames = ["Pandoc", "Doc"]

singleElement :: Peekable a => a -> Lua a
singleElement :: a -> Lua a
singleElement x :: a
x = do
  Bool
elementUnchanged <- StackIndex -> Lua Bool
Lua.isnil (-1)
  if Bool
elementUnchanged
    then a
x a -> Lua () -> Lua a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ StackIndex -> Lua ()
Lua.pop 1
    else do
    Either FilePath a
mbres <- StackIndex -> Lua (Either FilePath a)
forall a. Peekable a => StackIndex -> Lua (Either FilePath a)
Lua.peekEither (-1)
    case Either FilePath a
mbres of
      Right res :: a
res -> a
res a -> Lua () -> Lua a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ StackIndex -> Lua ()
Lua.pop 1
      Left err :: FilePath
err  -> do
        StackIndex -> Lua ()
Lua.pop 1
        FilePath -> Lua a
forall a. FilePath -> Lua a
Lua.throwException (FilePath -> Lua a) -> FilePath -> Lua a
forall a b. (a -> b) -> a -> b
$
          "Error while trying to get a filter's return " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++
          "value from lua stack.\n" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
err