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

Marshaling/unmarshaling functions of 'Row' values.
-}
module Text.Pandoc.Lua.Marshal.Row
  ( peekRow
  , peekRowFuzzy
  , pushRow
  , typeRow
  , mkRow
  ) where

import Control.Applicative (optional)
import Control.Monad ((<$!>))
import Data.Maybe (fromMaybe)
import HsLua
import Text.Pandoc.Lua.Marshal.Attr (peekAttr, pushAttr)
import Text.Pandoc.Lua.Marshal.Cell (peekCellFuzzy, pushCell)
import Text.Pandoc.Lua.Marshal.Filter (peekFilter)
import Text.Pandoc.Lua.Marshal.List (pushPandocList)
import Text.Pandoc.Lua.Marshal.Shared (walkBlocksAndInlines)
import Text.Pandoc.Definition

-- | Push a table Row as a table with fields @attr@, @alignment@,
-- @row_span@, @col_span@, and @contents@.
pushRow :: LuaError e => Row -> LuaE e ()
pushRow :: Row -> LuaE e ()
pushRow = UDTypeWithList e (DocumentedFunction e) Row Void
-> Row -> LuaE e ()
forall e fn a itemtype.
LuaError e =>
UDTypeWithList e fn a itemtype -> a -> LuaE e ()
pushUD UDTypeWithList e (DocumentedFunction e) Row Void
forall e. LuaError e => DocumentedType e Row
typeRow

-- | Retrieves a 'Cell' object from the stack.
peekRow :: LuaError e => Peeker e Row
peekRow :: Peeker e Row
peekRow = UDTypeWithList e (DocumentedFunction e) Row Void -> Peeker e Row
forall e fn a itemtype.
LuaError e =>
UDTypeWithList e fn a itemtype -> Peeker e a
peekUD UDTypeWithList e (DocumentedFunction e) Row Void
forall e. LuaError e => DocumentedType e Row
typeRow

-- | Retrieves a 'Cell' from the stack, accepting either a 'pandoc Cell'
-- userdata object or a table with fields @attr@, @alignment@, @row_span@,
-- @col_span@, and @contents@.
peekRowFuzzy :: LuaError e => Peeker e Row
peekRowFuzzy :: Peeker e Row
peekRowFuzzy StackIndex
idx = 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 Row) -> Peek e Row
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
  Type
TypeUserdata -> Peeker e Row
forall e. LuaError e => Peeker e Row
peekRow StackIndex
idx
  Type
TypeTable -> (Attr -> [Cell] -> Row) -> (Attr, [Cell]) -> Row
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Attr -> [Cell] -> Row
Row ((Attr, [Cell]) -> Row) -> Peek e (Attr, [Cell]) -> Peek e Row
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Peeker e Attr -> Peeker e [Cell] -> Peeker e (Attr, [Cell])
forall e a b.
LuaError e =>
Peeker e a -> Peeker e b -> Peeker e (a, b)
peekPair Peeker e Attr
forall e. LuaError e => Peeker e Attr
peekAttr (Peeker e Cell -> Peeker e [Cell]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Cell
forall e. LuaError e => Peeker e Cell
peekCellFuzzy) StackIndex
idx
  Type
_ -> ByteString -> Peek e Row
forall a e. ByteString -> Peek e a
failPeek (ByteString -> Peek e Row) -> Peek e ByteString -> Peek e Row
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

-- | Row object type.
typeRow :: LuaError e => DocumentedType e Row
typeRow :: DocumentedType e Row
typeRow = Name
-> [(Operation, DocumentedFunction e)]
-> [Member e (DocumentedFunction e) Row]
-> DocumentedType e Row
forall e a.
LuaError e =>
Name
-> [(Operation, DocumentedFunction e)]
-> [Member e (DocumentedFunction e) a]
-> DocumentedType e a
deftype Name
"pandoc Row"
  [ 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 Row -> Maybe Row -> LuaE e Bool)
-> HsFnPrecursor e (Maybe Row -> Maybe Row -> LuaE e Bool)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"__eq"
     ### liftPure2 (\a b -> fromMaybe False ((==) <$> a <*> b))
     HsFnPrecursor e (Maybe Row -> Maybe Row -> LuaE e Bool)
