diff options
Diffstat (limited to 'src/Text/Pandoc/Lua/Module')
-rw-r--r-- | src/Text/Pandoc/Lua/Module/MediaBag.hs | 77 | ||||
-rw-r--r-- | src/Text/Pandoc/Lua/Module/Pandoc.hs | 32 | ||||
-rw-r--r-- | src/Text/Pandoc/Lua/Module/Utils.hs | 38 |
3 files changed, 58 insertions, 89 deletions
diff --git a/src/Text/Pandoc/Lua/Module/MediaBag.hs b/src/Text/Pandoc/Lua/Module/MediaBag.hs index 3a296ef46..e5a10217a 100644 --- a/src/Text/Pandoc/Lua/Module/MediaBag.hs +++ b/src/Text/Pandoc/Lua/Module/MediaBag.hs @@ -14,13 +14,13 @@ module Text.Pandoc.Lua.Module.MediaBag ) where import Control.Monad (zipWithM_) -import Foreign.Lua (Lua, NumResults, Optional, liftIO) +import Foreign.Lua (Lua, NumResults, Optional) import Text.Pandoc.Class.CommonState (CommonState (..)) -import Text.Pandoc.Class.PandocIO (runIOorExplode) -import Text.Pandoc.Class.PandocMonad (fetchItem, putCommonState, setMediaBag) +import Text.Pandoc.Class.PandocMonad (fetchItem, getMediaBag, modifyCommonState, + setMediaBag) import Text.Pandoc.Lua.Marshaling () import Text.Pandoc.Lua.Marshaling.MediaBag (pushIterator) -import Text.Pandoc.Lua.Util (addFunction) +import Text.Pandoc.Lua.PandocLua (PandocLua (..), liftPandocLua, addFunction) import Text.Pandoc.MIME (MimeType) import qualified Data.ByteString.Lazy as BL @@ -31,9 +31,9 @@ import qualified Text.Pandoc.MediaBag as MB -- -- MediaBag submodule -- -pushModule :: Lua NumResults +pushModule :: PandocLua NumResults pushModule = do - Lua.newtable + liftPandocLua Lua.newtable addFunction "delete" delete addFunction "empty" empty addFunction "insert" insertMediaFn @@ -43,66 +43,46 @@ pushModule = do addFunction "fetch" fetch return 1 --- --- Port functions from Text.Pandoc.Class to the Lua monad. --- TODO: reuse existing functions. - --- Get the current CommonState. -getCommonState :: Lua CommonState -getCommonState = do - Lua.getglobal "PANDOC_STATE" - Lua.peek Lua.stackTop - --- Replace MediaBag in CommonState. -setCommonState :: CommonState -> Lua () -setCommonState st = do - Lua.push st - Lua.setglobal "PANDOC_STATE" - -modifyCommonState :: (CommonState -> CommonState) -> Lua () -modifyCommonState f = getCommonState >>= setCommonState . f - -- | Delete a single item from the media bag. -delete :: FilePath -> Lua NumResults +delete :: FilePath -> PandocLua NumResults delete fp = 0 <$ modifyCommonState (\st -> st { stMediaBag = MB.deleteMedia fp (stMediaBag st) }) -- | Delete all items from the media bag. -empty :: Lua NumResults +empty :: PandocLua NumResults empty = 0 <$ modifyCommonState (\st -> st { stMediaBag = mempty }) -- | Insert a new item into the media bag. insertMediaFn :: FilePath -> Optional MimeType -> BL.ByteString - -> Lua NumResults + -> PandocLua NumResults insertMediaFn fp optionalMime contents = do - modifyCommonState $ \st -> - let mb = MB.insertMedia fp (Lua.fromOptional optionalMime) contents - (stMediaBag st) - in st { stMediaBag = mb } - return 0 + mb <- getMediaBag + setMediaBag $ MB.insertMedia fp (Lua.fromOptional optionalMime) contents mb + return (Lua.NumResults 0) -- | Returns iterator values to be used with a Lua @for@ loop. -items :: Lua NumResults -items = getCommonState >>= pushIterator . stMediaBag +items :: PandocLua NumResults +items = getMediaBag >>= liftPandocLua . pushIterator lookupMediaFn :: FilePath - -> Lua NumResults + -> PandocLua NumResults lookupMediaFn fp = do - res <- MB.lookupMedia fp . stMediaBag <$> getCommonState - case res of + res <- MB.lookupMedia fp <$> getMediaBag + liftPandocLua $ case res of Nothing -> 1 <$ Lua.pushnil Just (mimeType, contents) -> do Lua.push mimeType Lua.push contents return 2 -mediaDirectoryFn :: Lua NumResults +mediaDirectoryFn :: PandocLua NumResults mediaDirectoryFn = do - dirContents <- MB.mediaDirectory . stMediaBag <$> getCommonState - Lua.newtable - zipWithM_ addEntry [1..] dirContents + dirContents <- MB.mediaDirectory <$> getMediaBag + liftPandocLua $ do + Lua.newtable + zipWithM_ addEntry [1..] dirContents return 1 where addEntry :: Lua.Integer -> (FilePath, MimeType, Int) -> Lua () @@ -114,14 +94,9 @@ mediaDirectoryFn = do Lua.rawseti (-2) idx fetch :: T.Text - -> Lua NumResults + -> PandocLua NumResults fetch src = do - commonState <- getCommonState - let mediaBag = stMediaBag commonState - (bs, mimeType) <- liftIO . runIOorExplode $ do - putCommonState commonState - setMediaBag mediaBag - fetchItem src - Lua.push $ maybe "" T.unpack mimeType - Lua.push bs + (bs, mimeType) <- fetchItem src + liftPandocLua . Lua.push $ maybe "" T.unpack mimeType + liftPandocLua $ Lua.push bs return 2 -- returns 2 values: contents, mimetype diff --git a/src/Text/Pandoc/Lua/Module/Pandoc.hs b/src/Text/Pandoc/Lua/Module/Pandoc.hs index f376d0044..3886568b7 100644 --- a/src/Text/Pandoc/Lua/Module/Pandoc.hs +++ b/src/Text/Pandoc/Lua/Module/Pandoc.hs @@ -24,6 +24,8 @@ import Text.Pandoc.Class.PandocIO (runIO) import Text.Pandoc.Definition (Block, Inline) import Text.Pandoc.Lua.Filter (walkInlines, walkBlocks, LuaFilter, SingletonsList (..)) import Text.Pandoc.Lua.Marshaling () +import Text.Pandoc.Lua.PandocLua (PandocLua, addFunction, liftPandocLua, + loadScriptFromDataDir) import Text.Pandoc.Walk (Walkable) import Text.Pandoc.Options (ReaderOptions (readerExtensions)) import Text.Pandoc.Process (pipeProcess) @@ -38,28 +40,28 @@ import Text.Pandoc.Error -- | Push the "pandoc" on the lua stack. Requires the `list` module to be -- loaded. -pushModule :: Maybe FilePath -> Lua NumResults -pushModule datadir = do - LuaUtil.loadScriptFromDataDir datadir "pandoc.lua" - LuaUtil.addFunction "read" readDoc - LuaUtil.addFunction "pipe" pipeFn - LuaUtil.addFunction "walk_block" walkBlock - LuaUtil.addFunction "walk_inline" walkInline +pushModule :: PandocLua NumResults +pushModule = do + loadScriptFromDataDir "pandoc.lua" + addFunction "read" readDoc + addFunction "pipe" pipeFn + addFunction "walk_block" walkBlock + addFunction "walk_inline" walkInline return 1 walkElement :: (Walkable (SingletonsList Inline) a, Walkable (SingletonsList Block) a) - => a -> LuaFilter -> Lua a -walkElement x f = walkInlines f x >>= walkBlocks f + => a -> LuaFilter -> PandocLua a +walkElement x f = liftPandocLua $ walkInlines f x >>= walkBlocks f -walkInline :: Inline -> LuaFilter -> Lua Inline +walkInline :: Inline -> LuaFilter -> PandocLua Inline walkInline = walkElement -walkBlock :: Block -> LuaFilter -> Lua Block +walkBlock :: Block -> LuaFilter -> PandocLua Block walkBlock = walkElement -readDoc :: T.Text -> Optional T.Text -> Lua NumResults -readDoc content formatSpecOrNil = do +readDoc :: T.Text -> Optional T.Text -> PandocLua NumResults +readDoc content formatSpecOrNil = liftPandocLua $ do let formatSpec = fromMaybe "markdown" (Lua.fromOptional formatSpecOrNil) res <- Lua.liftIO . runIO $ getReader formatSpec >>= \(rdr,es) -> @@ -80,8 +82,8 @@ readDoc content formatSpecOrNil = do pipeFn :: String -> [String] -> BL.ByteString - -> Lua NumResults -pipeFn command args input = do + -> PandocLua NumResults +pipeFn command args input = liftPandocLua $ do (ec, output) <- Lua.liftIO $ pipeProcess Nothing command args input case ec of ExitSuccess -> 1 <$ Lua.push output diff --git a/src/Text/Pandoc/Lua/Module/Utils.hs b/src/Text/Pandoc/Lua/Module/Utils.hs index 36bb2f59c..4fe5e255d 100644 --- a/src/Text/Pandoc/Lua/Module/Utils.hs +++ b/src/Text/Pandoc/Lua/Module/Utils.hs @@ -18,13 +18,11 @@ import Control.Monad.Catch (try) import Data.Default (def) import Data.Version (Version) import Foreign.Lua (Peekable, Lua, NumResults) -import Text.Pandoc.Class.PandocIO (runIO) -import Text.Pandoc.Class.PandocMonad (setUserDataDir) import Text.Pandoc.Definition ( Pandoc, Meta, MetaValue (..), Block, Inline , Citation, Attr, ListAttributes) import Text.Pandoc.Error (PandocError) import Text.Pandoc.Lua.Marshaling () -import Text.Pandoc.Lua.Util (addFunction) +import Text.Pandoc.Lua.PandocLua (PandocLua, addFunction, liftPandocLua) import qualified Data.Digest.Pure.SHA as SHA import qualified Data.ByteString.Lazy as BSL @@ -35,14 +33,14 @@ import qualified Text.Pandoc.Filter.JSON as JSONFilter import qualified Text.Pandoc.Shared as Shared -- | Push the "pandoc.utils" module to the lua stack. -pushModule :: Maybe FilePath -> Lua NumResults -pushModule mbDatadir = do - Lua.newtable +pushModule :: PandocLua NumResults +pushModule = do + liftPandocLua Lua.newtable addFunction "blocks_to_inlines" blocksToInlines addFunction "equals" equals addFunction "make_sections" makeSections addFunction "normalize_date" normalizeDate - addFunction "run_json_filter" (runJSONFilter mbDatadir) + addFunction "run_json_filter" runJSONFilter addFunction "sha1" sha1 addFunction "stringify" stringify addFunction "to_roman_numeral" toRomanNumeral @@ -50,8 +48,8 @@ pushModule mbDatadir = do return 1 -- | Squashes a list of blocks into inlines. -blocksToInlines :: [Block] -> Lua.Optional [Inline] -> Lua [Inline] -blocksToInlines blks optSep = do +blocksToInlines :: [Block] -> Lua.Optional [Inline] -> PandocLua [Inline] +blocksToInlines blks optSep = liftPandocLua $ do let sep = case Lua.fromOptional optSep of Just x -> B.fromList x Nothing -> Shared.defaultBlocksSeparator @@ -70,23 +68,17 @@ normalizeDate :: T.Text -> Lua (Lua.Optional T.Text) normalizeDate = return . Lua.Optional . Shared.normalizeDate -- | Run a JSON filter on the given document. -runJSONFilter :: Maybe FilePath - -> Pandoc +runJSONFilter :: Pandoc -> FilePath -> Lua.Optional [String] - -> Lua NumResults -runJSONFilter mbDatadir doc filterFile optArgs = do + -> PandocLua Pandoc +runJSONFilter doc filterFile optArgs = do args <- case Lua.fromOptional optArgs of Just x -> return x - Nothing -> do + Nothing -> liftPandocLua $ do Lua.getglobal "FORMAT" (:[]) <$> Lua.popValue - filterRes <- Lua.liftIO . runIO $ do - setUserDataDir mbDatadir - JSONFilter.apply def args filterFile doc - case filterRes of - Left err -> Lua.raiseError (show err) - Right d -> (1 :: NumResults) <$ Lua.push d + JSONFilter.apply def args filterFile doc -- | Calculate the hash of the given contents. sha1 :: BSL.ByteString @@ -96,7 +88,7 @@ sha1 = return . T.pack . SHA.showDigest . SHA.sha1 -- | Convert pandoc structure to a string with formatting removed. -- Footnotes are skipped (since we don't want their contents in link -- labels). -stringify :: AstElement -> Lua T.Text +stringify :: AstElement -> PandocLua T.Text stringify el = return $ case el of PandocElement pd -> Shared.stringify pd InlineElement i -> Shared.stringify i @@ -112,7 +104,7 @@ stringifyMetaValue mv = case mv of MetaString s -> s _ -> Shared.stringify mv -equals :: AstElement -> AstElement -> Lua Bool +equals :: AstElement -> AstElement -> PandocLua Bool equals e1 e2 = return (e1 == e2) data AstElement @@ -141,5 +133,5 @@ instance Peekable AstElement where "Expected an AST element, but could not parse value as such." -- | Convert a number < 4000 to uppercase roman numeral. -toRomanNumeral :: Lua.Integer -> Lua T.Text +toRomanNumeral :: Lua.Integer -> PandocLua T.Text toRomanNumeral = return . Shared.toRomanNumeral . fromIntegral |