{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}
{- |
   Module      : Text.Pandoc.Writers.Custom
   Copyright   : Copyright (C) 2012-2022 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Conversion of 'Pandoc' documents to custom markup using
a Lua writer.
-}
module Text.Pandoc.Writers.Custom ( writeCustom ) where
import Control.Applicative (optional)
import Control.Arrow ((***))
import Control.Exception
import Control.Monad (when)
import Data.List (intersperse)
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import Data.Text (Text, pack)
import HsLua as Lua hiding (Operation (Div))
import HsLua.Aeson (peekViaJSON)
import Text.DocLayout (render, literal)
import Text.DocTemplates (Context)
import Control.Monad.IO.Class (MonadIO)
import Text.Pandoc.Definition
import Text.Pandoc.Lua (Global (..), runLua, setGlobals)
import Text.Pandoc.Lua.Marshal.Attr (pushAttributeList)
import Text.Pandoc.Options
import Text.Pandoc.Class (PandocMonad)
import Text.Pandoc.Templates (renderTemplate)
import Text.Pandoc.Writers.Shared

-- | List of key-value pairs that is pushed to Lua as AttributeList
-- userdata.
newtype AttributeList = AttributeList [(Text, Text)]
instance Pushable AttributeList where
  push :: AttributeList -> LuaE e ()
push (AttributeList kvs :: [(Text, Text)]
kvs) = Pusher e [(Text, Text)]
forall e. LuaError e => Pusher e [(Text, Text)]
pushAttributeList [(Text, Text)]
kvs

attrToMap :: Attr -> AttributeList
attrToMap :: Attr -> AttributeList
attrToMap (id' :: Text
id',classes :: [Text]
classes,keyvals :: [(Text, Text)]
keyvals) = [(Text, Text)] -> AttributeList
AttributeList
    ([(Text, Text)] -> AttributeList)
-> [(Text, Text)] -> AttributeList
forall a b. (a -> b) -> a -> b
$ ("id", Text
id')
    (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
forall a. a -> [a] -> [a]
: ("class", [Text] -> Text
T.unwords [Text]
classes)
    (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
forall a. a -> [a] -> [a]
: [(Text, Text)]
keyvals

newtype Stringify a = Stringify a

instance Pushable (Stringify Format) where
  push :: Stringify Format -> LuaE e ()
push (Stringify (Format f :: Text
f)) = Text -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push (Text -> Text
T.toLower Text
f)

instance Pushable (Stringify [Inline]) where
  push :: Stringify [Inline] -> LuaE e ()
push (Stringify ils :: [Inline]
ils) = String -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push (String -> LuaE e ()) -> LuaE e String -> LuaE e ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Inline] -> LuaE e String
forall e. LuaError e => [Inline] -> LuaE e String
inlineListToCustom [Inline]
ils

instance Pushable (Stringify [Block]) where
  push :: Stringify [Block] -> LuaE e ()
push (Stringify blks :: [Block]
blks) = String -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push (String -> LuaE e ()) -> LuaE e String -> LuaE e ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [Block] -> LuaE e String
forall e. LuaError e => [Block] -> LuaE e String
blockListToCustom [Block]
blks

instance Pushable (Stringify MetaValue) where
  push :: Stringify MetaValue -> LuaE e ()
push (Stringify (MetaMap m :: Map Text MetaValue
m))       = Map Text (Stringify MetaValue) -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push ((MetaValue -> Stringify MetaValue)
-> Map Text MetaValue -> Map Text (Stringify MetaValue)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaValue -> Stringify MetaValue
forall a. a -> Stringify a
Stringify Map Text MetaValue
m)
  push (Stringify (MetaList xs :: [MetaValue]
xs))     = [Stringify MetaValue] -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push ((MetaValue -> Stringify MetaValue)
-> [MetaValue] -> [Stringify MetaValue]
forall a b. (a -> b) -> [a] -> [b]
map MetaValue -> Stringify MetaValue
forall a. a -> Stringify a
Stringify [MetaValue]
xs)
  push (Stringify (MetaBool x :: Bool
x))      = Bool -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push Bool
x
  push (Stringify (MetaString s :: Text
s))    = Text -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push Text
s
  push (Stringify (MetaInlines ils :: [Inline]
ils)) = Stringify [Inline] -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
ils)
  push (Stringify (MetaBlocks bs :: [Block]
bs))   = Stringify [Block] -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify [Block]
bs)

