pandoc-lua-engine 0.4.1.1 → 0.4.2
raw patch · 5 files changed
+119/−19 lines, 5 filesdep ~citeprocdep ~pandocbinary-addedPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: citeproc, pandoc
API changes (from Hackage documentation)
Files
- pandoc-lua-engine.cabal +5/−3
- src/Text/Pandoc/Lua/Module/Pandoc.hs +57/−16
- test/lua/module/include.tex +1/−0
- test/lua/module/pandoc.lua +56/−0
- test/lua/module/sample.epub binary
pandoc-lua-engine.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: pandoc-lua-engine-version: 0.4.1.1+version: 0.4.2 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md@@ -26,8 +26,10 @@ , test/extensions.lua , test/lua/*.lua , test/lua/module/*.lua+ , test/lua/module/include.tex , test/lua/module/partial.test , test/lua/module/sample.svg+ , test/lua/module/sample.epub , test/lua/module/tiny.epub , test/sample.lua , test/tables.custom@@ -108,7 +110,7 @@ build-depends: aeson , bytestring >= 0.9 && < 0.13 , crypton >= 0.30 && < 1.1- , citeproc >= 0.8 && < 0.9+ , citeproc >= 0.8 && < 0.10 , containers >= 0.6.0.1 && < 0.9 , data-default >= 0.4 && < 0.9 , doclayout >= 0.5 && < 0.6@@ -124,7 +126,7 @@ , hslua-repl >= 0.1.1 && < 0.2 , lpeg >= 1.1 && < 1.2 , mtl >= 2.2 && < 2.4- , pandoc >= 3.6 && < 3.7+ , pandoc >= 3.7 && < 3.8 , pandoc-lua-marshal >= 0.3 && < 0.4 , pandoc-types >= 1.22 && < 1.24 , parsec >= 3.1 && < 3.2
src/Text/Pandoc/Lua/Module/Pandoc.hs view
@@ -17,8 +17,9 @@ import Prelude hiding (read) import Control.Applicative ((<|>))-import Control.Monad (forM_, when)+import Control.Monad (foldM, forM_, when) import Control.Monad.Catch (catch, handle, throwM)+import Control.Monad.Except (MonadError (throwError)) import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr) import Data.Default (Default (..)) import Data.Maybe (fromMaybe)@@ -26,9 +27,13 @@ import Data.Text.Encoding.Error (UnicodeException) import HsLua import System.Exit (ExitCode (..))+import Text.Pandoc.Class ( PandocMonad, FileInfo (..), FileTree+ , addToFileTree, getCurrentTime+ , insertInFileTree, sandboxWithFileTree+ ) import Text.Pandoc.Definition import Text.Pandoc.Error (PandocError (..))-import Text.Pandoc.Format (parseFlavoredFormat)+import Text.Pandoc.Format (FlavoredFormat, parseFlavoredFormat) import Text.Pandoc.Lua.Orphans () import Text.Pandoc.Lua.Marshal.AST import Text.Pandoc.Lua.Marshal.Format (peekFlavoredFormat)@@ -234,22 +239,28 @@ =?> "output string, or error triple" , defun "read"- ### (\content mformatspec mreaderOptions ->- handle (failLua . show @UnicodeException) . unPandocLua $ do- flvrd <- maybe (parseFlavoredFormat "markdown") pure mformatspec+ ### (\content mformatspec mreaderOptions mreadEnv -> do let readerOpts = fromMaybe def mreaderOptions- getReader flvrd >>= \case- (TextReader r, es) ->- r readerOpts{readerExtensions = es}- (case content of++ readAction :: PandocMonad m => FlavoredFormat -> m Pandoc+ readAction flvrd = getReader flvrd >>= \case+ (TextReader r, es) ->+ r readerOpts{readerExtensions = es} $+ case content of Left bs -> toSources $ UTF8.toText bs- Right sources -> sources)- (ByteStringReader r, es) ->- case content of- Left bs -> r readerOpts{readerExtensions = es}- (BSL.fromStrict bs)- Right _ -> throwM $ PandocLuaError- "Cannot use bytestring reader with Sources")+ Right sources -> sources+ (ByteStringReader r, es) ->+ case content of+ Left bs -> r readerOpts{readerExtensions = es}+ (BSL.fromStrict bs)+ Right _ -> throwError $ PandocLuaError+ "Cannot use bytestring reader with Sources"++ handle (failLua . show @UnicodeException) . unPandocLua $ do+ flvrd <- maybe (parseFlavoredFormat "markdown") pure mformatspec+ case mreadEnv of+ Nothing -> readAction flvrd+ Just tree -> sandboxWithFileTree tree (readAction flvrd)) <#> parameter (\idx -> (Left <$> peekByteString idx) <|> (Right <$> peekSources idx)) "string|Sources" "content" "text to parse"@@ -257,6 +268,15 @@ "formatspec" "format and extensions") <#> opt (parameter peekReaderOptions "ReaderOptions" "reader_options" "reader options")+ <#> opt (parameter peekReadEnv "table" "read_env" $ T.unlines+ [ "If the value is not given or `nil`, then the global environment"+ , "is used. Passing a list of filenames causes the reader to"+ , "be run in a sandbox. The given files are read from the file"+ , "system and provided to the sandbox via an ersatz file system."+ , "The table can also contain mappings from filenames to"+ , "contents, which will be used to populate the ersatz file"+ , "system."+ ]) =#> functionResult pushPandoc "Pandoc" "result document" , sha1@@ -387,3 +407,24 @@ , if output == mempty then BSL.pack "<no output>" else output ] return (NumResults 1)++-- | Peek the environment in which the `read` function operates.+peekReadEnv :: Peeker PandocError FileTree+peekReadEnv idx = do+ mtime <- liftLua . unPandocLua $ getCurrentTime++ -- Add files from file system+ files <- peekList peekString idx+ tree1 <- liftLua $+ foldM (\tree fp -> liftIO $ addToFileTree tree fp) mempty files++ -- Add files from key-value pairs+ let toFileInfo contents = FileInfo+ { infoFileMTime = mtime+ , infoFileContents = contents+ }+ pairs <- peekKeyValuePairs peekString (fmap toFileInfo . peekByteString) idx+ let tree2 = foldr (uncurry insertInFileTree) tree1 pairs++ -- Return ersatz file system.+ pure tree2
+ test/lua/module/include.tex view
@@ -0,0 +1,1 @@+included
test/lua/module/pandoc.lua view
@@ -293,6 +293,62 @@ 'Unknown input format nosuchreader' ) end),+ group 'read_env' {+ test('images are added to the mediabag', function ()+ local epub = io.open('lua/module/sample.epub', 'rb'):read('a')+ local _ = pandoc.read(epub, 'epub')+ assert.are_equal(#pandoc.mediabag.list(), 1)+ end),+ test('images from EPUB are added when using the sandbox', function ()+ local epub = io.open('lua/module/sample.epub', 'rb'):read('a')+ local _ = pandoc.read(epub, 'epub', nil, {})+ assert.are_equal(#pandoc.mediabag.list(), 1)+ end),+ test('includes work in global env', function ()+ local tex = '\\include{lua/module/include.tex}'+ local doc = pandoc.read(tex, 'latex')+ assert.are_equal(+ doc.blocks,+ pandoc.Blocks{pandoc.Para 'included'}+ )+ end),+ test('sandbox disallows access to the filesystem', function ()+ local tex = '\\include{lua/module/include.tex}'+ local doc = pandoc.read(tex, 'latex', nil, {})+ assert.are_equal(doc.blocks, pandoc.Blocks{})+ end),+ test('files can be added to the sandbox', function ()+ local tex = '\\include{lua/module/include.tex}'+ local doc = pandoc.read(tex, 'latex', nil, {'lua/module/include.tex'})+ assert.are_equal(+ doc.blocks,+ pandoc.Blocks{pandoc.Para 'included'}+ )+ end),+ test('sandbox files can be given as key-value pairs', function ()+ local tex = '\\include{lua/module/include.tex}'+ local files = {+ ['lua/module/include.tex'] = 'Hello'+ }+ local doc = pandoc.read(tex, 'latex', nil, files)+ assert.are_equal(+ doc.blocks,+ pandoc.Blocks{pandoc.Para 'Hello'}+ )+ end),+ test('kv-pairs override contents read from file system', function ()+ local tex = '\\include{lua/module/include.tex}'+ local files = {+ 'lua/module/include.tex',+ ['lua/module/include.tex'] = 'Hello'+ }+ local doc = pandoc.read(tex, 'latex', nil, files)+ assert.are_equal(+ doc.blocks,+ pandoc.Blocks{pandoc.Para 'Hello'}+ )+ end),+ }, group 'extensions' { test('string spec', function () local doc = pandoc.read('"vice versa"', 'markdown-smart')
+ test/lua/module/sample.epub view
binary file changed (absent → 5522 bytes)