|
Packit Service |
d2f85f |
{-
|
|
Packit Service |
d2f85f |
Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
d2f85f |
it under the terms of the GNU General Public License as published by
|
|
Packit Service |
d2f85f |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
d2f85f |
(at your option) any later version.
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
This program is distributed in the hope that it will be useful,
|
|
Packit Service |
d2f85f |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
d2f85f |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
d2f85f |
GNU General Public License for more details.
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
You should have received a copy of the GNU General Public License
|
|
Packit Service |
d2f85f |
along with this program; if not, write to the Free Software
|
|
Packit Service |
d2f85f |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit Service |
d2f85f |
-}
|
|
Packit Service |
d2f85f |
{-# LANGUAGE FlexibleContexts #-}
|
|
Packit Service |
d2f85f |
{- |
|
|
Packit Service |
d2f85f |
Module : Text.Pandoc.Lua.Module.Pandoc
|
|
Packit Service |
d2f85f |
Copyright : Copyright © 2017 Albert Krewinkel
|
|
Packit Service |
d2f85f |
License : GNU GPL, version 2 or above
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
|
|
Packit Service |
d2f85f |
Stability : alpha
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
Pandoc module for lua.
|
|
Packit Service |
d2f85f |
-}
|
|
Packit Service |
d2f85f |
module Text.Pandoc.Lua.Module.Pandoc
|
|
Packit Service |
d2f85f |
( pushModule
|
|
Packit Service |
d2f85f |
) where
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
import Control.Monad (when)
|
|
Packit Service |
d2f85f |
import Data.Default (Default (..))
|
|
Packit Service |
d2f85f |
import Data.Maybe (fromMaybe)
|
|
Packit Service |
d2f85f |
import Data.Text (pack)
|
|
Packit Service |
d2f85f |
import Foreign.Lua (ToLuaStack, FromLuaStack, Lua, NumResults, liftIO)
|
|
Packit Service |
d2f85f |
import System.Exit (ExitCode (..))
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Class (runIO)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Definition (Block, Inline)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Lua.Filter (walkInlines, walkBlocks, LuaFilter)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Lua.StackInstances ()
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Lua.Util (OrNil (toMaybe), addFunction, addValue,
|
|
Packit Service |
d2f85f |
loadScriptFromDataDir, raiseError)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Walk (Walkable)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Options (ReaderOptions (readerExtensions))
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Process (pipeProcess)
|
|
Packit Service |
d2f85f |
import Text.Pandoc.Readers (Reader (..), getReader)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
import qualified Data.ByteString.Lazy as BL
|
|
Packit Service |
d2f85f |
import qualified Data.ByteString.Lazy.Char8 as BSL
|
|
Packit Service |
d2f85f |
import qualified Foreign.Lua as Lua
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
-- | Push the "pandoc" on the lua stack. Requires the `list` module to be
|
|
Packit Service |
d2f85f |
-- loaded.
|
|
Packit Service |
d2f85f |
pushModule :: Maybe FilePath -> Lua NumResults
|
|
Packit Service |
d2f85f |
pushModule datadir = do
|
|
Packit Service |
d2f85f |
loadScriptFromDataDir datadir "pandoc.lua"
|
|
Packit Service |
d2f85f |
addFunction "read" readDoc
|
|
Packit Service |
d2f85f |
addFunction "pipe" pipeFn
|
|
Packit Service |
d2f85f |
addFunction "walk_block" walkBlock
|
|
Packit Service |
d2f85f |
addFunction "walk_inline" walkInline
|
|
Packit Service |
d2f85f |
return 1
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
walkElement :: (ToLuaStack a, Walkable [Inline] a, Walkable [Block] a)
|
|
Packit Service |
d2f85f |
=> a -> LuaFilter -> Lua a
|
|
Packit Service |
d2f85f |
walkElement x f = walkInlines f x >>= walkBlocks f
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
walkInline :: Inline -> LuaFilter -> Lua Inline
|
|
Packit Service |
d2f85f |
walkInline = walkElement
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
walkBlock :: Block -> LuaFilter -> Lua Block
|
|
Packit Service |
d2f85f |
walkBlock = walkElement
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
readDoc :: String -> OrNil String -> Lua NumResults
|
|
Packit Service |
d2f85f |
readDoc content formatSpecOrNil = do
|
|
Packit Service |
d2f85f |
let formatSpec = fromMaybe "markdown" (toMaybe formatSpecOrNil)
|
|
Packit Service |
d2f85f |
case getReader formatSpec of
|
|
Packit Service |
d2f85f |
Left s -> raiseError s -- Unknown reader
|
|
Packit Service |
d2f85f |
Right (reader, es) ->
|
|
Packit Service |
d2f85f |
case reader of
|
|
Packit Service |
d2f85f |
TextReader r -> do
|
|
Packit Service |
d2f85f |
res <- liftIO $ runIO $ r def{ readerExtensions = es } (pack content)
|
|
Packit Service |
d2f85f |
case res of
|
|
Packit Service |
d2f85f |
Right pd -> (1 :: NumResults) <$ Lua.push pd -- success, push Pandoc
|
|
Packit Service |
d2f85f |
Left s -> raiseError (show s) -- error while reading
|
|
Packit Service |
d2f85f |
_ -> raiseError "Only string formats are supported at the moment."
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
-- | Pipes input through a command.
|
|
Packit Service |
d2f85f |
pipeFn :: String
|
|
Packit Service |
d2f85f |
-> [String]
|
|
Packit Service |
d2f85f |
-> BL.ByteString
|
|
Packit Service |
d2f85f |
-> Lua NumResults
|
|
Packit Service |
d2f85f |
pipeFn command args input = do
|
|
Packit Service |
d2f85f |
(ec, output) <- liftIO $ pipeProcess Nothing command args input
|
|
Packit Service |
d2f85f |
case ec of
|
|
Packit Service |
d2f85f |
ExitSuccess -> 1 <$ Lua.push output
|
|
Packit Service |
d2f85f |
ExitFailure n -> raiseError (PipeError command n output)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
data PipeError = PipeError
|
|
Packit Service |
d2f85f |
{ pipeErrorCommand :: String
|
|
Packit Service |
d2f85f |
, pipeErrorCode :: Int
|
|
Packit Service |
d2f85f |
, pipeErrorOutput :: BL.ByteString
|
|
Packit Service |
d2f85f |
}
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
instance FromLuaStack PipeError where
|
|
Packit Service |
d2f85f |
peek idx =
|
|
Packit Service |
d2f85f |
PipeError
|
|
Packit Service |
d2f85f |
<$> (Lua.getfield idx "command" *> Lua.peek (-1) <* Lua.pop 1)
|
|
Packit Service |
d2f85f |
<*> (Lua.getfield idx "error_code" *> Lua.peek (-1) <* Lua.pop 1)
|
|
Packit Service |
d2f85f |
<*> (Lua.getfield idx "output" *> Lua.peek (-1) <* Lua.pop 1)
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
instance ToLuaStack PipeError where
|
|
Packit Service |
d2f85f |
push pipeErr = do
|
|
Packit Service |
d2f85f |
Lua.newtable
|
|
Packit Service |
d2f85f |
addValue "command" (pipeErrorCommand pipeErr)
|
|
Packit Service |
d2f85f |
addValue "error_code" (pipeErrorCode pipeErr)
|
|
Packit Service |
d2f85f |
addValue "output" (pipeErrorOutput pipeErr)
|
|
Packit Service |
d2f85f |
pushPipeErrorMetaTable
|
|
Packit Service |
d2f85f |
Lua.setmetatable (-2)
|
|
Packit Service |
d2f85f |
where
|
|
Packit Service |
d2f85f |
pushPipeErrorMetaTable :: Lua ()
|
|
Packit Service |
d2f85f |
pushPipeErrorMetaTable = do
|
|
Packit Service |
d2f85f |
v <- Lua.newmetatable "pandoc pipe error"
|
|
Packit Service |
d2f85f |
when v $ addFunction "__tostring" pipeErrorMessage
|
|
Packit Service |
d2f85f |
|
|
Packit Service |
d2f85f |
pipeErrorMessage :: PipeError -> Lua BL.ByteString
|
|
Packit Service |
d2f85f |
pipeErrorMessage (PipeError cmd errorCode output) = return $ mconcat
|
|
Packit Service |
d2f85f |
[ BSL.pack "Error running "
|
|
Packit Service |
d2f85f |
, BSL.pack cmd
|
|
Packit Service |
d2f85f |
, BSL.pack " (error code "
|
|
Packit Service |
d2f85f |
, BSL.pack $ show errorCode
|
|
Packit Service |
d2f85f |
, BSL.pack "): "
|
|
Packit Service |
d2f85f |
, if output == mempty then BSL.pack "<no output>" else output
|
|
Packit Service |
d2f85f |
]
|