instance Pushable (Stringify Citation) where
  push :: Stringify Citation -> LuaE e ()
push (Stringify cit :: Citation
cit) = ([(Name, Citation -> LuaE e ())] -> Citation -> LuaE e ())
-> Citation -> [(Name, Citation -> LuaE e ())] -> LuaE e ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip [(Name, Citation -> LuaE e ())] -> Citation -> LuaE e ()
forall e a.
LuaError e =>
[(Name, a -> LuaE e ())] -> a -> LuaE e ()
pushAsTable Citation
cit
    [ ("citationId", Text -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (Text -> LuaE e ()) -> (Citation -> Text) -> Citation -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> Text
citationId)
    , ("citationPrefix",  Stringify [Inline] -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (Stringify [Inline] -> LuaE e ())
-> (Citation -> Stringify [Inline]) -> Citation -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify ([Inline] -> Stringify [Inline])
-> (Citation -> [Inline]) -> Citation -> Stringify [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> [Inline]
citationPrefix)
    , ("citationSuffix",  Stringify [Inline] -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (Stringify [Inline] -> LuaE e ())
-> (Citation -> Stringify [Inline]) -> Citation -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify ([Inline] -> Stringify [Inline])
-> (Citation -> [Inline]) -> Citation -> Stringify [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> [Inline]
citationSuffix)
    , ("citationMode",    CitationMode -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (CitationMode -> LuaE e ())
-> (Citation -> CitationMode) -> Citation -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> CitationMode
citationMode)
    , ("citationNoteNum", Int -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (Int -> LuaE e ()) -> (Citation -> Int) -> Citation -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> Int
citationNoteNum)
    , ("citationHash",    Int -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (Int -> LuaE e ()) -> (Citation -> Int) -> Citation -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> Int
citationHash)
    ]

-- | Key-value pair, pushed as a table with @a@ as the only key and @v@ as the
-- associated value.
newtype KeyValue a b = KeyValue (a, b)

instance (Pushable a, Pushable b) => Pushable (KeyValue a b) where
  push :: KeyValue a b -> LuaE e ()
push (KeyValue (k :: a
k, v :: b
v)) = do
    LuaE e ()
forall e. LuaE e ()
Lua.newtable
    a -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push a
k
    b -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push b
v
    StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
Lua.rawset (CInt -> StackIndex
Lua.nth 3)

-- | Convert Pandoc to custom markup.
writeCustom :: (PandocMonad m, MonadIO m)
            => FilePath -> WriterOptions -> Pandoc -> m Text
writeCustom :: String -> WriterOptions -> Pandoc -> m Text
writeCustom luaFile :: String
luaFile opts :: WriterOptions
opts doc :: Pandoc
doc@(Pandoc meta :: Meta
meta _) = do
  let globals :: [Global]
globals = [ Pandoc -> Global
PANDOC_DOCUMENT Pandoc
doc
                , String -> Global
PANDOC_SCRIPT_FILE String
luaFile
                , WriterOptions -> Global
PANDOC_WRITER_OPTIONS WriterOptions
opts
                ]
  Either PandocError (Text, Context Text)
res <- LuaE PandocError (Text, Context Text)
-> m (Either PandocError (Text, Context Text))
forall (m :: * -> *) a.
(PandocMonad m, MonadIO m) =>
LuaE PandocError a -> m (Either PandocError a)
runLua (LuaE PandocError (Text, Context Text)
 -> m (Either PandocError (Text, Context Text)))
-> LuaE PandocError (Text, Context Text)
-> m (Either PandocError (Text, Context Text))
forall a b. (a -> b) -> a -> b
$ do
    [Global] -> LuaE PandocError ()
setGlobals [Global]
globals
    Status
stat <- String -> LuaE PandocError Status
forall e. String -> LuaE e Status
dofileTrace String
luaFile
    -- check for error in lua script (later we'll change the return type
    -- to handle this more gracefully):
    Bool -> LuaE PandocError () -> LuaE PandocError ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Status
stat Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
/= Status
Lua.OK)
      LuaE PandocError ()
forall e a. LuaError e => LuaE e a
Lua.throwErrorAsException
    (rendered :: String
rendered, context :: Context Text
context) <- WriterOptions -> Pandoc -> LuaE PandocError (String, Context Text)
forall e.
LuaError e =>
WriterOptions -> Pandoc -> LuaE e (String, Context Text)
docToCustom WriterOptions
opts Pandoc
doc
    Context Text
metaContext <- WriterOptions
-> ([Block] -> LuaE PandocError (Doc Text))
-> ([Inline] -> LuaE PandocError (Doc Text))
-> Meta
-> LuaE PandocError (Context Text)
forall (m :: * -> *) a.
(Monad m, TemplateTarget a) =>
WriterOptions
-> ([Block] -> m (Doc a))
-> ([Inline] -> m (Doc a))
-> Meta
-> m (Context a)
metaToContext WriterOptions
opts
                   ((String -> Doc Text)
-> LuaE PandocError String -> LuaE PandocError (Doc Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal (Text -> Doc Text) -> (String -> Text) -> String -> Doc Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack) (LuaE PandocError String -> LuaE PandocError (Doc Text))
-> ([Block] -> LuaE PandocError String)
-> [Block]
-> LuaE PandocError (Doc Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> LuaE PandocError String
forall e. LuaError e => [Block] -> LuaE e String
blockListToCustom)
                   ((String -> Doc Text)
-> LuaE PandocError String -> LuaE PandocError (Doc Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal (Text -> Doc Text) -> (String -> Text) -> String -> Doc Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack) (LuaE PandocError String -> LuaE PandocError (Doc Text))
-> ([Inline] -> LuaE PandocError String)
-> [Inline]
-> LuaE PandocError (Doc Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> LuaE PandocError String
forall e. LuaError e => [Inline] -> LuaE e String
inlineListToCustom)
                   Meta
meta
    (Text, Context Text) -> LuaE PandocError (Text, Context Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Text
pack String
rendered, Context Text
context Context Text -> Context Text -> Context Text
forall a. Semigroup a => a -> a -> a
<> Context Text
metaContext)
  case Either PandocError (Text, Context Text)
res of
    Left msg :: PandocError
msg -> PandocError -> m Text
forall a e. Exception e => e -> a
throw PandocError
msg
    Right (body :: Text
body, context :: Context Text
context) -> Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> m Text) -> Text -> m Text
forall a b. (a -> b) -> a -> b
$
      case WriterOptions -> Maybe (Template Text)
writerTemplate WriterOptions
opts of
        Nothing  -> Text
body
        Just tpl :: Template Text
tpl -> Maybe Int -> Doc Text -> Text
forall a. HasChars a => Maybe Int -> Doc a -> a
render Maybe Int
forall a. Maybe a
Nothing (Doc Text -> Text) -> Doc Text -> Text
forall a b. (a -> b) -> a -> b
$
                    Template Text -> Context Text -> Doc Text
forall a b.
(TemplateTarget a, ToContext a b) =>
Template a -> b -> Doc a
renderTemplate Template Text
tpl (Context Text -> Doc Text) -> Context Text -> Doc Text
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Context Text -> Context Text
forall a b. ToContext a b => Text -> b -> Context a -> Context a
setField "body" Text
body Context Text
context

docToCustom :: forall e. LuaError e
            => WriterOptions -> Pandoc -> LuaE e (String, Context Text)
docToCustom :: WriterOptions -> Pandoc -> LuaE e (String, Context Text)
docToCustom opts :: WriterOptions
opts (Pandoc (Meta metamap :: Map Text MetaValue
metamap) blocks :: [Block]
blocks) = do
  String
body <- [Block] -> LuaE e String
forall e. LuaError e => [Block] -> LuaE e String
blockListToCustom [Block]
blocks
  -- invoke doesn't work with multiple return values, so we have to call
  -- `Doc` manually.
  Name -> LuaE e Type
forall e. LuaError e => Name -> LuaE e Type
Lua.getglobal "Doc"                 -- function
  String -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push String
body                           -- argument 1
  Map Text (Stringify MetaValue) -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push ((MetaValue -> Stringify MetaValue)
-> Map Text MetaValue -> Map Text (Stringify MetaValue)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaValue -> Stringify MetaValue
forall a. a -> Stringify a
Stringify  Map Text MetaValue
metamap)      -- argument 2
  Context Text -> LuaE e ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
push (WriterOptions -> Context Text
writerVariables WriterOptions
opts)         -- argument 3
  NumArgs -> NumResults -> LuaE e ()
forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
call 3 2
  String
rendered  <- StackIndex -> LuaE e String
forall a e. (LuaError e, Peekable a) => StackIndex -> LuaE e a
peek (CInt -> StackIndex
nth 2)           -- first return value
  Maybe (Context Text)
context <- Peek e (Maybe (Context Text)) -> LuaE e (Maybe (Context Text))
forall e a. LuaError e => Peek e a -> LuaE e a
forcePeek (Peek e (Maybe (Context Text)) -> LuaE e (Maybe (Context Text)))
-> (Peek e (Context Text) -> Peek e (Maybe (Context Text)))
-> Peek e (Context Text)
-> LuaE e (Maybe (Context Text))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Peek e (Context Text) -> Peek e (Maybe (Context Text))
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Peek e (Context Text) -> LuaE e (Maybe (Context Text)))
-> Peek e (Context Text) -> LuaE e (Maybe (Context Text))
forall a b. (a -> b) -> a -> b
$ Peeker e (Context Text)
forall a e. (FromJSON a, LuaError e) => Peeker e a
peekViaJSON StackIndex
top  -- snd return value
  (String, Context Text) -> LuaE e (String, Context Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (String
rendered, Context Text -> Maybe (Context Text) -> Context Text
forall a. a -> Maybe a -> a
fromMaybe Context Text
forall a. Monoid a => a
mempty Maybe (Context Text)
context)

-- | Convert Pandoc block element to Custom.
blockToCustom :: forall e. LuaError e
              => Block         -- ^ Block element
              -> LuaE e String

blockToCustom :: Block -> LuaE e String
blockToCustom Null = String -> LuaE e String
forall (m :: * -> *) a. Monad m => a -> m a
return ""

blockToCustom (Plain inlines :: [Inline]
inlines) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Plain" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
inlines)

blockToCustom (Para [Image attr :: Attr
attr txt :: [Inline]
txt (src :: Text
src,tit :: Text
tit)]) =
  Name
-> Text
-> Text
-> Stringify [Inline]
-> AttributeList
-> LuaE e String
forall a. Invokable a => Name -> a
invoke "CaptionedImage" Text
src Text
tit ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
txt) (Attr -> AttributeList
attrToMap Attr
attr)

