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

Marshaling/unmarshaling functions of 'TableBody' values.
-}
module Text.Pandoc.Lua.Marshal.TableBody
  ( peekTableBody
  , peekTableBodyFuzzy
  , pushTableBody
  , typeTableBody
  , mkTableBody
  ) where

import Control.Applicative (optional)
import Data.Aeson (encode)
import Data.Maybe (fromMaybe)
import HsLua
import Text.Pandoc.Lua.Marshal.Attr (peekAttr, pushAttr)
import Text.Pandoc.Lua.Marshal.List (pushPandocList)
import Text.Pandoc.Lua.Marshal.Row (peekRowFuzzy, pushRow)
import Text.Pandoc.Definition

-- | Push a TableBody as a userdata value.
pushTableBody :: LuaError e => TableBody -> LuaE e ()
pushTableBody :: forall e. LuaError e => TableBody -> LuaE e ()
pushTableBody = DocumentedTypeWithList e TableBody (ZonkAny 2)
-> TableBody -> LuaE e ()
forall e a itemtype.
LuaError e =>
DocumentedTypeWithList e a itemtype -> a -> LuaE e ()
pushUD DocumentedTypeWithList e TableBody (ZonkAny 2)
forall e. LuaError e => DocumentedType e TableBody
typeTableBody

-- | Retrieves a TableBody from the stack.
peekTableBody :: LuaError e => Peeker e TableBody
peekTableBody :: forall e. LuaError e => Peeker e TableBody
peekTableBody = DocumentedTypeWithList e TableBody (ZonkAny 0)
-> Peeker e TableBody
forall e a itemtype.
LuaError e =>
DocumentedTypeWithList e a itemtype -> Peeker e a
peekUD DocumentedTypeWithList e TableBody (ZonkAny 0)
forall e. LuaError e => DocumentedType e TableBody
typeTableBody

-- | Retrieves a TableBody from the stack, accepting either a 
-- 'pandoc TableBody' userdata object or a table with fields @attr@,
-- @body@, @head@, @row_head_columns@.
peekTableBodyFuzzy :: LuaError e => Peeker e TableBody
peekTableBodyFuzzy :: forall e. LuaError e => Peeker e TableBody
peekTableBodyFuzzy StackIndex
idx = Name -> Peek e TableBody -> Peek e TableBody
forall e a. Name -> Peek e a -> Peek e a
retrieving Name
"TableBody" (Peek e TableBody -> Peek e TableBody)
-> Peek e TableBody -> Peek e TableBody
forall a b. (a -> b) -> a -> b
$ LuaE e Type -> Peek e Type
forall e a. LuaE e a -> Peek e a
liftLua (StackIndex -> LuaE e Type
forall e. StackIndex -> LuaE e Type
ltype StackIndex
idx) Peek e Type -> (Type -> Peek e TableBody) -> Peek e TableBody
forall a b. Peek e a -> (a -> Peek e b) -> Peek e b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  Type
TypeUserdata -> Peeker e TableBody
forall e. LuaError e => Peeker e TableBody
peekTableBody StackIndex
idx
  Type
TypeTable -> do
    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
    body <- peekFieldRaw (peekList peekRowFuzzy) "body" idx
    ihead <- peekFieldRaw (peekList peekRowFuzzy) "head" idx
    rhc <- peekFieldRaw (fmap RowHeadColumns . peekIntegral) "row_head_columns" idx
    return $! TableBody attr rhc ihead body
  Type
_ -> ByteString -> Peek e TableBody
forall a e. ByteString -> Peek e a
failPeek (ByteString -> Peek e TableBody)
-> Peek e ByteString -> Peek e TableBody
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Name -> StackIndex -> Peek e ByteString
forall e. Name -> StackIndex -> Peek e ByteString
typeMismatchMessage Name
"Cell or table" StackIndex
idx