-> Parameter e (Maybe Row)
-> HsFnPrecursor e (Maybe Row -> LuaE e Bool)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e (Maybe Row)
-> Text -> Text -> Text -> Parameter e (Maybe Row)
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter (Peek e Row -> Peek e (Maybe Row)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Peek e Row -> Peek e (Maybe Row))
-> (StackIndex -> Peek e Row) -> Peeker e (Maybe Row)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackIndex -> Peek e Row
forall e. LuaError e => Peeker e Row
peekRow) Text
"Row" Text
"self" Text
""
     HsFnPrecursor e (Maybe Row -> LuaE e Bool)
-> Parameter e (Maybe Row) -> HsFnPrecursor e (LuaE e Bool)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e (Maybe Row)
-> Text -> Text -> Text -> Parameter e (Maybe Row)
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter (Peek e Row -> Peek e (Maybe Row)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Peek e Row -> Peek e (Maybe Row))
-> (StackIndex -> Peek e Row) -> Peeker e (Maybe Row)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackIndex -> Peek e Row
forall e. LuaError e => Peeker e Row
peekRow) Text
"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 -> Text -> Text -> FunctionResults e Bool
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e Bool
forall e. Pusher e Bool
pushBool Text
"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
$ (Row -> LuaE e String) -> HsFnPrecursor e (Row -> LuaE e String)
forall a e. a -> HsFnPrecursor e a
lambda
    ### liftPure show
    HsFnPrecursor e (Row -> LuaE e String)
-> Parameter e Row -> HsFnPrecursor e (LuaE e String)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> (StackIndex -> Peek e Row)
-> Text -> Text -> Text -> Parameter e Row
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter StackIndex -> Peek e Row
forall e. LuaError e => Peeker e Row
peekRow Text
"Row" 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 -> Text -> Text -> FunctionResults e String
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e String
forall e. String -> LuaE e ()
pushString Text
"string" Text
"native Haskell representation"
  ]
  [ Name
-> Text
-> (Pusher e Attr, Row -> Attr)
-> (Peeker e Attr, Row -> Attr -> Row)
-> Member e (DocumentedFunction e) Row
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
"row attributes"
      (Pusher e Attr
forall e. LuaError e => Pusher e Attr
pushAttr, \(Row Attr
attr [Cell]
_) -> Attr
attr)
      (Peeker e Attr
forall e. LuaError e => Peeker e Attr
peekAttr, \(Row Attr
_ [Cell]
cells) Attr
attr ->
                   Attr -> [Cell] -> Row
Row Attr
attr [Cell]
cells)
  , Name
-> Text
-> (Pusher e [Cell], Row -> [Cell])
-> (Peeker e [Cell], Row -> [Cell] -> Row)
-> Member e (DocumentedFunction e) Row
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
"cells" Text
"row cells"
      (Pusher e Cell -> Pusher e [Cell]
forall e a. LuaError e => Pusher e a -> Pusher e [a]
pushPandocList Pusher e Cell
forall e. LuaError e => Cell -> LuaE e ()
pushCell, \(Row Attr
_ [Cell]
cells) -> [Cell]
cells)
      (Peeker e Cell -> Peeker e [Cell]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Cell
forall e. LuaError e => Peeker e Cell
peekCellFuzzy, \(Row Attr
attr [Cell]
_) [Cell]
cells ->
                                 Attr -> [Cell] -> Row
Row Attr
attr [Cell]
cells)

  , AliasIndex
-> Text -> [AliasIndex] -> Member e (DocumentedFunction e) Row
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) Row
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) Row
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) Row
forall e a.
DocumentedFunction e -> Member e (DocumentedFunction e) a
method (DocumentedFunction e -> Member e (DocumentedFunction e) Row)
-> DocumentedFunction e -> Member e (DocumentedFunction e) Row
forall a b. (a -> b) -> a -> b
$ Name -> (Row -> LuaE e Row) -> HsFnPrecursor e (Row -> LuaE e Row)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"clone"
    ### return
    HsFnPrecursor e (Row -> LuaE e Row)