blockToCustom (Para inlines :: [Inline]
inlines) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Para" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
inlines)

blockToCustom (LineBlock linesList :: [[Inline]]
linesList) =
  Name -> [Stringify [Inline]] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "LineBlock" (([Inline] -> Stringify [Inline])
-> [[Inline]] -> [Stringify [Inline]]
forall a b. (a -> b) -> [a] -> [b]
map ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify) [[Inline]]
linesList)

blockToCustom (RawBlock format :: Format
format str :: Text
str) =
  Name -> Stringify Format -> Text -> LuaE e String
forall a. Invokable a => Name -> a
invoke "RawBlock" (Format -> Stringify Format
forall a. a -> Stringify a
Stringify Format
format) Text
str

blockToCustom HorizontalRule = Name -> LuaE e String
forall a. Invokable a => Name -> a
invoke "HorizontalRule"

blockToCustom (Header level :: Int
level attr :: Attr
attr inlines :: [Inline]
inlines) =
  Name -> Int -> Stringify [Inline] -> AttributeList -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Header" Int
level ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
inlines) (Attr -> AttributeList
attrToMap Attr
attr)

blockToCustom (CodeBlock attr :: Attr
attr str :: Text
str) =
  Name -> Text -> AttributeList -> LuaE e String
forall a. Invokable a => Name -> a
invoke "CodeBlock" Text
str (Attr -> AttributeList
attrToMap Attr
attr)