-- | TableBody object type.
typeTableBody :: LuaError e => DocumentedType e TableBody
typeTableBody :: forall e. LuaError e => DocumentedType e TableBody
typeTableBody = Name
-> [(Operation, DocumentedFunction e)]
-> [Member e (DocumentedFunction e) TableBody]
-> DocumentedType e TableBody
forall e a.
LuaError e =>
Name
-> [(Operation, DocumentedFunction e)]
-> [Member e (DocumentedFunction e) a]
-> DocumentedType e a
deftype Name
"TableBody"
  [ Operation
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
forall e.
Operation
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
operation Operation
Eq (DocumentedFunction e -> (Operation, DocumentedFunction e))
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
forall a b. (a -> b) -> a -> b
$ Name
-> (Maybe TableBody -> Maybe TableBody -> LuaE e Bool)
-> HsFnPrecursor
     e (Maybe TableBody -> Maybe TableBody -> LuaE e Bool)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"__eq"
     ### liftPure2 (\a b -> fromMaybe False ((==) <$> a <*> b))
     HsFnPrecursor e (Maybe TableBody -> Maybe TableBody -> LuaE e Bool)
-> Parameter e (Maybe TableBody)
-> HsFnPrecursor e (Maybe TableBody -> LuaE e Bool)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e (Maybe TableBody)
-> TypeSpec -> Text -> Text -> Parameter e (Maybe TableBody)
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter (Peek e TableBody -> Peek e (Maybe TableBody)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Peek e TableBody -> Peek e (Maybe TableBody))
-> (StackIndex -> Peek e TableBody) -> Peeker e (Maybe TableBody)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackIndex -> Peek e TableBody
forall e. LuaError e => Peeker e TableBody
peekTableBody) TypeSpec
"TableBody" Text
"self" Text
""
     HsFnPrecursor e (Maybe TableBody -> LuaE e Bool)
-> Parameter e (Maybe TableBody) -> HsFnPrecursor e (LuaE e Bool)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e (Maybe TableBody)
-> TypeSpec -> Text -> Text -> Parameter e (Maybe TableBody)
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter (Peek e TableBody -> Peek e (Maybe TableBody)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Peek e TableBody -> Peek e (Maybe TableBody))
-> (StackIndex -> Peek e TableBody) -> Peeker e (Maybe TableBody)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackIndex -> Peek e TableBody
forall e. LuaError e => Peeker e TableBody
peekTableBody) TypeSpec
"any" Text
"object" Text
""
     HsFnPrecursor e (LuaE e Bool)
-> FunctionResults e Bool -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e Bool -> TypeSpec -> Text -> FunctionResults e Bool
forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
functionResult Pusher e Bool
forall e. Pusher e Bool
pushBool TypeSpec
"boolean" Text
"true iff the two values are equal"
  , Operation
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
forall e.
Operation
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
operation Operation
Tostring (DocumentedFunction e -> (Operation, DocumentedFunction e))
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
forall a b. (a -> b) -> a -> b
$ (TableBody -> LuaE e String)
-> HsFnPrecursor e (TableBody -> LuaE e String)
forall a e. a -> HsFnPrecursor e a
lambda
    ### liftPure show
    HsFnPrecursor e (TableBody -> LuaE e String)
-> Parameter e TableBody -> HsFnPrecursor e (LuaE e String)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> (StackIndex -> Peek e TableBody)
-> TypeSpec -> Text -> Text -> Parameter e TableBody
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter StackIndex -> Peek e TableBody
forall e. LuaError e => Peeker e TableBody
peekTableBody TypeSpec
"TableBody" Text
"self" Text
""
    HsFnPrecursor e (LuaE e String)
-> FunctionResults e String -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e String -> TypeSpec -> Text -> FunctionResults e String
forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
functionResult Pusher e String
forall e. String -> LuaE e ()
pushString TypeSpec
"string" Text
"native Haskell representation"
  , Operation
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
forall e.
Operation
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
operation (Name -> Operation
CustomOperation Name
"__tojson") (DocumentedFunction e -> (Operation, DocumentedFunction e))
-> DocumentedFunction e -> (Operation, DocumentedFunction e)
forall a b. (a -> b) -> a -> b
$ (TableBody -> LuaE e ByteString)
-> HsFnPrecursor e (TableBody -> LuaE e ByteString)
forall a e. a -> HsFnPrecursor e a
lambda
    ### liftPure encode
    HsFnPrecursor e (TableBody -> LuaE e ByteString)
