{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Text.Pandoc.Lua.Module.Pandoc
( pushModule
, documentedModule
) where
import Prelude hiding (read)
import Control.Monad (forM_, when)
import Control.Monad.Catch (catch, throwM)
import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr)
import Data.Default (Default (..))
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy (Proxy))
import HsLua hiding (pushModule)
import System.Exit (ExitCode (..))
import Text.Pandoc.Definition
import Text.Pandoc.Error (PandocError (..))
import Text.Pandoc.Lua.Orphans ()
import Text.Pandoc.Lua.Marshal.AST
import Text.Pandoc.Lua.Marshal.Filter (peekFilter)
import Text.Pandoc.Lua.Marshal.ReaderOptions ( peekReaderOptions
, pushReaderOptions)
import Text.Pandoc.Lua.Marshal.WriterOptions ( peekWriterOptions
, pushWriterOptions)
import Text.Pandoc.Lua.Module.Utils (sha1)
import Text.Pandoc.Lua.PandocLua (PandocLua (unPandocLua), liftPandocLua)
import Text.Pandoc.Options ( ReaderOptions (readerExtensions)
, WriterOptions (writerExtensions) )
import Text.Pandoc.Process (pipeProcess)
import Text.Pandoc.Readers (Reader (..), getReader)
import Text.Pandoc.Writers (Writer (..), getWriter)
import qualified HsLua as Lua
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Char8 as BSL
import qualified Data.Text as T
import qualified Text.Pandoc.UTF8 as UTF8
pushModule :: PandocLua NumResults
pushModule :: PandocLua NumResults
pushModule = do
LuaE PandocError () -> PandocLua ()
forall a. LuaE PandocError a -> PandocLua a
liftPandocLua (LuaE PandocError () -> PandocLua ())
-> LuaE PandocError () -> PandocLua ()
forall a b. (a -> b) -> a -> b
$ Module PandocError -> LuaE PandocError ()
forall e. LuaError e => Module e -> LuaE e ()
Lua.pushModule Module PandocError
documentedModule
NumResults -> PandocLua NumResults
forall (m :: * -> *) a. Monad m => a -> m a
return 1
documentedModule :: Module PandocError
documentedModule :: Module PandocError
documentedModule = $WModule :: forall e.
Name
-> Text
-> [Field e]
-> [DocumentedFunction e]
-> [(Operation, DocumentedFunction e)]
-> Module e
Module
{ moduleName :: Name
moduleName = "pandoc"
, moduleDescription :: Text
moduleDescription = [Text] -> Text
T.unlines
[ "Lua functions for pandoc scripts; includes constructors for"
, "document elements, functions to parse text in a given"
, "format, and functions to filter and modify a subtree."
]
, moduleFields :: [Field PandocError]
moduleFields = [Field PandocError]
forall e. [Field e]
stringConstants [Field PandocError] -> [Field PandocError] -> [Field PandocError]
forall a. [a] -> [a] -> [a]
++ [Field PandocError
inlineField, Field PandocError
blockField]
, moduleOperations :: [(Operation, DocumentedFunction PandocError)]
moduleOperations = []
, moduleFunctions :: [DocumentedFunction PandocError]
moduleFunctions = [[DocumentedFunction PandocError]]
-> [DocumentedFunction PandocError]
forall a. Monoid a => [a] -> a
mconcat
[ [DocumentedFunction PandocError]
functions
, [DocumentedFunction PandocError]
forall e. LuaError e => [DocumentedFunction e]
otherConstructors
, [DocumentedFunction PandocError]
forall e. LuaError e => [DocumentedFunction e]
blockConstructors
, [DocumentedFunction PandocError]
forall e. LuaError e => [DocumentedFunction e]
inlineConstructors
, [DocumentedFunction PandocError]
forall e. LuaError e => [DocumentedFunction e]
metaValueConstructors
]
}
inlineField :: Field PandocError
inlineField :: Field PandocError
inlineField = $WField :: forall e. Text -> Text -> LuaE e () -> Field e
Field
{ fieldName :: Text
fieldName = "Inline"
, fieldDescription :: Text
fieldDescription = "Inline constructors, nested under 'constructors'."
, fieldPushValue :: LuaE PandocError ()
fieldPushValue = [DocumentedFunction PandocError] -> LuaE PandocError ()
pushWithConstructorsSubtable [DocumentedFunction PandocError]
forall e. LuaError e => [DocumentedFunction e]
inlineConstructors
}
blockField :: Field PandocError
blockField :: Field PandocError
blockField = $WField :: forall e. Text -> Text -> LuaE e () -> Field e
Field
{ fieldName :: Text
fieldName = "Block"
, fieldDescription :: Text
fieldDescription = "Inline constructors, nested under 'constructors'."
, fieldPushValue :: LuaE PandocError ()
fieldPushValue = [DocumentedFunction PandocError] -> LuaE PandocError ()
pushWithConstructorsSubtable [DocumentedFunction PandocError]
forall e. LuaError e => [DocumentedFunction e]
blockConstructors
}
pushWithConstructorsSubtable :: [DocumentedFunction PandocError]
-> LuaE PandocError ()
constructors :: [DocumentedFunction PandocError]
constructors = do
LuaE PandocError ()
forall e. LuaE e ()
newtable
LuaE PandocError ()
forall e. LuaE e ()
newtable
Name -> LuaE PandocError ()
forall e. Name -> LuaE e ()
pushName "constructor" LuaE PandocError () -> LuaE PandocError () -> LuaE PandocError ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> StackIndex -> LuaE PandocError ()
forall e. StackIndex -> LuaE e ()
pushvalue (CInt -> StackIndex
nth 2) LuaE PandocError () -> LuaE PandocError () -> LuaE PandocError ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> StackIndex -> LuaE PandocError ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth 4)
[DocumentedFunction PandocError]
-> (DocumentedFunction PandocError -> LuaE PandocError ())
-> LuaE PandocError ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [DocumentedFunction PandocError]
constructors ((DocumentedFunction PandocError -> LuaE PandocError ())
-> LuaE PandocError ())
-> (DocumentedFunction PandocError -> LuaE PandocError ())
-> LuaE PandocError ()
forall a b. (a -> b) -> a -> b
$ \fn :: DocumentedFunction PandocError
fn -> do
Name -> LuaE PandocError ()
forall e. Name -> LuaE e ()
pushName (DocumentedFunction PandocError -> Name
forall e. DocumentedFunction e -> Name
functionName DocumentedFunction PandocError
fn)
DocumentedFunction PandocError -> LuaE PandocError ()
forall e. LuaError e => DocumentedFunction e -> LuaE e ()
pushDocumentedFunction DocumentedFunction PandocError
fn
StackIndex -> LuaE PandocError ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth 3)
Int -> LuaE PandocError ()
forall e. Int -> LuaE e ()
pop 1
otherConstructors :: LuaError e => [DocumentedFunction e]
otherConstructors :: [DocumentedFunction e]
otherConstructors =
[ DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkPandoc
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkMeta
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkAttr
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkAttributeList
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkBlocks
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkCitation
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkCell
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkRow
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkTableHead
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkTableFoot
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkInlines
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkListAttributes
, DocumentedFunction e
forall e. LuaError e => DocumentedFunction e
mkSimpleTable
, Name
-> (ReaderOptions -> LuaE e ReaderOptions)
-> HsFnPrecursor e (ReaderOptions -> LuaE e ReaderOptions)
forall a e. Name -> a -> HsFnPrecursor e a
defun "ReaderOptions"
### liftPure id
HsFnPrecursor e (ReaderOptions -> LuaE e ReaderOptions)
-> Parameter e ReaderOptions
-> HsFnPrecursor e (LuaE e ReaderOptions)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e ReaderOptions
-> Text -> Text -> Text -> Parameter e ReaderOptions
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker e ReaderOptions
forall e. LuaError e => Peeker e ReaderOptions
peekReaderOptions "ReaderOptions|table" "opts" "reader options"
HsFnPrecursor e (LuaE e ReaderOptions)
-> FunctionResults e ReaderOptions -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e ReaderOptions
-> Text -> Text -> FunctionResults e ReaderOptions
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e ReaderOptions
forall e. LuaError e => Pusher e ReaderOptions
pushReaderOptions "ReaderOptions" "new object"
#? "Creates a new ReaderOptions value."
, Name
-> (WriterOptions -> LuaE e WriterOptions)
-> HsFnPrecursor e (WriterOptions -> LuaE e WriterOptions)
forall a e. Name -> a -> HsFnPrecursor e a
defun "WriterOptions"
### liftPure id
HsFnPrecursor e (WriterOptions -> LuaE e WriterOptions)
-> Parameter e WriterOptions
-> HsFnPrecursor e (LuaE e WriterOptions)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker e WriterOptions
-> Text -> Text -> Text -> Parameter e WriterOptions
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker e WriterOptions
forall e. LuaError e => Peeker e WriterOptions
peekWriterOptions "WriterOptions|table" "opts"
"writer options"
HsFnPrecursor e (LuaE e WriterOptions)
-> FunctionResults e WriterOptions -> DocumentedFunction e
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher e WriterOptions
-> Text -> Text -> FunctionResults e WriterOptions
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher e WriterOptions
forall e. LuaError e => Pusher e WriterOptions
pushWriterOptions "WriterOptions" "new object"
#? "Creates a new WriterOptions value."
]
stringConstants :: [Field e]
stringConstants :: [Field e]
stringConstants =
let constrs :: forall a. Data a => Proxy a -> [String]
constrs :: Proxy a -> [String]
constrs _ = (Constr -> String) -> [Constr] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Constr -> String
showConstr ([Constr] -> [String]) -> (a -> [Constr]) -> a -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataType -> [Constr]
dataTypeConstrs (DataType -> [Constr]) -> (a -> DataType) -> a -> [Constr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Data a => a -> DataType
forall a. Data a => a -> DataType
dataTypeOf @a (a -> [String]) -> a -> [String]
forall a b. (a -> b) -> a -> b
$ a
forall a. HasCallStack => a
undefined
nullaryConstructors :: [String]
nullaryConstructors = [[String]] -> [String]
forall a. Monoid a => [a] -> a
mconcat
[ Proxy ListNumberStyle -> [String]
forall a. Data a => Proxy a -> [String]
constrs (Proxy ListNumberStyle
forall k (t :: k). Proxy t
Proxy @ListNumberStyle)
, Proxy ListNumberDelim -> [String]
forall a. Data a => Proxy a -> [String]
constrs (Proxy ListNumberDelim
forall k (t :: k). Proxy t
Proxy @ListNumberDelim)
, Proxy QuoteType -> [String]
forall a. Data a => Proxy a -> [String]
constrs (Proxy QuoteType
forall k (t :: k). Proxy t
Proxy @QuoteType)
, Proxy MathType -> [String]
forall a. Data a => Proxy a -> [String]
constrs (Proxy MathType
forall k (t :: k). Proxy t
Proxy @MathType)
, Proxy Alignment -> [String]
forall a. Data a => Proxy a -> [String]
constrs (Proxy Alignment
forall k (t :: k). Proxy t
Proxy @Alignment)
, Proxy CitationMode -> [String]
forall a. Data a => Proxy a -> [String]
constrs (Proxy CitationMode
forall k (t :: k). Proxy t
Proxy @CitationMode)
]
toField :: String -> Field e
toField s :: String
s = $WField :: forall e. Text -> Text -> LuaE e () -> Field e
Field
{ fieldName :: Text
fieldName = String -> Text
T.pack String
s
, fieldDescription :: Text
fieldDescription = String -> Text
T.pack String
s
, fieldPushValue :: LuaE e ()
fieldPushValue = String -> LuaE e ()
forall e. String -> LuaE e ()
pushString String
s
}
in (String -> Field e) -> [String] -> [Field e]
forall a b. (a -> b) -> [a] -> [b]
map String -> Field e
forall e. String -> Field e
toField [String]
nullaryConstructors
functions :: [DocumentedFunction PandocError]
functions :: [DocumentedFunction PandocError]
functions =
[ Name
-> (String
-> [String] -> ByteString -> LuaE PandocError NumResults)
-> HsFnPrecursor
PandocError
(String -> [String] -> ByteString -> LuaE PandocError NumResults)
forall a e. Name -> a -> HsFnPrecursor e a
defun "pipe"
### (\command args input -> do
(ec, output) <- Lua.liftIO $ pipeProcess Nothing command args input
`catch` (throwM . PandocIOError "pipe")
case ec of
ExitSuccess -> 1 <$ Lua.pushLazyByteString output
ExitFailure n -> do
pushPipeError (PipeError (T.pack command) n output)
Lua.error)
HsFnPrecursor
PandocError
(String -> [String] -> ByteString -> LuaE PandocError NumResults)
-> Parameter PandocError String
-> HsFnPrecursor
PandocError ([String] -> ByteString -> LuaE PandocError NumResults)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError String
-> Text -> Text -> Text -> Parameter PandocError String
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError String
forall e. Peeker e String
peekString "string" "command" "path to executable"
HsFnPrecursor
PandocError ([String] -> ByteString -> LuaE PandocError NumResults)
-> Parameter PandocError [String]
-> HsFnPrecursor
PandocError (ByteString -> LuaE PandocError NumResults)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError [String]
-> Text -> Text -> Text -> Parameter PandocError [String]
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter (Peeker PandocError String -> Peeker PandocError [String]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker PandocError String
forall e. Peeker e String
peekString) "{string,...}" "args"
"list of arguments"
HsFnPrecursor
PandocError (ByteString -> LuaE PandocError NumResults)
-> Parameter PandocError ByteString
-> HsFnPrecursor PandocError (LuaE PandocError NumResults)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError ByteString
-> Text -> Text -> Text -> Parameter PandocError ByteString
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError ByteString
forall e. Peeker e ByteString
peekLazyByteString "string" "input"
"input passed to process via stdin"
HsFnPrecursor PandocError (LuaE PandocError NumResults)
-> Text -> DocumentedFunction PandocError
forall e.
HsFnPrecursor e (LuaE e NumResults) -> Text -> DocumentedFunction e
=?> "output string, or error triple"
, Name
-> (ByteString
-> Maybe Text -> Maybe ReaderOptions -> LuaE PandocError Pandoc)
-> HsFnPrecursor
PandocError
(ByteString
-> Maybe Text -> Maybe ReaderOptions -> LuaE PandocError Pandoc)
forall a e. Name -> a -> HsFnPrecursor e a
defun "read"
### (\content mformatspec mreaderOptions -> do
let formatSpec = fromMaybe "markdown" mformatspec
readerOpts = fromMaybe def mreaderOptions
readAction = getReader formatSpec >>= \case
(TextReader r, es) ->
r readerOpts{readerExtensions = es} (UTF8.toText content)
(ByteStringReader r, es) ->
r readerOpts{readerExtensions = es} (BSL.fromStrict content)
try (unPandocLua readAction) >>= \case
Right pd ->
return pd
Left (PandocUnknownReaderError f) ->
Lua.failLua . T.unpack $ "Unknown reader: " <> f
Left (PandocUnsupportedExtensionError e f) ->
Lua.failLua . T.unpack $
"Extension " <> e <> " not supported for " <> f
Left e ->
throwM e)
HsFnPrecursor
PandocError
(ByteString
-> Maybe Text -> Maybe ReaderOptions -> LuaE PandocError Pandoc)
-> Parameter PandocError ByteString
-> HsFnPrecursor
PandocError
(Maybe Text -> Maybe ReaderOptions -> LuaE PandocError Pandoc)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError ByteString
-> Text -> Text -> Text -> Parameter PandocError ByteString
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError ByteString
forall e. Peeker e ByteString
peekByteString "string" "content" "text to parse"
HsFnPrecursor
PandocError
(Maybe Text -> Maybe ReaderOptions -> LuaE PandocError Pandoc)
-> Parameter PandocError (Maybe Text)
-> HsFnPrecursor
PandocError (Maybe ReaderOptions -> LuaE PandocError Pandoc)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter PandocError Text -> Parameter PandocError (Maybe Text)
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Text -> Text -> Parameter PandocError Text
forall e. Text -> Text -> Parameter e Text
textParam "formatspec" "format and extensions")
HsFnPrecursor
PandocError (Maybe ReaderOptions -> LuaE PandocError Pandoc)
-> Parameter PandocError (Maybe ReaderOptions)
-> HsFnPrecursor PandocError (LuaE PandocError Pandoc)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter PandocError ReaderOptions
-> Parameter PandocError (Maybe ReaderOptions)
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker PandocError ReaderOptions
-> Text -> Text -> Text -> Parameter PandocError ReaderOptions
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError ReaderOptions
forall e. LuaError e => Peeker e ReaderOptions
peekReaderOptions "ReaderOptions" "reader_options"
"reader options")
HsFnPrecursor PandocError (LuaE PandocError Pandoc)
-> FunctionResults PandocError Pandoc
-> DocumentedFunction PandocError
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher PandocError Pandoc
-> Text -> Text -> FunctionResults PandocError Pandoc
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher PandocError Pandoc
forall e. LuaError e => Pusher e Pandoc
pushPandoc "Pandoc" "result document"
, DocumentedFunction PandocError
forall e. DocumentedFunction e
sha1
, Name
-> (Block -> Filter -> LuaE PandocError Block)
-> HsFnPrecursor
PandocError (Block -> Filter -> LuaE PandocError Block)
forall a e. Name -> a -> HsFnPrecursor e a
defun "walk_block"
### walkElement
HsFnPrecursor
PandocError (Block -> Filter -> LuaE PandocError Block)
-> Parameter PandocError Block
-> HsFnPrecursor PandocError (Filter -> LuaE PandocError Block)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError Block
-> Text -> Text -> Text -> Parameter PandocError Block
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError Block
forall e. LuaError e => Peeker e Block
peekBlockFuzzy "Block" "block" "element to traverse"
HsFnPrecursor PandocError (Filter -> LuaE PandocError Block)
-> Parameter PandocError Filter
-> HsFnPrecursor PandocError (LuaE PandocError Block)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError Filter
-> Text -> Text -> Text -> Parameter PandocError Filter
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError Filter
forall e. LuaError e => Peeker e Filter
peekFilter "Filter" "lua_filter" "filter functions"
HsFnPrecursor PandocError (LuaE PandocError Block)
-> FunctionResults PandocError Block
-> DocumentedFunction PandocError
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher PandocError Block
-> Text -> Text -> FunctionResults PandocError Block
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher PandocError Block
forall e. LuaError e => Pusher e Block
pushBlock "Block" "modified Block"
, Name
-> (Inline -> Filter -> LuaE PandocError Inline)
-> HsFnPrecursor
PandocError (Inline -> Filter -> LuaE PandocError Inline)
forall a e. Name -> a -> HsFnPrecursor e a
defun "walk_inline"
### walkElement
HsFnPrecursor
PandocError (Inline -> Filter -> LuaE PandocError Inline)
-> Parameter PandocError Inline
-> HsFnPrecursor PandocError (Filter -> LuaE PandocError Inline)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError Inline
-> Text -> Text -> Text -> Parameter PandocError Inline
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError Inline
forall e. LuaError e => Peeker e Inline
peekInlineFuzzy "Inline" "inline" "element to traverse"
HsFnPrecursor PandocError (Filter -> LuaE PandocError Inline)
-> Parameter PandocError Filter
-> HsFnPrecursor PandocError (LuaE PandocError Inline)
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError Filter
-> Text -> Text -> Text -> Parameter PandocError Filter
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError Filter
forall e. LuaError e => Peeker e Filter
peekFilter "Filter" "lua_filter" "filter functions"
HsFnPrecursor PandocError (LuaE PandocError Inline)
-> FunctionResults PandocError Inline
-> DocumentedFunction PandocError
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher PandocError Inline
-> Text -> Text -> FunctionResults PandocError Inline
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult Pusher PandocError Inline
forall e. LuaError e => Pusher e Inline
pushInline "Inline" "modified Inline"
, Name
-> (Pandoc
-> Maybe Text
-> Maybe WriterOptions
-> LuaE PandocError (Either ByteString Text))
-> HsFnPrecursor
PandocError
(Pandoc
-> Maybe Text
-> Maybe WriterOptions
-> LuaE PandocError (Either ByteString Text))
forall a e. Name -> a -> HsFnPrecursor e a
defun "write"
### (\doc mformatspec mwriterOpts -> do
let formatSpec = fromMaybe "html" mformatspec
writerOpts = fromMaybe def mwriterOpts
unPandocLua $ getWriter formatSpec >>= \case
(TextWriter w, es) -> Right <$>
w writerOpts{ writerExtensions = es } doc
(ByteStringWriter w, es) -> Left <$>
w writerOpts{ writerExtensions = es } doc)
HsFnPrecursor
PandocError
(Pandoc
-> Maybe Text
-> Maybe WriterOptions
-> LuaE PandocError (Either ByteString Text))
-> Parameter PandocError Pandoc
-> HsFnPrecursor
PandocError
(Maybe Text
-> Maybe WriterOptions
-> LuaE PandocError (Either ByteString Text))
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Peeker PandocError Pandoc
-> Text -> Text -> Text -> Parameter PandocError Pandoc
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError Pandoc
forall e. LuaError e => Peeker e Pandoc
peekPandoc "Pandoc" "doc" "document to convert"
HsFnPrecursor
PandocError
(Maybe Text
-> Maybe WriterOptions
-> LuaE PandocError (Either ByteString Text))
-> Parameter PandocError (Maybe Text)
-> HsFnPrecursor
PandocError
(Maybe WriterOptions -> LuaE PandocError (Either ByteString Text))
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter PandocError Text -> Parameter PandocError (Maybe Text)
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Text -> Text -> Parameter PandocError Text
forall e. Text -> Text -> Parameter e Text
textParam "formatspec" "format and extensions")
HsFnPrecursor
PandocError
(Maybe WriterOptions -> LuaE PandocError (Either ByteString Text))
-> Parameter PandocError (Maybe WriterOptions)
-> HsFnPrecursor
PandocError (LuaE PandocError (Either ByteString Text))
forall e a b.
HsFnPrecursor e (a -> b) -> Parameter e a -> HsFnPrecursor e b
<#> Parameter PandocError WriterOptions
-> Parameter PandocError (Maybe WriterOptions)
forall e a. Parameter e a -> Parameter e (Maybe a)
opt (Peeker PandocError WriterOptions
-> Text -> Text -> Text -> Parameter PandocError WriterOptions
forall e a. Peeker e a -> Text -> Text -> Text -> Parameter e a
parameter Peeker PandocError WriterOptions
forall e. LuaError e => Peeker e WriterOptions
peekWriterOptions "WriterOptions" "writer_options"
"writer options")
HsFnPrecursor
PandocError (LuaE PandocError (Either ByteString Text))
-> FunctionResults PandocError (Either ByteString Text)
-> DocumentedFunction PandocError
forall e a.
HsFnPrecursor e (LuaE e a)
-> FunctionResults e a -> DocumentedFunction e
=#> Pusher PandocError (Either ByteString Text)
-> Text
-> Text
-> FunctionResults PandocError (Either ByteString Text)
forall e a. Pusher e a -> Text -> Text -> FunctionResults e a
functionResult (Pusher PandocError ByteString
-> (Text -> LuaE PandocError ())
-> Pusher PandocError (Either ByteString Text)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Pusher PandocError ByteString
forall e. Pusher e ByteString
pushLazyByteString Text -> LuaE PandocError ()
forall e. Pusher e Text
pushText) "string"
"result document"
]
where
walkElement :: b -> Filter -> LuaE e b
walkElement x :: b
x f :: Filter
f =
Filter -> b -> LuaE e b
forall e a.
(LuaError e, Walkable (SpliceList Inline) a) =>
Filter -> a -> LuaE e a
walkInlineSplicing Filter
f b
x
LuaE e b -> (b -> LuaE e b) -> LuaE e b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Filter -> b -> LuaE e b
forall e a.
(LuaError e, Walkable [Inline] a) =>
Filter -> a -> LuaE e a
walkInlinesStraight Filter
f
LuaE e b -> (b -> LuaE e b) -> LuaE e b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Filter -> b -> LuaE e b
forall e a.
(LuaError e, Walkable (SpliceList Block) a) =>
Filter -> a -> LuaE e a
walkBlockSplicing Filter
f
LuaE e b -> (b -> LuaE e b) -> LuaE e b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Filter -> b -> LuaE e b
forall e a.
(LuaError e, Walkable [Block] a) =>
Filter -> a -> LuaE e a
walkBlocksStraight Filter
f
data PipeError = PipeError
{ PipeError -> Text
pipeErrorCommand :: T.Text
, PipeError -> Int
pipeErrorCode :: Int
, PipeError -> ByteString
pipeErrorOutput :: BL.ByteString
}
peekPipeError :: LuaError e => StackIndex -> LuaE e PipeError
peekPipeError :: StackIndex -> LuaE e PipeError
peekPipeError idx :: StackIndex
idx =
Text -> Int -> ByteString -> PipeError
PipeError
(Text -> Int -> ByteString -> PipeError)
-> LuaE e Text -> LuaE e (Int -> ByteString -> PipeError)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (StackIndex -> Name -> LuaE e Type
forall e. LuaError e => StackIndex -> Name -> LuaE e Type
Lua.getfield StackIndex
idx "command" LuaE e Type -> LuaE e Text -> LuaE e Text
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> StackIndex -> LuaE e Text
forall a e. (LuaError e, Peekable a) => StackIndex -> LuaE e a
Lua.peek (-1) LuaE e Text -> LuaE e () -> LuaE e Text
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Int -> LuaE e ()
forall e. Int -> LuaE e ()
Lua.pop 1)
LuaE e (Int -> ByteString -> PipeError)
-> LuaE e Int -> LuaE e (ByteString -> PipeError)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (StackIndex -> Name -> LuaE e Type
forall e. LuaError e => StackIndex -> Name -> LuaE e Type
Lua.getfield StackIndex
idx "error_code" LuaE e Type -> LuaE e Int -> LuaE e Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> StackIndex -> LuaE e Int
forall a e. (LuaError e, Peekable a) => StackIndex -> LuaE e a
Lua.peek (-1) LuaE e Int -> LuaE e () -> LuaE e Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Int -> LuaE e ()
forall e. Int -> LuaE e ()
Lua.pop 1)
LuaE e (ByteString -> PipeError)
-> LuaE e ByteString -> LuaE e PipeError
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (StackIndex -> Name -> LuaE e Type
forall e. LuaError e => StackIndex -> Name -> LuaE e Type
Lua.getfield StackIndex
idx "output" LuaE e Type -> LuaE e ByteString -> LuaE e ByteString
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> StackIndex -> LuaE e ByteString
forall a e. (LuaError e, Peekable a) => StackIndex -> LuaE e a
Lua.peek (-1) LuaE e ByteString -> LuaE e () -> LuaE e ByteString
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Int -> LuaE e ()
forall e. Int -> LuaE e ()
Lua.pop 1)
pushPipeError :: LuaError e => Pusher e PipeError
pushPipeError :: Pusher e PipeError
pushPipeError pipeErr :: PipeError
pipeErr = do
[(Name, Pusher e PipeError)] -> Pusher e PipeError
forall e a.
LuaError e =>
[(Name, a -> LuaE e ())] -> a -> LuaE e ()
pushAsTable [ ("command" , Pusher e Text
forall e. Pusher e Text
pushText Pusher e Text -> (PipeError -> Text) -> Pusher e PipeError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PipeError -> Text
pipeErrorCommand)
, ("error_code" , Int -> LuaE e ()
forall a e. (Integral a, Show a) => a -> LuaE e ()
pushIntegral (Int -> LuaE e ()) -> (PipeError -> Int) -> Pusher e PipeError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PipeError -> Int
pipeErrorCode)
, ("output" , Pusher e ByteString
forall e. Pusher e ByteString
pushLazyByteString Pusher e ByteString
-> (PipeError -> ByteString) -> Pusher e PipeError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PipeError -> ByteString
pipeErrorOutput)
] PipeError
pipeErr
LuaE e ()
forall e. LuaError e => LuaE e ()
pushPipeErrorMetaTable
StackIndex -> LuaE e ()
forall e. StackIndex -> LuaE e ()
Lua.setmetatable (CInt -> StackIndex
nth 2)
where
pushPipeErrorMetaTable :: LuaError e => LuaE e ()
pushPipeErrorMetaTable :: LuaE e ()
pushPipeErrorMetaTable = do
Bool
v <- Name -> LuaE e Bool
forall e. Name -> LuaE e Bool
Lua.newmetatable "pandoc pipe error"
Bool -> LuaE e () -> LuaE e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
v (LuaE e () -> LuaE e ()) -> LuaE e () -> LuaE e ()
forall a b. (a -> b) -> a -> b
$ do
Name -> LuaE e ()
forall e. Name -> LuaE e ()
pushName "__tostring"
HaskellFunction e -> LuaE e ()
forall e. LuaError e => HaskellFunction e -> LuaE e ()
pushHaskellFunction HaskellFunction e
forall e. LuaError e => LuaE e NumResults
pipeErrorMessage
StackIndex -> LuaE e ()
forall e. LuaError e => StackIndex -> LuaE e ()
rawset (CInt -> StackIndex
nth 3)
pipeErrorMessage :: LuaError e => LuaE e NumResults
pipeErrorMessage :: LuaE e NumResults
pipeErrorMessage = do
(PipeError cmd :: Text
cmd errorCode :: Int
errorCode output :: ByteString
output) <- StackIndex -> LuaE e PipeError
forall e. LuaError e => StackIndex -> LuaE e PipeError
peekPipeError (CInt -> StackIndex
nthBottom 1)
Pusher e ByteString
forall e. Pusher e ByteString
pushByteString Pusher e ByteString
-> ([ByteString] -> ByteString) -> [ByteString] -> LuaE e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BSL.toStrict (ByteString -> ByteString)
-> ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
BSL.concat ([ByteString] -> LuaE e ()) -> [ByteString] -> LuaE e ()
forall a b. (a -> b) -> a -> b
$
[ String -> ByteString
BSL.pack "Error running "
, String -> ByteString
BSL.pack (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
cmd
, String -> ByteString
BSL.pack " (error code "
, String -> ByteString
BSL.pack (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show Int
errorCode
, String -> ByteString
BSL.pack "): "
, if ByteString
output ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
forall a. Monoid a => a
mempty then String -> ByteString
BSL.pack "<no output>" else ByteString
output
]
NumResults -> LuaE e NumResults
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> NumResults
NumResults 1)