blockToCustom (BlockQuote blocks :: [Block]
blocks) =
  Name -> Stringify [Block] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "BlockQuote" ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify [Block]
blocks)

blockToCustom (Table _ blkCapt :: Caption
blkCapt specs :: [ColSpec]
specs thead :: TableHead
thead tbody :: [TableBody]
tbody tfoot :: TableFoot
tfoot) =
  let (capt :: [Inline]
capt, aligns :: [Alignment]
aligns, widths :: [Double]
widths, headers :: [[Block]]
headers, rows :: [[[Block]]]
rows) = Caption
-> [ColSpec]
-> TableHead
-> [TableBody]
-> TableFoot
-> ([Inline], [Alignment], [Double], [[Block]], [[[Block]]])
toLegacyTable Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot
      aligns' :: [String]
aligns' = (Alignment -> String) -> [Alignment] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Alignment -> String
forall a. Show a => a -> String
show [Alignment]
aligns
      capt' :: Stringify [Inline]
capt' = [Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
capt
      headers' :: [Stringify [Block]]
headers' = ([Block] -> Stringify [Block]) -> [[Block]] -> [Stringify [Block]]
forall a b. (a -> b) -> [a] -> [b]
map ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify) [[Block]]
headers
      rows' :: [[Stringify [Block]]]