-> Parameter e TableBody -> HsFnPrecursor e (LuaE e ByteString)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> DocumentedType e TableBody -> Text -> Text -> Parameter e TableBody
forall e a itemtype.
LuaError e =>
DocumentedTypeWithList e a itemtype
-> Text -> Text -> Parameter e a
udparam DocumentedType e TableBody
forall e. LuaError e => DocumentedType e TableBody
typeTableBody Text
"self" Text
""
    HsFnPrecursor e (LuaE e ByteString)
-> FunctionResults e ByteString -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e ByteString
-> TypeSpec -> Text -> FunctionResults e ByteString
forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
functionResult Pusher e ByteString
forall e. Pusher e ByteString
pushLazyByteString TypeSpec
"string" Text
"JSON representation"
  ]
  [ Name
-> Text
-> (Pusher e Attr, TableBody -> Attr)
-> (Peeker e Attr, TableBody -> Attr -> TableBody)
-> Member e (DocumentedFunction e) TableBody
forall e b a fn.
LuaError e =>
Name
-> Text
-> (Pusher e b, a -> b)
-> (Peeker e b, a -> b -> a)
-> Member e fn a
property Name
"attr" Text
"table body attributes"
      (Pusher e Attr
forall e. LuaError e => Pusher e Attr
pushAttr, \(TableBody Attr
attr RowHeadColumns
_ [Row]
_ [Row]
_) -> Attr
attr)
      (Peeker e Attr
forall e. LuaError e => Peeker e Attr
peekAttr, \(TableBody Attr
_ RowHeadColumns
body [Row]
ihead [Row]
rhc) Attr
attr ->
                   Attr -> RowHeadColumns -> [Row] -> [Row] -> TableBody
TableBody Attr
attr RowHeadColumns
body [Row]
ihead [Row]
rhc)
  , Name
-> Text
-> (Pusher e Int, TableBody -> Int)
-> (Peeker e Int, TableBody -> Int -> TableBody)
-> Member e (DocumentedFunction e) TableBody
forall e b a fn.
LuaError e =>
Name
-> Text
-> (Pusher e b, a -> b)
-> (Peeker e b, a -> b -> a)
-> Member e fn a
property Name
"row_head_columns" Text
"number of columns taken up by the row head of each row of the TableBody"
    (Pusher e Int
forall a e. (Integral a, Show a) => a -> LuaE e ()
pushIntegral, \(TableBody Attr
_ (RowHeadColumns Int
rhc) [Row]
_ [Row]
_) -> Int
rhc)
    (Peeker e Int
forall a e. (Integral a, Read a) => Peeker e a
peekIntegral, \(TableBody Attr
attr RowHeadColumns
_ [Row]
ihead [Row]
body) Int
rhc ->
                      Attr -> RowHeadColumns -> [Row] -> [Row] -> TableBody
TableBody Attr
attr (Int -> RowHeadColumns
RowHeadColumns Int
rhc) [Row]
ihead [Row]
body)
  , Name
-> Text
-> (Pusher e [Row], TableBody -> [Row])
-> (Peeker e [Row], TableBody -> [Row] -> TableBody)
-> Member e (DocumentedFunction e) TableBody
forall e b a fn.
LuaError e =>
Name
-> Text
-> (Pusher e b, a -> b)
-> (Peeker e b, a -> b -> a)
-> Member e fn a
property Name
"head" Text
"intermediate head"
      (Pusher e Row -> Pusher e [Row]
forall e a. LuaError e => Pusher e a -> Pusher e [a]
pushPandocList Pusher e Row
forall e. LuaError e => Row -> LuaE e ()
pushRow, \(TableBody Attr
_ RowHeadColumns
_ [Row]
ihead [Row]
_) -> [Row]
ihead)
      (Peeker e Row -> Peeker e [Row]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Row
forall e. LuaError e => Peeker e Row
peekRowFuzzy, \(TableBody Attr
attr RowHeadColumns
rhc [Row]
_ [Row]
body) [Row]
ihead ->
                                Attr -> RowHeadColumns -> [Row] -> [Row] -> TableBody
TableBody Attr
attr RowHeadColumns
rhc [Row]
ihead [Row]
body)
  , Name
-> Text
-> (Pusher e [Row], TableBody -> [Row])
-> (Peeker e [Row], TableBody -> [Row] -> TableBody)
-> Member e (DocumentedFunction e) TableBody
forall e b a fn.
LuaError e =>
Name
-> Text
-> (Pusher e b, a -> b)
-> (Peeker e b, a -> b -> a)
-> Member e fn a
property Name
"body" Text
"table body rows"
      (Pusher e Row -> Pusher e [Row]
forall e a. LuaError e => Pusher e a -> Pusher e [a]
pushPandocList Pusher e Row
forall e. LuaError e => Row -> LuaE e ()
pushRow, \(TableBody Attr
_ RowHeadColumns
_ [Row]
_ [Row]
body) -> [Row]
body)
      (Peeker e Row -> Peeker e [Row]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Row
forall e. LuaError e => Peeker e Row
peekRowFuzzy, \(TableBody Attr
attr RowHeadColumns
rhc [Row]
ihead [Row]
_) [Row]
body ->
                                Attr -> RowHeadColumns -> [Row] -> [Row] -> TableBody
TableBody Attr
attr RowHeadColumns
rhc [Row]
ihead [Row]
body)
  , AliasIndex
-> Text
-> [AliasIndex]
-> Member e (DocumentedFunction e) TableBody
forall e fn a. AliasIndex -> Text -> [AliasIndex] -> Member e fn a
alias AliasIndex
"identifier" Text
"cell ID"         [AliasIndex
"attr", AliasIndex
"identifier"]
  , AliasIndex
-> Text
-> [AliasIndex]
-> Member e (DocumentedFunction e) TableBody
forall e fn a. AliasIndex -> Text -> [AliasIndex] -> Member e fn a
alias AliasIndex
"classes"    Text
"cell classes"    [AliasIndex
"attr", AliasIndex
"classes"]
  , AliasIndex
-> Text
-> [AliasIndex]
-> Member e (DocumentedFunction e) TableBody
forall e fn a. AliasIndex -> Text -> [AliasIndex] -> Member e fn a
alias AliasIndex
"attributes" Text
"cell attributes" [AliasIndex
"attr", AliasIndex
"attributes"]

  , DocumentedFunction e -> Member e (DocumentedFunction e) TableBody
forall e a.
DocumentedFunction e -> Member e (DocumentedFunction e) a
method (DocumentedFunction e -> Member e (DocumentedFunction e) TableBody)
-> DocumentedFunction e
-> Member e (DocumentedFunction e) TableBody
forall a b. (a -> b) -> a -> b
$ Name
-> (TableBody -> LuaE e TableBody)
-> HsFnPrecursor e (TableBody -> LuaE e TableBody)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"clone"
    ### return
    HsFnPrecursor e (TableBody -> LuaE e TableBody)
-> Parameter e TableBody -> HsFnPrecursor e (LuaE e TableBody)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> (StackIndex -> Peek e TableBody)
-> TypeSpec -> Text -> Text -> Parameter e TableBody
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter StackIndex -> Peek e TableBody
forall e. LuaError e => Peeker e TableBody
peekTableBody TypeSpec
"TableBody" Text
"self" Text
""
    HsFnPrecursor e (LuaE e TableBody)
-> FunctionResults e TableBody -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e TableBody
-> TypeSpec -> Text -> FunctionResults e TableBody
forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
functionResult Pusher e TableBody
forall e. LuaError e => TableBody -> LuaE e ()
pushTableBody TypeSpec
"TableBody" Text
"cloned object"
  ]

