{-# LANGUAGE OverloadedStrings    #-}
{- |
Copyright               : © 2021 Albert Krewinkel
SPDX-License-Identifier : MIT
Maintainer              : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>

Marshaling/unmarshaling functions of table 'Cell' values.
-}
module Text.Pandoc.Lua.Marshal.Cell
  ( peekCell
  , pushCell
  ) where

import Control.Monad ((<$!>))
import HsLua
import Text.Pandoc.Lua.Marshal.Alignment (peekAlignment, pushAlignment)
import Text.Pandoc.Lua.Marshal.Attr (peekAttr, pushAttr)
import {-# SOURCE #-} Text.Pandoc.Lua.Marshal.Block
  ( peekBlocksFuzzy, pushBlocks )
import Text.Pandoc.Definition (Cell (..), RowSpan (..), ColSpan (..))

-- | Push a table cell as a table with fields @attr@, @alignment@,
-- @row_span@, @col_span@, and @contents@.
pushCell :: LuaError e => Cell -> LuaE e ()
pushCell :: Cell -> LuaE e ()
pushCell (Cell Attr
attr Alignment
align (RowSpan Int
rowSpan) (ColSpan Int
colSpan) [Block]
contents) = do
  LuaE e ()
forall e. LuaE e ()
newtable
  Name -> LuaE e () -> LuaE e ()
forall e a. LuaError e => Name -> LuaE e a -> LuaE e ()
addField Name
"attr" (Pusher e Attr
forall e. LuaError e => Pusher e Attr
pushAttr Attr
attr)
  Name -> LuaE e () -> LuaE e ()
forall e a. LuaError e => Name -> LuaE e a -> LuaE e ()
addField Name
"alignment" (Pusher e Alignment
forall e. Pusher e Alignment
pushAlignment Alignment
align)
  Name -> LuaE e () -> LuaE e ()
forall e a. LuaError e => Name -> LuaE e a -> LuaE e ()
addField Name
"row_span" (Int -> LuaE e ()
forall a e. (Integral a, Show a) => a -> LuaE e ()
pushIntegral Int
rowSpan)
  Name -> LuaE e () -> LuaE e ()
forall e a. LuaError e => Name -> LuaE e a -> LuaE e ()
addField Name
"col_span" (Int -> LuaE e ()
forall a e. (Integral a, Show a) => a -> LuaE e ()
pushIntegral Int
colSpan)
  Name -> LuaE e () -> LuaE e ()
forall e a. LuaError e => Name -> LuaE e a -> LuaE e ()
addField Name
"contents" (Pusher e [Block]
forall e. LuaError e => Pusher e [Block]
pushBlocks [Block]
contents)
 where addField :: Name -> LuaE e a -> LuaE e ()
addField Name
key LuaE e a
pusher = Name -> LuaE e ()
forall e. Name -> LuaE e ()
pushName Name
key LuaE e () -> LuaE e a -> LuaE e a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> LuaE e a
pusher LuaE e a -> LuaE e () -> LuaE e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth CInt
3)

-- | Retrieves a table 'Cell' from the stack.
peekCell :: LuaError e => Peeker e Cell
peekCell :: Peeker e Cell
peekCell = (Peek e Cell -> Peek e Cell) -> Peeker e Cell -> Peeker e Cell
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Name -> Peek e Cell -> Peek e Cell
forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"Cell")
  (Peeker e Cell -> Peeker e Cell)
-> (Peeker e Cell -> Peeker e Cell)
-> Peeker e Cell
-> Peeker e Cell
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name
-> (StackIndex -> LuaE e Bool) -> Peeker e Cell -> Peeker e Cell
forall e a.
Name -> (StackIndex -> LuaE e Bool) -> Peeker e a -> Peeker e a
typeChecked Name
"table" StackIndex -> LuaE e Bool
forall e. StackIndex -> LuaE e Bool
istable
  (Peeker e Cell -> Peeker e Cell) -> Peeker e Cell -> Peeker e Cell
forall a b. (a -> b) -> a -> b
$ \StackIndex
idx -> do
  Attr
attr <- Peeker e Attr -> Name -> Peeker e Attr
forall e a. LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw Peeker e Attr
forall e. LuaError e => Peeker e Attr
peekAttr Name
"attr" StackIndex
idx
  Alignment
algn <- Peeker e Alignment -> Name -> Peeker e Alignment
forall e a. LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw Peeker e Alignment
forall e. Peeker e Alignment
peekAlignment Name
"alignment" StackIndex
idx
  RowSpan
rs   <- Int -> RowSpan
RowSpan (Int -> RowSpan) -> Peek e Int -> Peek e RowSpan
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Peeker e Int -> Name -> Peeker e Int
forall e a. LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw Peeker e Int
forall a e. (Integral a, Read a) => Peeker e a
peekIntegral Name
"row_span" StackIndex
idx
  ColSpan
cs   <- Int -> ColSpan
ColSpan (Int -> ColSpan) -> Peek e Int -> Peek e ColSpan
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Peeker e Int -> Name -> Peeker e Int
forall e a. LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw Peeker e Int
forall a e. (Integral a, Read a) => Peeker e a
peekIntegral Name
"col_span" StackIndex
idx
  [Block]
blks <- Peeker e [Block] -> Name -> Peeker e [Block]
forall e a. LuaError e => Peeker e a -> Name -> Peeker e a
peekFieldRaw Peeker e [Block]
forall e. LuaError e => Peeker e [Block]
peekBlocksFuzzy Name
"contents" StackIndex
idx
  Cell -> Peek e Cell
forall (m :: * -> *) a. Monad m => a -> m a
return (Cell -> Peek e Cell) -> Cell -> Peek e Cell
forall a b. (a -> b) -> a -> b
$! Attr -> Alignment -> RowSpan -> ColSpan -> [Block] -> Cell
Cell Attr
attr Alignment
algn RowSpan
rs ColSpan
cs [Block]
blks