rows' = ([[Block]] -> [Stringify [Block]])
-> [[[Block]]] -> [[Stringify [Block]]]
forall a b. (a -> b) -> [a] -> [b]
map (([Block] -> Stringify [Block]) -> [[Block]] -> [Stringify [Block]]
forall a b. (a -> b) -> [a] -> [b]
map ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify)) [[[Block]]]
rows
  in Name
-> Stringify [Inline]
-> [String]
-> [Double]
-> [Stringify [Block]]
-> [[Stringify [Block]]]
-> LuaE e String
forall a. Invokable a => Name -> a
invoke "Table" Stringify [Inline]
capt' [String]
aligns' [Double]
widths [Stringify [Block]]
headers' [[Stringify [Block]]]
rows'

blockToCustom (BulletList items :: [[Block]]
items) =
  Name -> [Stringify [Block]] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "BulletList" (([Block] -> Stringify [Block]) -> [[Block]] -> [Stringify [Block]]
forall a b. (a -> b) -> [a] -> [b]
map ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify) [[Block]]
items)

blockToCustom (OrderedList (num :: Int
num,sty :: ListNumberStyle
sty,delim :: ListNumberDelim
delim) items :: [[Block]]
items) =
  Name
-> [Stringify [Block]] -> Int -> String -> String -> LuaE e String
forall a. Invokable a => Name -> a
invoke "OrderedList" (([Block] -> Stringify [Block]) -> [[Block]] -> [Stringify [Block]]
forall a b. (a -> b) -> [a] -> [b]
map ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify) [[Block]]
items) Int
num (ListNumberStyle -> String
forall a. Show a => a -> String
show ListNumberStyle
sty) (ListNumberDelim -> String
forall a. Show a => a -> String
show ListNumberDelim
delim)

blockToCustom (DefinitionList items :: [([Inline], [[Block]])]
items) =
  Name
-> [KeyValue (Stringify [Inline]) [Stringify [Block]]]
-> LuaE e String
forall a. Invokable a => Name -> a
invoke "DefinitionList"
               ((([Inline], [[Block]])
 -> KeyValue (Stringify [Inline]) [Stringify [Block]])
-> [([Inline], [[Block]])]
-> [KeyValue (Stringify [Inline]) [Stringify [Block]]]
forall a b. (a -> b) -> [a] -> [b]
map ((Stringify [Inline], [Stringify [Block]])
-> KeyValue (Stringify [Inline]) [Stringify [Block]]
forall a b. (a, b) -> KeyValue a b
KeyValue ((Stringify [Inline], [Stringify [Block]])
 -> KeyValue (Stringify [Inline]) [Stringify [Block]])
-> (([Inline], [[Block]])
    -> (Stringify [Inline], [Stringify [Block]]))
-> ([Inline], [[Block]])
-> KeyValue (Stringify [Inline]) [Stringify [Block]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify ([Inline] -> Stringify [Inline])
-> ([[Block]] -> [Stringify [Block]])
-> ([Inline], [[Block]])
-> (Stringify [Inline], [Stringify [Block]])
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** ([Block] -> Stringify [Block]) -> [[Block]] -> [Stringify [Block]]
forall a b. (a -> b) -> [a] -> [b]
map ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify))) [([Inline], [[Block]])]
items)

blockToCustom (Div attr :: Attr
attr items :: [Block]
items) =
  Name -> Stringify [Block] -> AttributeList -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Div" ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify [Block]
items) (Attr -> AttributeList
attrToMap Attr
attr)

-- | Convert list of Pandoc block elements to Custom.
blockListToCustom :: forall e. LuaError e
                  => [Block]       -- ^ List of block elements
                  -> LuaE e String
blockListToCustom :: [Block] -> LuaE e String
blockListToCustom xs :: [Block]
xs = do
  String
blocksep <- Name -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Blocksep"
  [String]
bs <- (Block -> LuaE e String) -> [Block] -> LuaE e [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Block -> LuaE e String
forall e. LuaError e => Block -> LuaE e String
blockToCustom [Block]
xs
  String -> LuaE e String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> LuaE e String) -> String -> LuaE e String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall a. Monoid a => [a] -> a
mconcat ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
blocksep [String]
bs