-- | Constructor function for 'TableBody' values.
mkTableBody :: LuaError e => DocumentedFunction e
mkTableBody :: forall e. LuaError e => DocumentedFunction e
mkTableBody = Name
-> (Maybe [Row]
    -> Maybe [Row] -> Maybe Int -> Maybe Attr -> LuaE e TableBody)
-> HsFnPrecursor
     e
     (Maybe [Row]
      -> Maybe [Row] -> Maybe Int -> Maybe Attr -> LuaE e TableBody)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"TableBody"
  ### liftPure4 (\mBody mHead mRhc mAttr -> TableBody
                  (fromMaybe nullAttr mAttr)
                  (maybe 0 RowHeadColumns mRhc)
                  (fromMaybe [] mHead)
                  (fromMaybe [] mBody))
  HsFnPrecursor
  e
  (Maybe [Row]
   -> Maybe [Row] -> Maybe Int -> Maybe Attr -> LuaE e TableBody)
-> Parameter e (Maybe [Row])
-> HsFnPrecursor
     e (Maybe [Row] -> Maybe Int -> Maybe Attr -> LuaE e TableBody)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter e [Row] -> Parameter e (Maybe [Row])
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker e [Row] -> TypeSpec -> Text -> Text -> Parameter e [Row]
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter (Peeker e Row -> Peeker e [Row]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Row
forall e. LuaError e => Peeker e Row
peekRowFuzzy) TypeSpec
"{Row,...}" Text
"body"
           Text
