mirror of
https://github.com/jgm/pandoc.git
synced 2026-09-29 19:05:59 +00:00
T.P.Scripting: add CustomComponents, and change...
...the ScriptingEngine fields. Instead of separate fields for custom readers and writers, we now have a single function that loads any number of "components" from a script: these may be custom readers, custom writers, templates for writers, or extension configs. (Note: it's possible to have a custom reader and a custom writer for a format together in the same file.) This is primarily motivated by the need for a smoother check for custom templates and extensions for `-D` and `--list-extensions`, but it also seems more elegant. This is a partial implementation of #8417.
This commit is contained in:
@@ -86,8 +86,7 @@ library
|
||||
, Text.Pandoc.Lua.Module.Utils
|
||||
, Text.Pandoc.Lua.Orphans
|
||||
, Text.Pandoc.Lua.PandocLua
|
||||
, Text.Pandoc.Lua.Reader
|
||||
, Text.Pandoc.Lua.Writer
|
||||
, Text.Pandoc.Lua.Custom
|
||||
, Text.Pandoc.Lua.Writer.Classic
|
||||
, Text.Pandoc.Lua.Writer.Scaffolding
|
||||
|
||||
|
||||
@@ -30,8 +30,7 @@ import Text.Pandoc.Error (PandocError)
|
||||
import Text.Pandoc.Lua.Filter (applyFilter)
|
||||
import Text.Pandoc.Lua.Global (Global (..), setGlobals)
|
||||
import Text.Pandoc.Lua.Init (runLua, runLuaNoEnv)
|
||||
import Text.Pandoc.Lua.Reader (readCustom)
|
||||
import Text.Pandoc.Lua.Writer (writeCustom)
|
||||
import Text.Pandoc.Lua.Custom (loadCustom)
|
||||
import Text.Pandoc.Lua.Orphans ()
|
||||
import Text.Pandoc.Scripting (ScriptingEngine (..))
|
||||
import qualified Text.Pandoc.UTF8 as UTF8
|
||||
@@ -46,6 +45,5 @@ getEngine = do
|
||||
pure $ ScriptingEngine
|
||||
{ engineName = maybe "Lua (unknown version)" UTF8.toText versionName
|
||||
, engineApplyFilter = applyFilter
|
||||
, engineReadCustom = readCustom
|
||||
, engineWriteCustom = writeCustom
|
||||
, engineLoadCustom = loadCustom
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), Environment (..),
|
||||
applyFilters)
|
||||
import qualified Text.Pandoc.Format as Format
|
||||
import Text.Pandoc.PDF (makePDF)
|
||||
import Text.Pandoc.Scripting (ScriptingEngine (..))
|
||||
import Text.Pandoc.Scripting (ScriptingEngine (..), CustomComponents(..))
|
||||
import Text.Pandoc.SelfContained (makeSelfContained)
|
||||
import Text.Pandoc.Shared (eastAsianLineBreakFilter,
|
||||
headerShift, filterIpynbOutput, tshow)
|
||||
@@ -168,8 +168,13 @@ convertWithOpts' scriptingEngine istty datadir opts = do
|
||||
if ".lua" `T.isSuffixOf` readerName
|
||||
then do
|
||||
let scriptPath = T.unpack readerNameBase
|
||||
(r, extsConf) <- engineReadCustom scriptingEngine scriptPath
|
||||
rexts <- Format.applyExtensionsDiff extsConf flvrd
|
||||
components <- engineLoadCustom scriptingEngine scriptPath
|
||||
r <- case customReader components of
|
||||
Nothing -> throwError $ PandocAppError $
|
||||
readerName <> " does not contain a custom reader"
|
||||
Just r -> return r
|
||||
let extsConf = fromMaybe mempty (customExtensions components)
|
||||
rexts <- Format.applyExtensionsDiff extsConf flvrd
|
||||
return (r, rexts)
|
||||
else if optSandbox opts
|
||||
then case runPure (getReader flvrd) of
|
||||
|
||||
@@ -41,7 +41,8 @@ import Text.Pandoc.App.Opt (Opt (..))
|
||||
import Text.Pandoc.App.CommandLineOptions (engines, setVariable)
|
||||
import qualified Text.Pandoc.Format as Format
|
||||
import Text.Pandoc.Highlighting (lookupHighlightingStyle)
|
||||
import Text.Pandoc.Scripting (ScriptingEngine (engineWriteCustom))
|
||||
import Text.Pandoc.Scripting (ScriptingEngine (engineLoadCustom),
|
||||
CustomComponents(..))
|
||||
import qualified Text.Pandoc.UTF8 as UTF8
|
||||
|
||||
readUtf8File :: PandocMonad m => FilePath -> m T.Text
|
||||
@@ -127,12 +128,18 @@ optToOutputSettings scriptingEngine opts = do
|
||||
if "lua" `T.isSuffixOf` format
|
||||
then do
|
||||
let path = T.unpack format
|
||||
(w, extsConf, mt) <- engineWriteCustom scriptingEngine path
|
||||
components <- engineLoadCustom scriptingEngine path
|
||||
w <- case customWriter components of
|
||||
Nothing -> throwError $ PandocAppError $
|
||||
format <> " does not contain a custom writer"
|
||||
Just w -> return w
|
||||
let extsConf = fromMaybe mempty $ customExtensions components
|
||||
wexts <- Format.applyExtensionsDiff extsConf flvrd
|
||||
templ <- processCustomTemplate $ case mt of
|
||||
Nothing -> throwError $ PandocNoTemplateError format
|
||||
Just t -> (runWithDefaultPartials $ compileTemplate path t) >>=
|
||||
templateOrThrow
|
||||
templ <- processCustomTemplate $
|
||||
case customTemplate components of
|
||||
Nothing -> throwError $ PandocNoTemplateError format
|
||||
Just t -> (runWithDefaultPartials $ compileTemplate path t) >>=
|
||||
templateOrThrow
|
||||
return (w, wexts, templ)
|
||||
else do
|
||||
tmpl <- processCustomTemplate (compileDefaultTemplate format)
|
||||
|
||||
@@ -11,6 +11,7 @@ Central data structure for scripting engines.
|
||||
-}
|
||||
module Text.Pandoc.Scripting
|
||||
( ScriptingEngine (..)
|
||||
, CustomComponents(..)
|
||||
, noEngine
|
||||
)
|
||||
where
|
||||
@@ -26,6 +27,18 @@ import Text.Pandoc.Format (ExtensionsConfig)
|
||||
import Text.Pandoc.Readers (Reader)
|
||||
import Text.Pandoc.Writers (Writer)
|
||||
|
||||
-- | A component of a custom reader/writer: a custom reader,
|
||||
-- a custom writer, a template for a custom writer, or a specification
|
||||
-- of the extensions used by a script and their default values.
|
||||
-- Note that a single script can contain all of these.
|
||||
data CustomComponents m =
|
||||
CustomComponents
|
||||
{ customReader :: Maybe (Reader m)
|
||||
, customWriter :: Maybe (Writer m)
|
||||
, customTemplate :: Maybe Text
|
||||
, customExtensions :: Maybe ExtensionsConfig
|
||||
}
|
||||
|
||||
-- | Structure to define a scripting engine.
|
||||
data ScriptingEngine = ScriptingEngine
|
||||
{ engineName :: Text -- ^ Name of the engine.
|
||||
@@ -35,14 +48,9 @@ data ScriptingEngine = ScriptingEngine
|
||||
-> Pandoc -> m Pandoc
|
||||
-- ^ Use the scripting engine to run a filter.
|
||||
|
||||
, engineReadCustom :: forall m. (PandocMonad m, MonadIO m)
|
||||
=> FilePath -> m (Reader m, ExtensionsConfig)
|
||||
-- ^ Function to parse input into a 'Pandoc' document.
|
||||
|
||||
, engineWriteCustom :: forall m. (PandocMonad m, MonadIO m)
|
||||
=> FilePath
|
||||
-> m (Writer m, ExtensionsConfig, Maybe Text)
|
||||
-- ^ Invoke the given script file to convert to any custom format.
|
||||
, engineLoadCustom :: forall m. (PandocMonad m, MonadIO m)
|
||||
=> FilePath -> m (CustomComponents m)
|
||||
-- ^ Function to load a custom reader/writer from a script.
|
||||
}
|
||||
|
||||
noEngine :: ScriptingEngine
|
||||
@@ -50,8 +58,6 @@ noEngine = ScriptingEngine
|
||||
{ engineName = "none"
|
||||
, engineApplyFilter = \_env _args _fp _doc ->
|
||||
throwError PandocNoScriptingEngine
|
||||
, engineReadCustom = \_fp ->
|
||||
throwError PandocNoScriptingEngine
|
||||
, engineWriteCustom = \_fp ->
|
||||
, engineLoadCustom = \_fp ->
|
||||
throwError PandocNoScriptingEngine
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user