-- | Convert list of Pandoc inline elements to Custom.
inlineListToCustom :: forall e. LuaError e => [Inline] -> LuaE e String
inlineListToCustom :: [Inline] -> LuaE e String
inlineListToCustom lst :: [Inline]
lst = do
  [String]
xs <- (Inline -> LuaE e String) -> [Inline] -> LuaE e [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (LuaError e => Inline -> LuaE e String
forall e. LuaError e => Inline -> LuaE e String
inlineToCustom @e) [Inline]
lst
  String -> LuaE e String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> LuaE e String) -> String -> LuaE e String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall a. Monoid a => [a] -> a
mconcat [String]
xs

-- | Convert Pandoc inline element to Custom.
inlineToCustom :: forall e. LuaError e => Inline -> LuaE e String

inlineToCustom :: Inline -> LuaE e String
inlineToCustom (Str str :: Text
str) = Name -> Text -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Str" Text
str

inlineToCustom Space = Name -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Space"

inlineToCustom SoftBreak = Name -> LuaE e String
forall a. Invokable a => Name -> a
invoke "SoftBreak"

inlineToCustom (Emph lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Emph" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Underline lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Underline" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Strong lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Strong" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Strikeout lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Strikeout" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Superscript lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Superscript" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Subscript lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Subscript" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (SmallCaps lst :: [Inline]
lst) = Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "SmallCaps" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Quoted SingleQuote lst :: [Inline]
lst) =
  Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "SingleQuoted" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Quoted DoubleQuote lst :: [Inline]
lst) =
  Name -> Stringify [Inline] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "DoubleQuoted" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst)

inlineToCustom (Cite cs :: [Citation]
cs lst :: [Inline]
lst) =
  Name -> Stringify [Inline] -> [Stringify Citation] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Cite" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
lst) ((Citation -> Stringify Citation)
-> [Citation] -> [Stringify Citation]
forall a b. (a -> b) -> [a] -> [b]
map (Citation -> Stringify Citation
forall a. a -> Stringify a
Stringify) [Citation]
cs)

inlineToCustom (Code attr :: Attr
attr str :: Text
str) =
  Name -> Text -> AttributeList -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Code" Text
str (Attr -> AttributeList
attrToMap Attr
attr)

inlineToCustom (Math DisplayMath str :: Text
str) =
  Name -> Text -> LuaE e String
forall a. Invokable a => Name -> a
invoke "DisplayMath" Text
str

inlineToCustom (Math InlineMath str :: Text
str) =
  Name -> Text -> LuaE e String
forall a. Invokable a => Name -> a
invoke "InlineMath" Text
str

inlineToCustom (RawInline format :: Format
format str :: Text
str) =
  Name -> Stringify Format -> Text -> LuaE e String
forall a. Invokable a => Name -> a
invoke "RawInline" (Format -> Stringify Format
forall a. a -> Stringify a
Stringify Format
format) Text
str

inlineToCustom LineBreak = Name -> LuaE e String
forall a. Invokable a => Name -> a
invoke "LineBreak"

inlineToCustom (Link attr :: Attr
attr txt :: [Inline]
txt (src :: Text
src,tit :: Text
tit)) =
  Name
-> Stringify [Inline]
-> Text
-> Text
-> AttributeList
-> LuaE e String
forall a. Invokable a => Name -> a
invoke "Link" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
txt) Text
src Text
tit (Attr -> AttributeList
attrToMap Attr
attr)

inlineToCustom (Image attr :: Attr
attr alt :: [Inline]
alt (src :: Text
src,tit :: Text
tit)) =
  Name
-> Stringify [Inline]
-> Text
-> Text
-> AttributeList
-> LuaE e String
forall a. Invokable a => Name -> a
invoke "Image" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
alt) Text
src Text
tit (Attr -> AttributeList
attrToMap Attr
attr)

inlineToCustom (Note contents :: [Block]
contents) = Name -> Stringify [Block] -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Note" ([Block] -> Stringify [Block]
forall a. a -> Stringify a
Stringify [Block]
contents)

inlineToCustom (Span attr :: Attr
attr items :: [Inline]
items) =
  Name -> Stringify [Inline] -> AttributeList -> LuaE e String
forall a. Invokable a => Name -> a
invoke "Span" ([Inline] -> Stringify [Inline]
forall a. a -> Stringify a
Stringify [Inline]
items) (Attr -> AttributeList
attrToMap Attr
attr)