-> Parameter e Row -> HsFnPrecursor e (LuaE e Row)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> (StackIndex -> Peek e Row)
-> Text -> Text -> Text -> Parameter e Row
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter StackIndex -> Peek e Row
forall e. LuaError e => Peeker e Row
peekRow Text
"Row" Text
"self" Text
""
    HsFnPrecursor e (LuaE e Row)
-> FunctionResults e Row -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e Row -> Text -> Text -> FunctionResults e Row
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e Row
forall e. LuaError e => Row -> LuaE e ()
pushRow Text
"Row" Text
"cloned object"

  , DocumentedFunction e -> Member e (DocumentedFunction e) Row
forall e a.
DocumentedFunction e -> Member e (DocumentedFunction e) a
method (DocumentedFunction e -> Member e (DocumentedFunction e) Row)
-> DocumentedFunction e -> Member e (DocumentedFunction e) Row
forall a b. (a -> b) -> a -> b
$ Name
-> (Row -> Filter -> LuaE e Row)
-> HsFnPrecursor e (Row -> Filter -> LuaE e Row)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"walk"
    ### flip walkBlocksAndInlines
    HsFnPrecursor e (Row -> Filter -> LuaE e Row)
-> Parameter e Row -> HsFnPrecursor e (Filter -> LuaE e Row)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> (StackIndex -> Peek e Row)
-> Text -> Text -> Text -> Parameter e Row
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter StackIndex -> Peek e Row
forall e. LuaError e => Peeker e Row
peekRow Text
"Row" Text
"self" Text
""
    HsFnPrecursor e (Filter -> LuaE e Row)
-> Parameter e Filter -> HsFnPrecursor e (LuaE e Row)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e Filter -> Text -> Text -> Text -> Parameter e Filter
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker e Filter
forall e. LuaError e => Peeker e Filter
peekFilter Text
"Filter" Text
"lua_filter" Text
"table of filter functions"
    HsFnPrecursor e (LuaE e Row)
-> FunctionResults e Row -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e Row -> Text -> Text -> FunctionResults e Row
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e Row
forall e. LuaError e => Row -> LuaE e ()
pushRow Text
"Row" Text
"modified cell"
  ]

-- | Constructor function for 'Row' values.
mkRow :: LuaError e => DocumentedFunction e
mkRow :: DocumentedFunction e
mkRow = Name
-> (Maybe [Cell] -> Maybe Attr -> LuaE e Row)
-> HsFnPrecursor e (Maybe [Cell] -> Maybe Attr -> LuaE e Row)
forall a e. Name -> a -> HsFnPrecursor e a
defun Name
"Row"
  ### liftPure2 (\mCells mAttr -> Row
                  (fromMaybe nullAttr mAttr)
                  (fromMaybe [] mCells))
  HsFnPrecursor e (Maybe [Cell] -> Maybe Attr -> LuaE e Row)
-> Parameter e (Maybe [Cell])
-> HsFnPrecursor e (Maybe Attr -> LuaE e Row)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter e [Cell] -> Parameter e (Maybe [Cell])
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker e [Cell] -> Text -> Text -> Text -> Parameter e [Cell]
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter (Peeker e Cell -> Peeker e [Cell]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker e Cell
forall e. LuaError e => Peeker e Cell
peekCellFuzzy) Text
"{Cell,...}" Text
"cells" Text
"row cells")
  HsFnPrecursor e (Maybe Attr -> LuaE e Row)
-> Parameter e (Maybe Attr) -> HsFnPrecursor e (LuaE e Row)
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 -> Text -> Text -> Text -> Parameter e Attr
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker e Attr
forall e. LuaError e => Peeker e Attr
peekAttr Text
"Attr" Text
"attr" Text
"cell attributes")
  HsFnPrecursor e (LuaE e Row)
-> FunctionResults e Row -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e Row -> Text -> Text -> FunctionResults e Row
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e Row
forall e. LuaError e => Row -> LuaE e ()
pushRow Text
"Row" Text
"new Row object"