pandoc-lua-engine-0.4: src/Text/Pandoc/Lua/Marshal/Chunks.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Text.Pandoc.Lua.Marshal.Chunks
Copyright : © 2022 Albert Krewinkel
License : GPL-2.0-or-later
Maintainer : Albert Krewinkel <albert+pandoc@tarleb.com>
Marshaling chunks, i.e., pandoc subdocuments.
-}
module Text.Pandoc.Lua.Marshal.Chunks
( peekChunk
, pushChunk
, peekChunkedDoc
, pushChunkedDoc
) where
import Control.Monad ((<$!>))
import Data.Tree (Tree (..))
import HsLua
import Text.Pandoc.Chunks (Chunk (..), ChunkedDoc (..), SecInfo (..))
import Text.Pandoc.Lua.Marshal.AST
-- | Retrieves a 'Chunk' from the Lua stack.
peekChunk :: LuaError e => Peeker e Chunk
peekChunk = peekUD typeChunk
-- | Pushes a 'Chunk' to the top of the Lua stack.
pushChunk :: LuaError e => Pusher e Chunk
pushChunk = pushUD typeChunk
typeChunk :: LuaError e => DocumentedType e Chunk
typeChunk = deftype "Chunk"
[ operation Tostring $ lambda
### liftPure show
<#> udparam typeChunk "chunk" "chunk to print in native format"
=#> functionResult pushString "string" "Haskell representation"
]
[ property "heading"
"heading text"
(pushInlines, chunkHeading)
(peekInlinesFuzzy, \chunk inlns -> chunk{ chunkHeading = inlns })
, property "id"
"identifier"
(pushText, chunkId)
(peekText, \chunk ident -> chunk{ chunkId = ident })
, property "level"
"level of topmost heading in chunk"
(pushIntegral, chunkLevel)
(peekIntegral, \chunk level -> chunk{ chunkLevel = level })
, property "number"
"chunk number"
(pushIntegral, chunkNumber)
(peekIntegral, \chunk number -> chunk{ chunkNumber = number })
, property "section_number"
"hierarchical section number"
(pushMaybe pushText, chunkSectionNumber)
(peekMaybe peekText, \chunk secnum -> chunk{ chunkSectionNumber = secnum })
, property "path"
"target filepath for this chunk"
(pushString, chunkPath)
(peekString, \chunk path -> chunk{ chunkPath = path })
, property "up"
"link to the enclosing section chunk, if any"
(pushMaybe pushChunk, chunkUp)
(peekMaybe peekChunk, \chunk up -> chunk{ chunkUp = up })
, property "prev"
"link to the previous section, if any"
(pushMaybe pushChunk, chunkPrev)
(peekMaybe peekChunk, \chunk prev -> chunk{ chunkPrev = prev })
, property "next"
"link to the next section, if any"
(pushMaybe pushChunk, chunkNext)
(peekMaybe peekChunk, \chunk next' -> chunk{ chunkNext = next' })
, property "unlisted"
( "whether the section in this chunk should be listed in the TOC" <>
"even if the chunk has no section number" )
(pushBool, chunkUnlisted)
(peekBool, \chunk unlisted -> chunk { chunkUnlisted = unlisted })
, property "contents"
"the chunk's block contents"
(pushBlocks, chunkContents)
(peekBlocksFuzzy, \chunk blks -> chunk{ chunkContents = blks })
]
-- | Retrieves a 'ChunkedDoc' from the Lua stack.
peekChunkedDoc :: LuaError e => Peeker e ChunkedDoc
peekChunkedDoc = peekUD typeChunkedDoc
-- | Pushes a 'ChunkedDoc to the top of the Lua stack.
pushChunkedDoc :: LuaError e => Pusher e ChunkedDoc
pushChunkedDoc = pushUD typeChunkedDoc
-- | Lua type for 'ChunkedDoc' values.
typeChunkedDoc :: LuaError e => DocumentedType e ChunkedDoc
typeChunkedDoc = deftype "ChunkedDoc"
[]
[ readonly "chunks"
"list of chunks that make up the document"
(pushList pushChunk, chunkedChunks)
, readonly "meta"
"the document's metadata"
(pushMeta, chunkedMeta)
, readonly "toc"
"table of contents information"
(pushTocTree, chunkedTOC)
]
-- | Pushes a TOC tree to the stack. The resulting object is a list with
-- the top-level entry placed at index @0@ and all subentries as the
-- rest of the list.
pushTocTree :: LuaError e => Pusher e (Tree SecInfo)
pushTocTree (Node secInfo subSecInfo) = do
pushList pushTocTree subSecInfo
pushSecInfo secInfo
rawseti (nth 2) 0
pushSecInfo :: LuaError e => Pusher e SecInfo
pushSecInfo = pushAsTable
[ ("title" , pushInlines . secTitle)
, ("number" , maybe pushnil pushText . secNumber)
, ("id" , pushText . secId)
, ("path" , pushText . secPath)
, ("level" , pushIntegral . secLevel)
]
peekMaybe :: LuaError e => Peeker e a -> Peeker e (Maybe a)
peekMaybe p idx = liftLua (isnoneornil idx) >>= \case
True -> pure Nothing
False -> Just <$!> p idx
pushMaybe :: LuaError e => Pusher e a -> Pusher e (Maybe a)
pushMaybe = maybe pushnil