pandoc-lua-marshal-0.2.7: src/Text/Pandoc/Lua/Marshal/Content.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
Copyright : © 2021-2024 Albert Krewinkel
SPDX-License-Identifier : MIT
Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
Defines a helper type that can handle different types of 'Block' and
'Inline' element contents.
-}
module Text.Pandoc.Lua.Marshal.Content
( Content (..)
, contentTypeDescription
, peekContent
, pushContent
, peekDefinitionItem
) where
import Control.Applicative ((<|>))
import Control.Monad ((<$!>))
import HsLua
import {-# SOURCE #-} Text.Pandoc.Lua.Marshal.Block
( peekBlocksFuzzy, pushBlocks )
import {-# SOURCE #-} Text.Pandoc.Lua.Marshal.Inline
( peekInlinesFuzzy, pushInlines )
import Text.Pandoc.Lua.Marshal.List (pushPandocList)
import Text.Pandoc.Definition (Inline, Block)
--
-- Content
--
-- | Helper type to represent all the different types a `content`
-- attribute can have.
data Content
= ContentBlocks [Block]
| ContentInlines [Inline]
| ContentLines [[Inline]]
| ContentDefItems [([Inline], [[Block]])]
| ContentListItems [[Block]]
-- | Returns a human-readable type description; used for error messages.
contentTypeDescription :: Content -> String
contentTypeDescription = \case
ContentBlocks {} -> "list of Block items"
ContentInlines {} -> "list of Inline items"
ContentLines {} -> "list of Inline lists (i.e., a list of lines)"
ContentDefItems {} -> "list of definition items items"
ContentListItems {} -> "list items (i.e., list of list of Block elements)"
-- | Pushes the 'Content' to the stack.
pushContent :: LuaError e => Pusher e Content
pushContent = \case
ContentBlocks blks -> pushBlocks blks
ContentInlines inlns -> pushInlines inlns
ContentLines lns -> pushPandocList pushInlines lns
ContentDefItems itms -> pushPandocList pushDefinitionItem itms
ContentListItems itms -> pushPandocList pushBlocks itms
-- | Gets a 'Content' element from the stack.
peekContent :: LuaError e => Peeker e Content
peekContent idx =
(ContentInlines <$!> peekInlinesFuzzy idx) <|>
(ContentLines <$!> peekList peekInlinesFuzzy idx) <|>
(ContentBlocks <$!> peekBlocksFuzzy idx ) <|>
(ContentListItems <$!> peekList peekBlocksFuzzy idx) <|>
(ContentDefItems <$!> peekList peekDefinitionItem idx)
-- | Retrieves a single definition item from the stack; it is expected
-- to be a pair of a list of inlines and a list of list of blocks. Uses
-- fuzzy parsing, i.e., tries hard to convert mismatching types into the
-- expected result.
peekDefinitionItem :: LuaError e => Peeker e ([Inline], [[Block]])
peekDefinitionItem = peekPair peekInlinesFuzzy $ choice
[ peekList peekBlocksFuzzy
, \idx -> (:[]) <$!> peekBlocksFuzzy idx
]
-- | Pushes a single definition items on the stack.
pushDefinitionItem :: LuaError e => Pusher e ([Inline], [[Block]])
pushDefinitionItem = pushPair pushInlines
(pushPandocList pushBlocks)