@@ -35,13 +35,15 @@ module Text.Pandoc.Lua.StackInstances () where
3535
3636import Control.Applicative ((<|>))
3737import Control.Monad (when)
38+import Control.Monad.Catch (finally)
3839import Data.Data (showConstr, toConstr)
3940import Data.Foldable (forM_)
4041import Foreign.Lua (FromLuaStack (peek), Lua, LuaInteger, LuaNumber, StackIndex,
4142 ToLuaStack (push), Type (..), throwLuaError, tryLua)
4243import Text.Pandoc.Definition
4344import Text.Pandoc.Extensions (Extensions)
44−import Text.Pandoc.Lua.Util (adjustIndexBy, getTable, pushViaConstructor)
45+import Text.Pandoc.Lua.Util (adjustIndexBy, getTable, pushViaConstructor,
46+ typeCheck)
4547import Text.Pandoc.Options (ReaderOptions (..), TrackChanges)
4648import Text.Pandoc.Shared (Element (Blk, Sec), safeRead)
4749
@@ -49,21 +51,27 @@ import qualified Foreign.Lua as Lua
4951import qualified Data.Set as Set
5052import qualified Text.Pandoc.Lua.Util as LuaUtil
5153
54+defineHowTo :: String -> Lua a -> Lua a
55+defineHowTo ctx op = op `Lua.modifyLuaError` (("Could not " ++ ctx ++ ": ") ++)
56+
5257instance ToLuaStack Pandoc where
5358 push (Pandoc meta blocks) =
5459 pushViaConstructor "Pandoc" blocks meta
5560
5661instance FromLuaStack Pandoc where
57− peek idx = do
62+ peek idx = defineHowTo "get Pandoc value" $ do
63+ typeCheck idx Lua.TypeTable
5864 blocks <- getTable idx "blocks"
59− meta <- getTable idx "meta"
65+ meta <- Lua.getfield idx "meta" *> (Lua.peek Lua.stackTop `finally` Lua.pop 1)
6066 return $ Pandoc meta blocks
6167
6268instance ToLuaStack Meta where
6369 push (Meta mmap) =
6470 pushViaConstructor "Meta" mmap
6571instance FromLuaStack Meta where
66− peek idx = Meta <$> peek idx
72+ peek idx = defineHowTo "get Meta value" $ do
73+ typeCheck idx Lua.TypeTable
74+ Meta <$> peek idx
6775
6876instance ToLuaStack MetaValue where
6977 push = pushMetaValue
@@ -160,7 +168,7 @@ pushMetaValue = \case
160168
161169-- | Interpret the value at the given stack index as meta value.
162170peekMetaValue :: StackIndex -> Lua MetaValue
163−peekMetaValue idx = do
171+peekMetaValue idx = defineHowTo "get MetaValue" $ do
164172 -- Get the contents of an AST element.
165173 let elementContent :: FromLuaStack a => Lua a
166174 elementContent = peek idx
@@ -209,7 +217,8 @@ pushBlock = \case
209217
210218-- | Return the value at the given index as block if possible.
211219peekBlock :: StackIndex -> Lua Block
212−peekBlock idx = do
220+peekBlock idx = defineHowTo "get Block value" $ do
221+ typeCheck idx Lua.TypeTable
213222 tag <- getTag idx
214223 case tag of
215224 "BlockQuote" -> BlockQuote <$> elementContent
@@ -260,7 +269,8 @@ pushInline = \case
260269
261270-- | Return the value at the given index as inline if possible.
262271peekInline :: StackIndex -> Lua Inline
263−peekInline idx = do
272+peekInline idx = defineHowTo "get Inline value" $ do
273+ typeCheck idx Lua.TypeTable
264274 tag <- getTag idx
265275 case tag of
266276 "Cite" -> uncurry Cite <$> elementContent
@@ -296,11 +306,7 @@ getTag idx = do
296306 hasMT <- Lua.getmetatable idx
297307 push "tag"
298308 if hasMT then Lua.rawget (-2) else Lua.rawget (idx `adjustIndexBy` 1)
299− r <- tryLua (peek (-1))
300− Lua.settop top
301− case r of
302− Left (Lua.LuaException err) -> throwLuaError err
303− Right res -> return res
309+ peek Lua.stackTop `finally` Lua.settop top
304310
305311withAttr :: (Attr -> a -> b) -> (LuaAttr, a) -> b
306312withAttr f (attributes, x) = f (fromLuaAttr attributes) x
@@ -313,7 +319,7 @@ instance ToLuaStack LuaAttr where
313319 pushViaConstructor "Attr" id' classes kv
314320
315321instance FromLuaStack LuaAttr where
316− peek idx = LuaAttr <$> peek idx
322+ peek idx = defineHowTo "get Attr value" (LuaAttr <$> peek idx)
317323
318324--
319325-- Hierarchical elements