diff options
| author | Albert Krewinkel <albert@zeitkraut.de> | 2022-10-07 21:37:57 +0200 |
|---|---|---|
| committer | John MacFarlane <jgm@berkeley.edu> | 2022-10-10 09:39:18 -0700 |
| commit | a088cbf5637596a461ba9f99b49210235d6c0a68 (patch) | |
| tree | d4703d158cf07e4dd45b96fff16166d5ea9abf31 /pandoc-lua-engine/src | |
| parent | e1e07cce65a0bb007da934245e74be1b1c8a0f6e (diff) | |
Lua: support extensions in custom writers
Custom writers can define the extensions that they support via the
global `writer_extensions`. The variable's value must be a table with
all supported extensions as keys, and their default status as values.
E.g., the below specifies that the writer support the extensions `smart`
and `sourcepos`, but only the `smart` extension is enabled by default:
writer_extensions = {
smart = true,
sourcepos = false,
}
Diffstat (limited to 'pandoc-lua-engine/src')
6 files changed, 72 insertions, 41 deletions
diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Extensions.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Extensions.hs deleted file mode 100644 index 99e5bc442..000000000 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Extensions.hs +++ /dev/null @@ -1,32 +0,0 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} -{- | - Module : Text.Pandoc.Lua.Marshaling.Extensions - Copyright : © 2022 Albert Krewinkel - License : GPL-2.0-or-later - Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de> - -Marshaling functions and instance for 'Extensions'. --} -module Text.Pandoc.Lua.Marshal.Extensions - ( peekExtensions - , pushExtensions - ) where - -import HsLua -import Text.Pandoc.Extensions (Extensions) - --- | Retrieves an 'Extensions' set from the Lua stack. -peekExtensions :: LuaError e => Peeker e Extensions -peekExtensions = peekViaJSON -{-# INLINE peekExtensions #-} - --- | Pushes a set of 'Extensions' to the top of the Lua stack. -pushExtensions :: LuaError e => Pusher e Extensions -pushExtensions = pushViaJSON -{-# INLINE pushExtensions #-} - -instance Peekable Extensions where - safepeek = peekExtensions - -instance Pushable Extensions where - push = pushExtensions diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Format.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Format.hs new file mode 100644 index 000000000..a71aeb952 --- /dev/null +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/Format.hs @@ -0,0 +1,57 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -fno-warn-orphans #-} +{- | + Module : Text.Pandoc.Lua.Marshaling.Format + Copyright : © 2022 Albert Krewinkel + License : GPL-2.0-or-later + Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de> + +Marshaling functions and instance for format related types, including +'Extensions' and 'ExtensionConfig'. +-} +module Text.Pandoc.Lua.Marshal.Format + ( peekExtensions + , pushExtensions + , peekExtensionsConfig + ) where + +import HsLua +import Text.Pandoc.Extensions (Extension, Extensions, extensionsFromList, readExtension) +import Text.Pandoc.Format (ExtensionsConfig (..)) +import qualified HsLua.Core.Utf8 as UTF8 + +-- | Retrieves an 'Extensions' set from the Lua stack. +peekExtension :: LuaError e => Peeker e Extension +peekExtension idx = do + extString <- peekString idx + case readExtension extString of + Just ext -> return ext + Nothing -> failPeek . UTF8.fromString $ + "Unknown extension: " <> extString +{-# INLINE peekExtension #-} + +-- | Retrieves an 'Extensions' set from the Lua stack. +peekExtensions :: LuaError e => Peeker e Extensions +peekExtensions = peekViaJSON +{-# INLINE peekExtensions #-} + +-- | Pushes a set of 'Extensions' to the top of the Lua stack. +pushExtensions :: LuaError e => Pusher e Extensions +pushExtensions = pushViaJSON +{-# INLINE pushExtensions #-} + +instance Peekable Extensions where + safepeek = peekExtensions + +instance Pushable Extensions where + push = pushExtensions + +-- | Retrieves an 'ExtensionsConfig' value from the Lua stack. +peekExtensionsConfig :: LuaError e => Peeker e ExtensionsConfig +peekExtensionsConfig idx = do + exts <- peekKeyValuePairs peekExtension peekBool idx + return $ ExtensionsConfig + { extsDefault = extensionsFromList . map fst $ filter snd exts + , extsSupported = extensionsFromList . map fst $ exts + } diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/ReaderOptions.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/ReaderOptions.hs index 0d23e0fb7..8a02a6d7e 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/ReaderOptions.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/ReaderOptions.hs @@ -22,7 +22,7 @@ module Text.Pandoc.Lua.Marshal.ReaderOptions import Data.Default (def) import HsLua as Lua -import Text.Pandoc.Lua.Marshal.Extensions (peekExtensions, pushExtensions) +import Text.Pandoc.Lua.Marshal.Format (peekExtensions, pushExtensions) import Text.Pandoc.Lua.Marshal.List (pushPandocList) import Text.Pandoc.Options (ReaderOptions (..)) diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/WriterOptions.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/WriterOptions.hs index bbd878907..a96c3d4b8 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/WriterOptions.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Marshal/WriterOptions.hs @@ -21,7 +21,7 @@ module Text.Pandoc.Lua.Marshal.WriterOptions import Control.Applicative (optional) import Data.Default (def) import HsLua as Lua -import Text.Pandoc.Lua.Marshal.Extensions (peekExtensions, pushExtensions) +import Text.Pandoc.Lua.Marshal.Format (peekExtensions, pushExtensions) import Text.Pandoc.Lua.Marshal.List (pushPandocList) import Text.Pandoc.Lua.Marshal.Template (peekTemplate, pushTemplate) import Text.Pandoc.Options (WriterOptions (..)) diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Format.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Format.hs index 7eb66b3ca..d9d413e09 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Format.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Format.hs @@ -13,9 +13,8 @@ module Text.Pandoc.Lua.Module.Format import HsLua import Text.Pandoc.Error (PandocError) -import Text.Pandoc.Extensions - ( getAllExtensions, getDefaultExtensions ) -import Text.Pandoc.Lua.Marshal.Extensions (pushExtensions) +import Text.Pandoc.Extensions (getAllExtensions, getDefaultExtensions) +import Text.Pandoc.Lua.Marshal.Format (pushExtensions) import Text.Pandoc.Lua.PandocLua () import qualified Data.Text as T diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Writer.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Writer.hs index f2d75b905..a9a044fe6 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Writer.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Writer.hs @@ -1,5 +1,6 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} {- | Module : Text.Pandoc.Lua.Writer @@ -25,14 +26,16 @@ import HsLua.Core.Run (newGCManagedState, withGCManagedState) import Control.Monad.IO.Class (MonadIO) import Text.Pandoc.Class (PandocMonad, findFileWithDataFallback) import Text.Pandoc.Error (PandocError) +import Text.Pandoc.Format (ExtensionsConfig (..)) import Text.Pandoc.Lua.Global (Global (..), setGlobals) import Text.Pandoc.Lua.Init (runLuaWith) +import Text.Pandoc.Lua.Marshal.Format (peekExtensionsConfig) import Text.Pandoc.Writers (Writer (..)) import qualified Text.Pandoc.Lua.Writer.Classic as Classic -- | Convert Pandoc to custom markup. writeCustom :: (PandocMonad m, MonadIO m) - => FilePath -> m (Writer m) + => FilePath -> m (Writer m, ExtensionsConfig) writeCustom luaFile = do luaState <- liftIO newGCManagedState luaFile' <- fromMaybe luaFile <$> findFileWithDataFallback "writers" luaFile @@ -55,19 +58,23 @@ writeCustom luaFile = do let writerField = "PANDOC Writer function" + extsConf <- rawgetglobal "writer_extensions" >>= \case + TypeNil -> pure $ ExtensionsConfig mempty mempty + _ -> forcePeek $ peekExtensionsConfig top `lastly` pop 1 + rawgetglobal "Writer" >>= \case TypeNil -> rawgetglobal "ByteStringWriter" >>= \case TypeNil -> do -- Neither `Writer` nor `BinaryWriter` are defined. Try to -- use the file as a classic writer. pop 1 -- remove nil - return . TextWriter $ \opts doc -> + pure $ (,extsConf) . TextWriter $ \opts doc -> liftIO $ withGCManagedState luaState $ do Classic.runCustom @PandocError opts doc _ -> do -- Binary writer. Writer function is on top of the stack. setfield registryindex writerField - return . ByteStringWriter $ \opts doc -> + pure $ (,extsConf) . ByteStringWriter $ \opts doc -> -- Call writer with document and writer options as arguments. liftIO $ withGCManagedState luaState $ do getfield registryindex writerField @@ -78,7 +85,7 @@ writeCustom luaFile = do _ -> do -- New-type text writer. Writer function is on top of the stack. setfield registryindex writerField - return . TextWriter $ \opts doc -> + pure $ (,extsConf) . TextWriter $ \opts doc -> liftIO $ withGCManagedState luaState $ do getfield registryindex writerField push doc |