"list of table rows")
  HsFnPrecursor
  e (Maybe [Row] -> Maybe Int -> Maybe Attr -> LuaE e TableBody)
-> Parameter e (Maybe [Row])
-> HsFnPrecursor e (Maybe Int -> Maybe Attr -> LuaE e TableBody)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter e [Row] -> Parameter e (Maybe [Row])
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker e [Row] -> TypeSpec -> Text -> Text -> Parameter e [Row]
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter (Peeker e Row -> Peeker e [Row]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Row
forall e. LuaError e => Peeker e Row
peekRowFuzzy) TypeSpec
"{Row,...}" Text
"head"
           Text
"intermediate head")
  HsFnPrecursor e (Maybe Int -> Maybe Attr -> LuaE e TableBody)
-> Parameter e (Maybe Int)
-> HsFnPrecursor e (Maybe Attr -> LuaE e TableBody)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter e Int -> Parameter e (Maybe Int)
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker e Int -> TypeSpec -> Text -> Text -> Parameter e Int
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter Peeker e Int
forall a e. (Integral a, Read a) => Peeker e a
peekIntegral TypeSpec
"integer" Text
"row_head_columns"
           Text
"number of columns taken up by the row head of each row of the TableBody")
  HsFnPrecursor e (Maybe Attr -> LuaE e TableBody)
-> Parameter e (Maybe Attr) -> HsFnPrecursor e (LuaE e TableBody)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter e Attr -> Parameter e (Maybe Attr)
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker e Attr -> TypeSpec -> Text -> Text -> Parameter e Attr
forall e a. Peeker e a -> TypeSpec -> Text -> Text -> Parameter e a
parameter Peeker e Attr
forall e. LuaError e => Peeker e Attr
peekAttr TypeSpec
"Attr" Text
"attr" Text
"table body attributes")
  HsFnPrecursor e (LuaE e TableBody)
-> FunctionResults e TableBody -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e TableBody
-> TypeSpec -> Text -> FunctionResults e TableBody
forall e a. Pusher e a -> TypeSpec -> Text -> FunctionResults e a
functionResult Pusher e TableBody
forall e. LuaError e => TableBody -> LuaE e ()
pushTableBody TypeSpec
"TableBody" Text
"new TableBody object"
  #? "Creates a table body."