Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-pandoc-lua-engine for 
openSUSE:Factory checked in at 2026-06-10 16:04:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-pandoc-lua-engine (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-pandoc-lua-engine.new.2375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-pandoc-lua-engine"

Wed Jun 10 16:04:35 2026 rev:22 rq:1358418 version:0.5.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/ghc-pandoc-lua-engine/ghc-pandoc-lua-engine.changes  
    2025-12-05 16:56:29.988041674 +0100
+++ 
/work/SRC/openSUSE:Factory/.ghc-pandoc-lua-engine.new.2375/ghc-pandoc-lua-engine.changes
    2026-06-10 16:07:45.061014048 +0200
@@ -1,0 +2,6 @@
+Thu Jun  4 15:00:07 UTC 2026 - Peter Simons <[email protected]>
+
+- Update pandoc-lua-engine to version 0.5.3.
+  Upstream does not provide a change log file.
+
+-------------------------------------------------------------------

Old:
----
  pandoc-lua-engine-0.5.0.2.tar.gz

New:
----
  pandoc-lua-engine-0.5.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-pandoc-lua-engine.spec ++++++
--- /var/tmp/diff_new_pack.rqkKSE/_old  2026-06-10 16:07:46.797085991 +0200
+++ /var/tmp/diff_new_pack.rqkKSE/_new  2026-06-10 16:07:46.801086157 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-pandoc-lua-engine
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
 %global pkgver %{pkg_name}-%{version}
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.5.0.2
+Version:        0.5.3
 Release:        0
 Summary:        Lua engine to power custom pandoc conversions
 License:        GPL-2.0-or-later

++++++ pandoc-lua-engine-0.5.0.2.tar.gz -> pandoc-lua-engine-0.5.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pandoc-lua-engine-0.5.0.2/pandoc-lua-engine.cabal 
new/pandoc-lua-engine-0.5.3/pandoc-lua-engine.cabal
--- old/pandoc-lua-engine-0.5.0.2/pandoc-lua-engine.cabal       2001-09-09 
03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/pandoc-lua-engine.cabal 2001-09-09 
03:46:40.000000000 +0200
@@ -1,6 +1,6 @@
 cabal-version:       2.4
 name:                pandoc-lua-engine
-version:             0.5.0.2
+version:             0.5.3
 build-type:          Simple
 license:             GPL-2.0-or-later
 license-file:        COPYING.md
@@ -10,12 +10,6 @@
 bug-reports:         https://github.com/jgm/pandoc/issues
 homepage:            https://pandoc.org
 category:            Text
-tested-with:         GHC == 8.6.5
-                   , GHC == 8.8.4
-                   , GHC == 8.10.7
-                   , GHC == 9.0.2
-                   , GHC == 9.2.5
-                   , GHC == 9.4.4
 synopsis:            Lua engine to power custom pandoc conversions
 description:         This package provides a pandoc scripting engine based on
                      Lua.
@@ -44,6 +38,10 @@
   location:            https://github.com/jgm/pandoc.git
   subdir:              pandoc-lua-engine
 
+flag repl
+  Description:   Include pandoc Lua repl.
+  Default:       True
+
 common common-options
   default-language:    Haskell2010
   build-depends:       base              >= 4.12 && < 5
@@ -69,6 +67,7 @@
   hs-source-dirs:      src
   exposed-modules:     Text.Pandoc.Lua
   other-modules:       Text.Pandoc.Lua.Custom
+                     , Text.Pandoc.Lua.Documentation
                      , Text.Pandoc.Lua.Engine
                      , Text.Pandoc.Lua.Filter
                      , Text.Pandoc.Lua.Global
@@ -110,29 +109,31 @@
 
   build-depends:       aeson
                      , bytestring            >= 0.9     && < 0.13
-                     , crypton               >= 0.30    && < 1.1
-                     , citeproc              >= 0.8     && < 0.13
+                     , crypton               >= 0.30    && < 1.2
+                     , citeproc              >= 0.8     && < 0.14
                      , containers            >= 0.6.0.1 && < 0.9
                      , data-default          >= 0.4     && < 0.9
                      , doclayout             >= 0.5     && < 0.6
                      , doctemplates          >= 0.11    && < 0.12
                      , exceptions            >= 0.8     && < 0.11
-                     , hslua                 >= 2.3     && < 2.5
+                     , hslua                 >= 2.5     && < 2.6
                      , hslua-module-doclayout>= 1.2     && < 1.3
-                     , hslua-module-path     >= 1.1     && < 1.2
-                     , hslua-module-system   >= 1.2.3   && < 1.3
-                     , hslua-module-text     >= 1.1     && < 1.2
-                     , hslua-module-version  >= 1.1     && < 1.2
-                     , hslua-module-zip      >= 1.1.3   && < 1.2
-                     , hslua-repl            >= 0.1.1   && < 0.2
+                     , hslua-module-path     >= 1.2     && < 1.3
+                     , hslua-module-system   >= 1.3     && < 1.4
+                     , hslua-module-text     >= 1.2     && < 1.3
+                     , hslua-module-version  >= 1.2     && < 1.3
+                     , hslua-module-zip      >= 1.1.5   && < 1.3
                      , lpeg                  >= 1.1     && < 1.2
                      , mtl                   >= 2.2     && < 2.4
-                     , pandoc                >= 3.8     && < 3.9
+                     , pandoc                >= 3.10    && < 3.11
                      , pandoc-lua-marshal    >= 0.3     && < 0.4
                      , pandoc-types          >= 1.22    && < 1.24
                      , parsec                >= 3.1     && < 3.2
                      , text                  >= 1.1.1   && < 2.2
 
+  if flag(repl)
+     build-depends:    hslua-repl            >= 0.1.1   && < 0.2
+     cpp-options:      -DINCLUDE_REPL
 
 test-suite test-pandoc-lua-engine
   import:              common-options
@@ -145,7 +146,7 @@
                      , data-default
                      , exceptions            >= 0.8     && < 0.11
                      , filepath
-                     , hslua                 >= 2.3     && < 2.5
+                     , hslua                 >= 2.5     && < 2.6
                      , pandoc
                      , pandoc-types          >= 1.22    && < 1.24
                      , tasty
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Documentation.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Documentation.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Documentation.hs  
1970-01-01 01:00:00.000000000 +0100
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Documentation.hs    
2001-09-09 03:46:40.000000000 +0200
@@ -0,0 +1,187 @@
+{-# LANGUAGE LambdaCase        #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RankNTypes        #-}
+{- |
+   Module      : Text.Pandoc.Lua.Documentation
+   Copyright   : Copyright © 2026 Albert Krewinkel
+   License     : GPL-2.0-or-later
+   Maintainer  : Albert Krewinkel <[email protected]>
+
+Render Lua documentation
+-}
+module Text.Pandoc.Lua.Documentation
+  ( renderDocumentation
+  ) where
+
+import Data.Default (def)
+import Data.List (intersperse)
+import Data.Sequence (Seq ((:|>)))
+import Data.Version (showVersion)
+import HsLua as Lua
+import Text.Pandoc.Class (runPure)
+import Text.Pandoc.Definition (Pandoc (Pandoc))
+import Text.Pandoc.Extensions (extensionsFromList, Extension (..))
+import Text.Pandoc.Options (ReaderOptions (readerExtensions))
+import Text.Pandoc.Readers (readCommonMark)
+import Text.Pandoc.Shared (compactify)
+import Text.Pandoc.Walk (walk)
+
+import qualified Data.Text as T
+import qualified Text.Pandoc.Builder as B
+import qualified Text.Pandoc.UTF8 as UTF8
+
+-- | Render the documentation object as pandoc Blocks
+renderDocumentation :: DocumentationObject -> B.Blocks
+renderDocumentation = \case
+  DocObjectFunction fn -> renderFunctionDoc Nothing fn
+  DocObjectModule mdl  -> renderModuleDoc mdl
+  DocObjectType tp     -> renderTypeDoc Nothing tp
+
+renderTypeDoc :: Maybe T.Text -> TypeDoc -> B.Blocks
+renderTypeDoc mbmodname td = mconcat
+  [ B.headerWith (ident, [], []) 1 (B.str $ typeDocName td)
+  , parseCommonMark $ typeDocDescription td
+  , if null $ typeDocMethods td
+    then mempty
+    else
+      B.header 2 "Methods" <>
+      (shiftHeadings 2 . mconcat . map (renderFunctionDoc Nothing) $
+       typeDocMethods td)
+  ]
+ where
+  ident = case mbmodname of
+    Just modname  -> mconcat [ "type-", modname, ".", typeDocName td ]
+    Nothing       -> mconcat [ "type-", typeDocName td ]
+
+-- Shift headings
+shiftHeadings :: Int -> B.Blocks -> B.Blocks
+shiftHeadings incr blks = flip walk blks $ \case
+  B.Header level attr inner -> B.Header (level + incr) attr inner
+  x -> x
+
+renderModuleDoc :: ModuleDoc -> B.Blocks
+renderModuleDoc moddoc =
+  let modname = moduleDocName moddoc
+  in mconcat
+  [ B.headerWith ("module-" <> modname, [], []) 1
+      (B.str $ "Module " <> modname)
+  , parseCommonMark (moduleDocDescription moddoc)
+  , if null (moduleDocFields moddoc)
+    then mempty
+    else
+      let ident = modname <> "-fields"
+      in B.headerWith (ident, [], []) 2 (B.str "Fields") <>
+         shiftHeadings 0 (mconcat (map (renderFieldDoc modname)
+                                   (moduleDocFields moddoc)))
+  , if null (moduleDocFunctions moddoc)
+    then mempty
+    else
+      let ident = modname <> "-functions"
+      in B.headerWith (ident, [], []) 2 (B.str "Functions") <>
+         (shiftHeadings 2 . mconcat . map (renderFunctionDoc $ Just modname) $
+          moduleDocFunctions moddoc)
+  , if null (moduleDocTypes moddoc)
+    then mempty
+    else
+      let ident = modname <> "-types"
+      in B.headerWith (ident, [], []) 2 (B.str "Types") <>
+         (shiftHeadings 2 . mconcat . map (renderTypeDoc $ Just modname) .
+          reverse $ moduleDocTypes moddoc)
+  ]
+
+parseCommonMark :: T.Text -> B.Blocks
+parseCommonMark txt =
+  let exts = extensionsFromList
+        [ Ext_wikilinks_title_after_pipe
+        , Ext_smart
+        ]
+      result = runPure $ do
+        Pandoc _ blks <- readCommonMark (def {readerExtensions = exts}) txt
+        return $ B.fromList blks
+  in either mempty id result
+
+appendInlines :: B.Blocks -> B.Inlines -> B.Blocks
+appendInlines blks inlns = case B.unMany blks of
+  front :|> (B.Para xs) -> B.Many front <> B.para (addTo xs)
+  front :|> (B.Plain xs) -> B.Many front <> B.plain (addTo xs)
+  _ -> blks <> B.para inlns
+ where addTo xs = B.fromList xs <> B.space <> inlns
+
+appendType :: B.Blocks -> TypeSpec -> B.Blocks
+appendType blks typespec =
+  appendInlines blks (B.str "(" <> typeToInlines typespec <> B.str ")")
+
+typeToInlines :: TypeSpec -> B.Inlines
+typeToInlines = \case
+  bt@BasicType{}   -> builtin $ tystr bt
+  NamedType "integer" -> builtin "integer"
+  NamedType name   -> B.linkWith ("", ["documented-type"], [])
+                        ("#" <> n2t name) mempty $ B.str (n2t name)
+  SeqType itemtype -> "{" <> typeToInlines itemtype <> ",...}"
+  SumType summands -> mconcat . intersperse (B.str "|") $ map typeToInlines 
summands
+  AnyType          -> "any"
+  x                -> tystr x
+ where
+  tystr = B.str . T.pack . typeSpecToString
+  n2t = UTF8.toText . fromName
+  builtin = B.spanWith ("", ["builtin-lua-type"], [])
+
+renderFunctionDoc :: Maybe T.Text -> FunctionDoc -> B.Blocks
+renderFunctionDoc mbmodule fndoc =
+  let name = case mbmodule of
+        Just _   ->  T.takeWhileEnd (/= '.') $ funDocName fndoc
+        Nothing  -> funDocName fndoc
+      ident = funDocName fndoc
+      level = 1
+      argsString = argslist (funDocParameters fndoc)
+      paramToDefItem p = ( B.code $ parameterName p
+                         , compactify
+                           [ appendType
+                               (parseCommonMark $ parameterDescription p)
+                               (parameterType p)
+                           ]
+                         )
+      paramlist = B.definitionList . map paramToDefItem $
+                  funDocParameters fndoc
+  in mconcat
+     [ B.headerWith (ident, [], []) level (B.str name)
+     , B.plain (B.code $ name <> " (" <> argsString <> ")")
+     , parseCommonMark (funDocDescription fndoc)
+     , if null (funDocParameters fndoc)
+       then mempty
+       else B.para "Parameters:" <> paramlist
+     , if funDocResults fndoc == ResultsDocList []
+       then mempty
+       else B.para "Returns:" <> renderResults (funDocResults fndoc)
+     , case funDocSince fndoc of
+         Nothing -> mempty
+         Just version ->
+           B.para $ B.emph $ "Since: " <> (B.str . T.pack $ showVersion 
version)
+     ]
+
+renderResults :: ResultsDoc -> B.Blocks
+renderResults (ResultsDocMult descr) = parseCommonMark descr
+renderResults (ResultsDocList rvd) = B.bulletList $ map renderResultVal rvd
+ where
+   renderResultVal (ResultValueDoc typespec descr) =
+     parseCommonMark descr `appendType` typespec
+
+argslist :: [ParameterDoc] -> T.Text
+argslist params =
+  -- Expect optional values to come after required values.
+  let (required, optional') = break parameterIsOptional params
+      reqs = map parameterName required
+      opts = map parameterName optional'
+  in if null opts
+     then T.intercalate ", " reqs
+     else T.intercalate ", " reqs <>
+          (if null required then "[" else "[, ") <>
+          T.intercalate "[, " opts <> T.replicate (length opts) "]"
+
+renderFieldDoc :: T.Text -> FieldDoc -> B.Blocks
+renderFieldDoc _modname fd =
+  B.headerWith (ident, [], []) 3 (B.str name) <>
+  appendType (parseCommonMark $ fieldDocDescription fd) (fieldDocType fd)
+ where
+  ident = fieldDocName fd
+  name = T.takeWhileEnd (/= '.') $ fieldDocName fd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Init.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Init.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Init.hs   2001-09-09 
03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Init.hs     2001-09-09 
03:46:40.000000000 +0200
@@ -3,7 +3,7 @@
 {-# LANGUAGE RankNTypes        #-}
 {- |
    Module      : Text.Pandoc.Lua.Init
-   Copyright   : © 2017-2024 Albert Krewinkel
+   Copyright   : © 2017-2026 Albert Krewinkel
    License     : GPL-2.0-or-later
    Maintainer  : Albert Krewinkel <[email protected]>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Marshal/CommonState.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Marshal/CommonState.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Marshal/CommonState.hs    
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Marshal/CommonState.hs      
2001-09-09 03:46:40.000000000 +0200
@@ -26,8 +26,10 @@
 typeCommonState :: LuaError e => DocumentedType e CommonState
 typeCommonState = deftype "CommonState" [] []
 
+-- | Retrieves the common state from Lua
 peekCommonState :: LuaError e => Peeker e CommonState
 peekCommonState = peekUD typeCommonState
 
+-- | Pushes the common pandoc state to the Lua stack.
 pushCommonState :: LuaError e => Pusher e CommonState
 pushCommonState = pushUD typeCommonState
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Marshal/LogMessage.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Marshal/LogMessage.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Marshal/LogMessage.hs     
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Marshal/LogMessage.hs       
2001-09-09 03:46:40.000000000 +0200
@@ -13,6 +13,8 @@
   , typeLogMessage
   ) where
 
+import Control.Applicative (optional)
+import Data.Maybe (fromMaybe)
 import HsLua
 import Text.Pandoc.Logging (LogMessage, showLogMessage)
 import qualified Data.Aeson as Aeson
@@ -24,6 +26,11 @@
       ### liftPure showLogMessage
       <#> udparam typeLogMessage "msg" "object"
       =#> functionResult pushText "string" "stringified log message"
+  , operation Eq $ lambda
+      ### liftPure2 (\a b -> fromMaybe False ((==) <$> a <*> b))
+      <#> parameter (optional . peekLogMessage) "a" "LogMessage" ""
+      <#> parameter (optional . peekLogMessage) "b" "LogMessage" ""
+      =#> functionResult pushBool "boolean" "whether the two are equal"
   , operation (CustomOperation "__tojson") $ lambda
       ### liftPure Aeson.encode
       <#> udparam typeLogMessage "msg" "object"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Marshal/Sources.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Marshal/Sources.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Marshal/Sources.hs        
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Marshal/Sources.hs  
2001-09-09 03:46:40.000000000 +0200
@@ -1,17 +1,17 @@
 {-# LANGUAGE LambdaCase           #-}
 {-# LANGUAGE OverloadedStrings    #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE TupleSections        #-}
 {- |
 Module      : Text.Pandoc.Lua.Marshaling.Sources
-Copyright   : © 2021-2024 Albert Krewinkel
-License     : GNU GPL, version 2 or above
-Maintainer  : Albert Krewinkel <[email protected]>
+Copyright   : © 2021-2026 Albert Krewinkel <[email protected]>
+License     : GPL-2.0-or-later
 
 Marshal 'Sources'.
 -}
 module Text.Pandoc.Lua.Marshal.Sources
   ( peekSources
   , pushSources
+  , typeSource
   ) where
 
 import Control.Monad ((<$!>))
@@ -37,17 +37,31 @@
 -- | Retrieves sources from the stack.
 peekSources :: LuaError e => Peeker e Sources
 peekSources idx = liftLua (ltype idx) >>= \case
-  TypeString -> toSources <$!> peekText idx
-  TypeTable  -> Sources <$!> peekList (peekUD typeSource) idx
-  _          -> Sources . (:[]) <$!> peekUD typeSource idx
+  TypeTable  -> mconcat <$!> peekList peekSourcesSingleton idx
+  _          -> peekSourcesSingleton idx
+
+-- | Retrieves a Sources singleton, i.e., a list with exactly one item.
+peekSourcesSingleton :: LuaError e => Peeker e Sources
+peekSourcesSingleton = choice
+  [ fmap toSources . peekText
+  , fmap (Sources . (:[])) . peekUD typeSource
+  , fmap (toSources . (:[])) . peekPair peekString peekText
+  , fmap (toSources . (:[])) .
+    (\idx -> (,)
+      <$> peekFieldRaw peekString "name" idx
+      <*> peekFieldRaw peekText "text" idx)
+  ]
+
+-- | A @Sources@ item.
+type Source = (SourcePos, Text)
 
 -- | Source object type.
-typeSource :: LuaError e => DocumentedType e (SourcePos, Text)
+typeSource :: LuaError e => DocumentedType e Source
 typeSource = deftype "Source"
   [ operation Tostring $ lambda
     ### liftPure snd
     <#> udparam typeSource "srcs" "Source to print in native format"
-    =#> functionResult pushText "string" "Haskell representation"
+    =#> functionResult pushText "string" "source contents"
   ]
   [ readonly "name" "source name"
       (pushString, sourceName . fst)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/CLI.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/CLI.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/CLI.hs     
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/CLI.hs       
2001-09-09 03:46:40.000000000 +0200
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {- |
@@ -15,28 +16,27 @@
 import Control.Applicative ((<|>))
 import Data.Version (makeVersion)
 import HsLua
-import HsLua.REPL (defaultConfig, replWithEnv, setup)
 import Text.Pandoc.App (defaultOpts, options, parseOptionsFromArgs)
 import Text.Pandoc.Error (PandocError)
 import Text.Pandoc.Lua.PandocLua ()
 import qualified Data.Text as T
+#ifdef INCLUDE_REPL
+import HsLua.REPL (defaultConfig, replWithEnv, setup)
+#endif
 
 -- | Push the pandoc.types module on the Lua stack.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.cli"
-  , moduleDescription =
+documentedModule = defmodule "pandoc.cli"
+  `withDescription`
       "Command line options and argument parsing."
-  , moduleFields =
-      [ Field
-        { fieldName = "default_options"
-        , fieldType = "table"
-        , fieldDescription = "Default CLI options, using a JSON-like " <>
-          "representation."
-        , fieldPushValue = pushViaJSON defaultOpts
-        }
+  `withFields`
+      [ deffield "default_options"
+        `withType` "table"
+        `withDescription`
+          "Default CLI options, using a JSON-like representation."
+        `withValue` pushViaJSON defaultOpts
       ]
-  , moduleFunctions =
+  `withFunctions`
       [ defun "parse_options"
         ### parseOptions
         <#> parameter peekArgs "{string,...}" "args"
@@ -49,12 +49,10 @@
            , "scripts, taking the list of arguments from the global `arg`."
            ]
         `since` makeVersion [3, 0]
-
+#ifdef INCLUDE_REPL
       , repl `since` makeVersion [3, 1, 2]
+#endif
       ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
  where
   peekArgs idx =
     (,)
@@ -67,6 +65,7 @@
       Left e     -> failLua $ "Cannot process info option: " ++ show e
       Right opts -> pure opts
 
+#ifdef INCLUDE_REPL
 -- | Starts a REPL.
 repl :: DocumentedFunction PandocError
 repl = defun "repl"
@@ -123,3 +122,4 @@
             copyval
     copyval
     pop 1  -- global table
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Format.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Format.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Format.hs  
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Format.hs    
2001-09-09 03:46:40.000000000 +0200
@@ -23,16 +23,11 @@
 
 -- | The "pandoc.format" module.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.format"
-  , moduleDescription = T.unlines
+documentedModule = defmodule "pandoc.format"
+  `withDescription` T.unlines
     [ "Information about the formats supported by pandoc."
     ]
-  , moduleFields = []
-  , moduleOperations = []
-  , moduleFunctions = functions
-  , moduleTypeInitializers = []
-  }
+  `withFunctions` functions
 
 -- | Extension module functions.
 functions :: [DocumentedFunction PandocError]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Image.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Image.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Image.hs   
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Image.hs     
2001-09-09 03:46:40.000000000 +0200
@@ -34,22 +34,9 @@
 
 -- | The @pandoc.image@ module specification.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.image"
-  , moduleDescription = "Basic image querying functions."
-  , moduleFields = fields
-  , moduleFunctions = functions
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
-
---
--- Fields
---
-
--- | Exported fields.
-fields :: LuaError e => [Field e]
-fields = []
+documentedModule = defmodule "pandoc.image"
+  `withDescription` "Basic image querying functions."
+  `withFunctions` functions
 
 --
 -- Functions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/JSON.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/JSON.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/JSON.hs    
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/JSON.hs      
2001-09-09 03:46:40.000000000 +0200
@@ -35,15 +35,11 @@
 
 -- | The @aeson@ module specification.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.json"
-  , moduleDescription = "JSON module to work with JSON; " <>
-                        "based on the Aeson Haskell package."
-  , moduleFields = fields
-  , moduleFunctions = functions
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
+documentedModule = defmodule "pandoc.json"
+  `withDescription`
+    "JSON module to work with JSON; based on the Aeson Haskell package."
+  `withFields` fields
+  `withFunctions` functions
 
 --
 -- Fields
@@ -57,12 +53,10 @@
 
 -- | The value used to represent the JSON @null@.
 null :: LuaError e => Field e
-null = Field
-  { fieldName = "null"
-  , fieldType = "light userdata"
-  , fieldDescription = "Value used to represent the `null` JSON value."
-  , fieldPushValue = pushValue Aeson.Null
-  }
+null = deffield "null"
+  `withType` "light userdata"
+  `withDescription` "Value used to represent the `null` JSON value."
+  `withValue` pushValue Aeson.Null
 
 --
 -- Functions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Log.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Log.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Log.hs     
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Log.hs       
2001-09-09 03:46:40.000000000 +0200
@@ -26,12 +26,11 @@
 
 -- | Push the pandoc.log module on the Lua stack.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.log"
-  , moduleDescription =
+documentedModule = defmodule "pandoc.log"
+  `withDescription`
       "Access to pandoc's logging system."
-  , moduleFields = []
-  , moduleFunctions =
+  `withFields` []
+  `withFunctions`
       [ defun "info"
         ### (\msg -> do
                 -- reporting levels:
@@ -78,9 +77,6 @@
            ]
         `since` makeVersion [3, 2]
       ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
 
 -- | Calls the function given as the first argument, but suppresses logging.
 -- Returns the list of generated log messages as the first result, and the 
other
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/MediaBag.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/MediaBag.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/MediaBag.hs        
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/MediaBag.hs  
2001-09-09 03:46:40.000000000 +0200
@@ -37,9 +37,8 @@
 -- MediaBag submodule
 --
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.mediabag"
-  , moduleDescription = T.unlines
+documentedModule = Lua.defmodule "pandoc.mediabag"
+  `Lua.withDescription` T.unlines
     [ "The `pandoc.mediabag` module allows accessing pandoc's media"
     , "storage. The \"media bag\" is used when pandoc is called with the"
     , "`--extract-media` or (for HTML only) `--embed-resources` option."
@@ -50,8 +49,7 @@
     , ""
     , "    local mb = require 'pandoc.mediabag'"
     ]
-  , moduleFields = []
-  , moduleFunctions =
+  `Lua.withFunctions`
       [ delete  `since` makeVersion [2,7,3]
       , empty   `since` makeVersion [2,7,3]
       , fetch   `since` makeVersion [2,0]
@@ -63,9 +61,6 @@
       , make_data_uri `since` makeVersion [3,7,1]
       , write   `since` makeVersion [3,0]
       ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
 
 -- | Delete a single item from the media bag.
 delete :: DocumentedFunction PandocError
@@ -109,8 +104,9 @@
           setMediaBag $ MB.insertMedia fp mmime contents mb
           return (Lua.NumResults 0))
   <#> stringParam "filepath" "filename and path relative to the output folder."
-  <#> opt (textParam "mimetype"
-           "the item's MIME type; omit if unknown or unavailable.")
+  <#> parameter (Lua.peekNilOr Lua.peekText) "string|nil" "mimetype"
+        "the item's MIME type; use `nil` if the MIME type is\
+        \ unknown or unavailable."
   <#> parameter Lua.peekLazyByteString "string" "contents"
         "the binary contents of the file."
   =#> []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Pandoc.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Pandoc.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Pandoc.hs  
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Pandoc.hs    
2001-09-09 03:46:40.000000000 +0200
@@ -30,6 +30,8 @@
 import System.Exit (ExitCode (..))
 import Text.Pandoc.Class ( PandocMonad, FileInfo (..), FileTree
                          , addToFileTree, getCurrentTime
+                         , getRequestHeaders, getResourcePath, getUserDataDir
+                         , setRequestHeaders, setResourcePath, setUserDataDir
                          , insertInFileTree, sandboxWithFileTree
                          )
 import Text.Pandoc.Definition
@@ -57,22 +59,19 @@
 import qualified HsLua as Lua
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.ByteString.Lazy.Char8 as BSL
-import qualified Data.Set as Set
 import qualified Data.Text as T
 import qualified Text.Pandoc.UTF8 as UTF8
 
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc"
-  , moduleDescription = T.unlines
+documentedModule = defmodule "pandoc"
+  `withDescription` T.unlines
     [ "Fields and functions for pandoc scripts; includes constructors for"
     , "document tree elements, functions to parse text in a given"
     , "format, and functions to filter and modify a subtree."
     ]
-  , moduleFields = readersField : writersField :
+  `withFields` readersField : writersField :
                    stringConstants ++ [inlineField, blockField]
-  , moduleOperations = []
-  , moduleFunctions = mconcat
+  `withFunctions` mconcat
       [ [mkPandoc, mkMeta]
       , metaValueConstructors
       , blockConstructors
@@ -82,60 +81,57 @@
       , otherConstructors
       , functions
       ]
-  , moduleTypeInitializers =
-    [ initType typePandoc
-    , initType typeBlock
-    , initType typeInline
-    ]
-  }
+  `associateType` typePandoc
+  `associateType` typeBlock
+  `associateType` typeInline
 
 -- | Set of input formats accepted by @read@.
 readersField :: Field PandocError
-readersField = Field
-  { fieldName = "readers"
-  , fieldType = "table"
-  , fieldDescription = T.unlines
+readersField = deffield "readers"
+  `withType` "table"
+  `withDescription` T.unlines
     [ "Set of formats that pandoc can parse. All keys in this table can"
     , "be used as the `format` value in `pandoc.read`."
     ]
-  , fieldPushValue = pushSet pushText $
-                     Set.fromList (map fst (readers @PandocLua))
-  }
+  `withValue` pushKeyValuePairs pushText (pushText . readerType)
+                     (readers @PandocLua)
+ where
+  readerType = \case
+    TextReader {} -> "text"
+    ByteStringReader {} -> "bytestring"
 
 -- | Set of input formats accepted by @write@.
 writersField :: Field PandocError
-writersField = Field
-  { fieldName = "writers"
-  , fieldType = "table"
-  , fieldDescription = T.unlines
+writersField = deffield "writers"
+  `withType` "table"
+  `withDescription` T.unlines
     [ "Set of formats that pandoc can generate. All keys in this table"
     , "can be used as the `format` value in `pandoc.write`."
     ]
-  , fieldPushValue = pushSet pushText $
-                     Set.fromList (map fst (writers @PandocLua))
-  }
+  `withValue` pushKeyValuePairs pushText (pushText . writerType)
+                     (writers @PandocLua)
+ where
+  writerType = \case
+    TextWriter {} -> "text"
+    ByteStringWriter {} -> "bytestring"
 
 -- | Inline table field
 inlineField :: Field PandocError
-inlineField = Field
-  { fieldName = "Inline"
-  , fieldType = "table"
-  , fieldDescription = "Inline constructors, nested under 'constructors'."
+inlineField = deffield "Inline"
+  `withType` "table"
+  `withDescription` "Inline constructors, nested under 'constructors'."
   -- the nesting happens for historical reasons and should probably be
   -- changed.
-  , fieldPushValue = pushWithConstructorsSubtable inlineConstructors
-  }
+  `withValue` pushWithConstructorsSubtable inlineConstructors
 
 -- | @Block@ module field
 blockField :: Field PandocError
-blockField = Field
-  { fieldName = "Block"
-  , fieldType = "table"
-  , fieldDescription = "Inline constructors, nested under 'constructors'."
+blockField = deffield "Block"
+  `withType` "table"
+  `withDescription` "Inline constructors, nested under 'constructors'."
   -- the nesting happens for historical reasons and should probably be
   -- changed.
-  , fieldPushValue = pushWithConstructorsSubtable blockConstructors
-  }
+  `withValue` pushWithConstructorsSubtable blockConstructors
 
 pushWithConstructorsSubtable :: [DocumentedFunction PandocError]
                              -> LuaE PandocError ()
@@ -158,6 +154,7 @@
   , mkCitation
   , mkListAttributes
   , mkRow
+  , mkTableBody
   , mkTableFoot
   , mkTableHead
   , mkSimpleTable
@@ -213,12 +210,10 @@
         , constrs (Proxy @Alignment)
         , constrs (Proxy @CitationMode)
         ]
-      toField s = Field
-        { fieldName = T.pack s
-        , fieldType = "string"
-        , fieldDescription = T.pack s
-        , fieldPushValue = pushString s
-        }
+      toField s = deffield (Name $ UTF8.fromString s)
+        `withType` "string"
+        `withDescription` T.pack s
+        `withValue` pushString s
   in map toField nullaryConstructors
 
 functions :: [DocumentedFunction PandocError]
@@ -294,6 +289,37 @@
     <#> parameter peekFilter "Filter" "lua_filter" "filter functions"
     =#> functionResult pushInline "Inline" "modified Inline"
 
+  , defun "with_state"
+    ### with_state
+    <#> parameter peekStateOptions "table" "options" "state options"
+    <#> parameter pure "function" "callback"
+          "The action to run with the given state."
+    =?> "The results of the call to *callback*."
+    #? "Runs a function with a modified pandoc state.\n\
+       \\n\
+       \The given callback is invoked after setting the pandoc state to the\
+       \ given values. The modifiable options are restored to their original\
+       \ values once the callback has returned.\n\
+       \\n\
+       \The following state variables can be controlled:\n\
+       \\n\
+       \  - `request_headers` (list of key-value tuples)\n\
+       \  - `resource_path` (list of filepaths)\n\
+       \  - `user_data_dir` (string)\n\
+       \\n\
+       \Other options are ignored, and the rest of the state is not 
modified.\n\
+       \\n\
+       \Usage:\n\
+       \\n\
+       \    local opts = {\n\
+       \      request_headers = {\n\
+       \        {'Authorization', 'Basic my-secret'}\n\
+       \      }\n\
+       \    }\n\
+       \    pandoc.with_state(opts, function ()\n\
+       \      local mime, contents = pandoc.mediabag.fetch(image_url)\n\
+       \    )\n"
+
   , defun "write"
     ### (\doc mformatspec mwriterOpts -> unPandocLua $ do
             flvrd <- maybe (parseFlavoredFormat "markdown") pure mformatspec
@@ -429,3 +455,69 @@
 
   -- Return ersatz file system.
   pure tree2
+
+-- | Helper type that holds all common state values that can be controlled.
+--
+-- This is closely related to "CommonState", but that's an opaque value
+-- that can only be read and modified through accessor functions. All
+-- fields in this type can be modified through accessors.
+data StateOptions = StateOptions
+  { stateOptsRequestHeaders :: [(T.Text, T.Text)]
+  , stateOptsResourcePath :: [String]
+  , stateOptsUserDataDir :: Maybe String
+  }
+
+-- | Peek pandoc state options; the current state properties are used for
+-- unspecified values.
+peekStateOptions :: Peeker PandocError StateOptions
+peekStateOptions idx = do
+  absidx <- liftLua $ absindex idx
+  let setOptions opts = do
+        liftLua (next absidx) >>= \case
+          False -> return opts
+          True -> do
+            key <- peekByteString (nth 2)
+            case key of
+              "request_headers" -> do
+                let peekHeaderPair = peekPair peekText peekText
+                value <- peekList peekHeaderPair top `lastly` pop 1
+                setOptions $ opts { stateOptsRequestHeaders = value }
+              "resource_path" -> do
+                value <- peekList peekString top `lastly` pop 1
+                setOptions $ opts { stateOptsResourcePath = value }
+              "user_data_dir" -> do
+                value <- peekNilOr peekString top `lastly` pop 1
+                setOptions $ opts { stateOptsUserDataDir = value }
+              _ -> do
+                liftLua $ pop 2 -- remove key and value
+                failPeek $ "Unknown or unsupported state option: " <> key
+
+  liftLua pushnil -- first "key"
+  liftLua getStateOptions >>= setOptions
+
+-- | Get the current options values from the pandoc state.
+getStateOptions :: LuaE PandocError StateOptions
+getStateOptions = unPandocLua $ StateOptions
+  <$> getRequestHeaders
+  <*> getResourcePath
+  <*> getUserDataDir
+
+-- | Update the pandoc state with the new options.
+setStateOptions :: StateOptions -> LuaE PandocError ()
+setStateOptions opts = unPandocLua $ do
+  setRequestHeaders $ stateOptsRequestHeaders opts
+  setResourcePath $ stateOptsResourcePath opts
+  setUserDataDir $ stateOptsUserDataDir opts
+
+-- | Run a callback with a modified pandoc state.
+with_state :: StateOptions -> StackIndex -> LuaE PandocError NumResults
+with_state options callback_idx = do
+  origState <- getStateOptions
+  setStateOptions options
+  -- Invoke the callback
+  oldTop <- gettop
+  pushvalue callback_idx
+  call 0 multret
+  newTop <- gettop
+  setStateOptions origState
+  return . NumResults . fromStackIndex $ newTop - oldTop
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Path.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Path.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Path.hs    
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Path.hs      
2001-09-09 03:46:40.000000000 +0200
@@ -3,7 +3,7 @@
 {-# LANGUAGE TypeApplications    #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Path
-   Copyright   : © 2019-2024 Albert Krewinkel
+   Copyright   : © 2019-2026 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <[email protected]>
@@ -22,14 +22,13 @@
 
 -- | Push the pandoc.system module on the Lua stack.
 documentedModule :: forall e. LuaError e => Module e
-documentedModule = Module
-  { moduleName = "pandoc.path"
-  , moduleDescription = moduleDescription @e MPath.documentedModule
-  , moduleFields =
+documentedModule = defmodule "pandoc.path"
+  `withDescription` moduleDescription @e MPath.documentedModule
+  `withFields`
       [ MPath.separator
       , MPath.search_path_separator
       ]
-  , moduleFunctions =
+  `withFunctions`
       [ MPath.directory              `since` v[2,12]
       , MSystem.exists               `since` v[3,7,1]
       , MPath.filename               `since` v[2,12]
@@ -43,8 +42,5 @@
       , MPath.split_search_path      `since` v[2,12]
       , MPath.treat_strings_as_paths `since` v[2,12]
       ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
  where
   v = makeVersion
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Scaffolding.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Scaffolding.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Scaffolding.hs     
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Scaffolding.hs       
2001-09-09 03:46:40.000000000 +0200
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Scaffolding
-   Copyright   : Copyright © 2022-2024 Albert Krewinkel, John MacFarlane
+   Copyright   : Copyright © 2022-2026 Albert Krewinkel, John MacFarlane
    License     : GNU GPL, version 2 or above
    Maintainer  : Albert Krewinkel <[email protected]>
 
@@ -18,28 +18,20 @@
 
 -- | The "pandoc.template" module.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.scaffolding"
-  , moduleDescription = T.unlines
-    [ "Scaffolding for custom writers."
-    ]
-  , moduleFields = [writerScaffolding]
-  , moduleOperations = []
-  , moduleFunctions = []
-  , moduleTypeInitializers = []
-  }
+documentedModule = defmodule "pandoc.scaffolding"
+  `withDescription` "Scaffolding for custom writers."
+  `withFields` [writerScaffolding]
 
 -- | Template module functions.
 writerScaffolding :: Field PandocError
-writerScaffolding = Field
-  { fieldName = "Writer"
-  , fieldType = "table"
-  , fieldDescription = T.unlines
+writerScaffolding = deffield "Writer"
+  `withType` "table"
+  `withDescription` T.unlines
     [ "An object to be used as a `Writer` function; the construct handles"
     , "most of the boilerplate, expecting only render functions for all"
     , "AST elements"
     ]
-  , fieldPushValue = do
+  `withValue` do
       pushWriterScaffolding
       -- pretend that it's a submodule so we get better error messages
       getfield registryindex loaded
@@ -50,5 +42,4 @@
       getfield (nth 2) "Block" *> setfield (nth 2) (submod "Writer.Block")
 
       pop 1 -- remove "LOADED_TABLE"
-  }
  where submod x = moduleName documentedModule <> "." <> x
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Structure.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Structure.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Structure.hs       
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Structure.hs 
2001-09-09 03:46:40.000000000 +0200
@@ -2,7 +2,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Structure
-   Copyright   : © 2023-2025 Albert Krewinkel <[email protected]>
+   Copyright   : © 2023-2026 Albert Krewinkel <[email protected]>
    License     : GPL-2.0-or-later
    Maintainer  : Albert Krewinkel <[email protected]>
 
@@ -17,11 +17,11 @@
 import Data.Maybe (fromMaybe)
 import Data.Version (makeVersion)
 import HsLua ( DocumentedFunction, LuaError, Module (..), Peeker
-             , (###), (<#>), (=#>), (#?)
+             , (###), (<#>), (=#>), (#?), defmodule
              , defun, functionResult, getfield, isnil, lastly, liftLua
              , opt, liftPure, parameter , peekBool, peekIntegral
              , peekFieldRaw, peekSet, peekText, pop, pushIntegral
-             , pushText, since, top )
+             , pushText, since, top, withDescription, withFunctions )
 import Text.Pandoc.Chunks ( ChunkedDoc (..), PathTemplate (..)
                           , tocToList, splitIntoChunks )
 import Text.Pandoc.Definition (Pandoc (..), Block)
@@ -41,22 +41,17 @@
 
 -- | Push the pandoc.structure module on the Lua stack.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.structure"
-  , moduleDescription =
+documentedModule = defmodule "pandoc.structure"
+  `withDescription`
     "Access to the higher-level document structure, including " <>
     "hierarchical sections and the table of contents."
-  , moduleFields = []
-  , moduleFunctions =
+  `withFunctions`
       [ make_sections     `since` makeVersion [3,0]
       , slide_level       `since` makeVersion [3,0]
       , split_into_chunks `since` makeVersion [3,0]
       , table_of_contents `since` makeVersion [3,0]
       , unique_identifier `since` makeVersion [3,8]
       ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
 
 make_sections :: LuaError e => DocumentedFunction e
 make_sections = defun "make_sections"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/System.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/System.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/System.hs  
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/System.hs    
2001-09-09 03:46:40.000000000 +0200
@@ -26,34 +26,27 @@
 
 -- | Push the pandoc.system module on the Lua stack.
 documentedModule :: forall e. LuaError e => Module e
-documentedModule = Module
-  { moduleName = "pandoc.system"
-  , moduleDescription = moduleDescription @e MSys.documentedModule
-  , moduleFields =
-      [ arch
-      , os
+documentedModule = defmodule "pandoc.system"
+  `withDescription` moduleDescription @e MSys.documentedModule
+  `withFields` [arch, os]
+  `withFunctions`
+      [         cputime                                `since` v[3,1,1]
+      , setName cmd         "command"                  `since` v[3,7,1]
+      , setName cp          "copy"                     `since` v[3,7,1]
+      , setName env         "environment"              `since` v[2,7,3]
+      , setName getwd       "get_working_directory"    `since` v[2,8]
+      , setName ls          "list_directory"           `since` v[2,19]
+      , setName mkdir       "make_directory"           `since` v[2,19]
+      ,         read_file                              `since` v[3,7,1]
+      ,         rename                                 `since` v[3,7,1]
+      , setName rm          "remove"                   `since` v[3,7,1]
+      , setName rmdir       "remove_directory"         `since` v[2,19]
+      ,         times                                  `since` v[3,7,1]
+      , setName with_env    "with_environment"         `since` v[2,7,3]
+      , setName with_tmpdir "with_temporary_directory" `since` v[2,8]
+      , setName with_wd     "with_working_directory"   `since` v[2,7,3]
+      ,         write_file                             `since` v[3,7,1]
+      ,         xdg                                    `since` v[3,7,1]
       ]
-  , moduleFunctions =
-      [ cputime                                        `since` v[3,1,1]
-      , setName "command" cmd                          `since` v[3,7,1]
-      , setName "copy" cp                              `since` v[3,7,1]
-      , setName "environment" env                      `since` v[2,7,3]
-      , setName "get_working_directory" getwd          `since` v[2,8]
-      , setName "list_directory" ls                    `since` v[2,19]
-      , setName "make_directory" mkdir                 `since` v[2,19]
-      , read_file                                      `since` v[3,7,1]
-      , rename                                         `since` v[3,7,1]
-      , setName "remove" rm                            `since` v[3,7,1]
-      , setName "remove_directory" rmdir               `since` v[2,19]
-      , times                                          `since` v[3,7,1]
-      , setName "with_environment" with_env            `since` v[2,7,3]
-      , setName "with_temporary_directory" with_tmpdir `since` v[2,8]
-      , setName "with_working_directory" with_wd       `since` v[2,7,3]
-      , write_file                                     `since` v[3,7,1]
-      , xdg                                            `since` v[3,7,1]
-      ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
  where
   v = makeVersion
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Template.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Template.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Template.hs        
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Template.hs  
2001-09-09 03:46:40.000000000 +0200
@@ -1,8 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Template
-   Copyright   : Copyright © 2022-2024 Albert Krewinkel, John MacFarlane
-   License     : GNU GPL, version 2 or above
+   Copyright   : Copyright © 2022-2026 Albert Krewinkel, John MacFarlane
+   License     : GPL-2.0-or-later
    Maintainer  : Albert Krewinkel <[email protected]>
 
 Lua module to handle pandoc templates.
@@ -28,16 +28,10 @@
 
 -- | The "pandoc.template" module.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.template"
-  , moduleDescription = T.unlines
-    [ "Handle pandoc templates."
-    ]
-  , moduleFields = []
-  , moduleOperations = []
-  , moduleFunctions = functions
-  , moduleTypeInitializers = [initType typeTemplate]
-  }
+documentedModule = defmodule "pandoc.template"
+  `withDescription` "Handle pandoc templates."
+  `withFunctions` functions
+  `associateType` typeTemplate
 
 -- | Template module functions.
 functions :: [DocumentedFunction PandocError]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Text.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Text.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Text.hs    
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Text.hs      
2001-09-09 03:46:40.000000000 +0200
@@ -22,9 +22,8 @@
 
 -- | The @aeson@ module specification.
 documentedModule :: Module PandocError
-documentedModule = TM.documentedModule
-  { moduleName = "pandoc.text"
-  , moduleFunctions =
+documentedModule = defmodule "pandoc.text"
+  `withFunctions`
     [ TM.fromencoding `since` v[3,0]
     , TM.len          `since` v[2,0,3]
     , TM.lower        `since` v[2,0,3]
@@ -35,7 +34,7 @@
     , TM.toencoding   `since` v[3,0]
     , TM.upper        `since` v[2,0,3]
     ]
-  , moduleDescription = T.unlines
+  `withDescription` T.unlines
     [ "UTF-8 aware text manipulation functions, implemented in Haskell."
     , ""
     , "The text module can also be loaded under the name `text`, although"
@@ -49,7 +48,6 @@
     , "end"
     , "```"
     ]
-  }
  where
   v = makeVersion
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Types.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Types.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Types.hs   
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Types.hs     
2001-09-09 03:46:40.000000000 +0200
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Types
-   Copyright   : © 2019-2024 Albert Krewinkel
+   Copyright   : © 2019-2026 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <[email protected]>
@@ -13,33 +13,64 @@
   ( documentedModule
   ) where
 
-import Data.Version (makeVersion)
-import HsLua ( Module (..), (###), (<#>), (=#>)
-             , defun, functionResult, parameter, since)
-import HsLua.Module.Version (peekVersionFuzzy, pushVersion)
+import Data.Version (Version, makeVersion)
+import HsLua ( DocumentedFunction, Module (..)
+             , (###), (<#>), (=#>), (#?), associateType
+             , defmodule, defun, functionResult, parameter, since
+             , withDescription, withFunctions
+             )
+import HsLua.Module.Version (peekVersionFuzzy, pushVersion, typeVersion)
 import Text.Pandoc.Error (PandocError)
+import Text.Pandoc.Lua.Marshal.Sources (peekSources, pushSources, typeSource)
 import Text.Pandoc.Lua.PandocLua ()
 
 -- | Push the pandoc.types module on the Lua stack.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.types"
-  , moduleDescription =
+documentedModule = defmodule "pandoc.types"
+  `withDescription`
       "Constructors for types that are not part of the pandoc AST."
-  , moduleFields = []
-  , moduleFunctions =
-      [ defun "Version"
-        ### return
-        <#> parameter peekVersionFuzzy "string|number|{integer,...}|Version"
-              "version_specifier"
-              (mconcat [ "A version string like `'2.7.3'`, "
-                       , "a Lua number like `2.0`, "
-                       , "a list of integers like `{2,7,3}`, "
-                       , "or a Version object."
-                       ])
-        =#> functionResult pushVersion "Version" "New Version object."
-        `since` makeVersion [2,7,3]
-      ]
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  }
+  `withFunctions`
+    [ mkVersion `since` v[2,7,3]
+    , mkSources `since` v[3,9,1]
+    ]
+  `associateType` typeSource
+  `associateType` typeVersion
+ where
+  v :: [Int] -> Version
+  v = makeVersion
+
+mkVersion :: DocumentedFunction PandocError
+mkVersion = defun "Version"
+  ### return
+  <#> parameter peekVersionFuzzy "string|number|{integer,...}|Version"
+        "version_specifier"
+        (mconcat [ "A version string like `'2.7.3'`, "
+                 , "a Lua number like `2.0`, "
+                 , "a list of integers like `{2,7,3}`, "
+                 , "or a Version object."
+                 ])
+  =#> functionResult pushVersion "Version" "New Version object."
+
+mkSources :: DocumentedFunction PandocError
+mkSources = defun "Sources"
+  ### pure
+  <#> parameter peekSources "string|{string,...}|table" "srcs"
+        "sources"
+  =#> functionResult pushSources "{Source,...}" "new Sources object"
+  #?
+    "Creates a new Sources element, i.e., a list of [[Source]] items.\n\
+    \\n\
+    \ Pandoc's text readers expect the input text to be paired\
+    \ with information on where the text originated, e.g., a\
+    \ file name. This abstraction is provided via the `Sources` type.\n\
+    \\n\
+    \Pandoc accepts a range of objects wherever a *Sources* list is\
+    \ expected:\n\
+    \\n\
+    \  - a list of [[Source]] items;\n\
+    \  - a simple string, which becomes an unnamed source;\n\
+    \  - a list of table objects, where each table contains the fields\n\
+    \    `name` (the filepath) and `text` (the file contents)\n\
+    \\n\
+    \A Sources list can be converted to a string via the default `tostring`\
+    \ Lua function. This will concatenate all source items."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Utils.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Utils.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module/Utils.hs   
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module/Utils.hs     
2001-09-09 03:46:40.000000000 +0200
@@ -4,7 +4,7 @@
 {-# LANGUAGE TypeApplications    #-}
 {- |
    Module      : Text.Pandoc.Lua.Module.Utils
-   Copyright   : Copyright © 2017-2024 Albert Krewinkel
+   Copyright   : © 2017-2026 Albert Krewinkel
    License     : GNU GPL, version 2 or above
 
    Maintainer  : Albert Krewinkel <[email protected]>
@@ -19,6 +19,7 @@
 
 import Control.Applicative ((<|>))
 import Control.Monad ((<$!>))
+import Control.Monad.Except (MonadError (throwError))
 import Crypto.Hash (hashWith, SHA1(SHA1))
 import Data.Data (showConstr, toConstr)
 import Data.Default (def)
@@ -28,12 +29,17 @@
 import HsLua.Module.Version (peekVersionFuzzy, pushVersion)
 import Text.Pandoc.Citeproc (getReferences, processCitations)
 import Text.Pandoc.Definition
-import Text.Pandoc.Error (PandocError)
+import Text.Pandoc.Error (PandocError (PandocLuaError))
 import Text.Pandoc.Filter (applyJSONFilter)
+import Text.Pandoc.Format (FlavoredFormat (formatName), parseFlavoredFormat)
+import Text.Pandoc.Lua.Documentation (renderDocumentation)
 import Text.Pandoc.Lua.Filter (runFilterFile')
 import Text.Pandoc.Lua.Marshal.AST
+import Text.Pandoc.Lua.Marshal.Format (peekFlavoredFormat)
 import Text.Pandoc.Lua.Marshal.Reference
 import Text.Pandoc.Lua.PandocLua (PandocLua (unPandocLua))
+import Text.Pandoc.Options (WriterOptions (writerExtensions))
+import Text.Pandoc.Writers (Writer (..), getWriter)
 
 import qualified Data.Map as Map
 import qualified Data.Text as T
@@ -44,18 +50,15 @@
 
 -- | Push the "pandoc.utils" module to the Lua stack.
 documentedModule :: Module PandocError
-documentedModule = Module
-  { moduleName = "pandoc.utils"
-  , moduleDescription = T.unlines
+documentedModule = defmodule "pandoc.utils"
+  `withDescription` T.unlines
     [ "This module exposes internal pandoc functions and utility"
     , "functions."
     ]
-  , moduleFields = []
-  , moduleOperations = []
-  , moduleTypeInitializers = []
-  , moduleFunctions =
+  `withFunctions`
     [ blocks_to_inlines `since` v[2,2,3]
     , citeproc          `since` v[2,19,1]
+    , documentation     `since` v[3,8,4]
     , equals            `since` v[2,5]
     , from_simple_table `since` v[2,11]
     , make_sections     `since` v[2,8]
@@ -71,13 +74,11 @@
 
     , defun "Version"
       ### liftPure (id @Version)
-      <#> parameter peekVersionFuzzy
-            "version string, list of integers, or integer"
+      <#> parameter peekVersionFuzzy "Version|string|{integer,...}|number"
             "v" "version description"
       =#> functionResult pushVersion "Version" "new Version object"
       #? "Creates a Version object."
     ]
-  }
  where
   v = makeVersion
 
@@ -130,6 +131,35 @@
       , "    end"
       ]
 
+documentation :: DocumentedFunction PandocError
+documentation = defun "documentation"
+  ### (\idx mformat -> do
+          docobj <- getdocumentation idx >>= \case
+            TypeNil -> fail "Undocumented object"
+            _ -> forcePeek $ peekDocumentationObject top
+          let blocks = renderDocumentation docobj
+          if maybe mempty formatName mformat == "blocks"
+            then pure . Left $ B.toList blocks
+            else unPandocLua $ do
+              flvrd <- maybe (parseFlavoredFormat "ansi") pure mformat
+              getWriter flvrd >>= \case
+                (TextWriter w, es) -> Right <$>
+                  w def{ writerExtensions = es } (B.doc blocks)
+                _ -> throwError $ PandocLuaError
+                  "ByteString writers are not supported here.")
+  <#> parameter pure "any" "object" "Retrieve documentation for this object"
+  <#> opt (parameter peekFlavoredFormat "string|table" "format"
+            "result format; defaults to `'ansi'`")
+  =#> functionResult (either pushBlocks pushText) "string|Blocks"
+        "rendered documentation"
+  #? "Return the documentation for a function or module defined by pandoc.\
+     \ Throws an error if there is no documentation for the given object.\n\
+     \\n\
+     \The result format can be any textual format accepted by `pandoc.write`,\
+     \ and the documentation will be returned in that format.\
+     \ Additionally, the special format `blocks` is accepted, in which case\
+     \ the documentation is returned as [[Blocks]]."
+
 equals :: LuaError e => DocumentedFunction e
 equals = defun "equals"
   ### equal
@@ -210,7 +240,7 @@
 normalize_date = defun "normalize_date"
   ### liftPure Shared.normalizeDate
   <#> parameter peekText "string" "date" "the date string"
-  =#> functionResult (maybe pushnil pushText) "string or nil"
+  =#> functionResult (maybe pushnil pushText) "string|nil"
         "normalized date, or nil if normalization failed."
   #? T.unwords
   [ "Parse a date and convert (if possible) to \"YYYY-MM-DD\" format. We"
@@ -325,7 +355,8 @@
          , (fmap (const "") . peekAttr)
          , (fmap (const "") . peekListAttributes)
          ] idx)
-  <#> parameter pure "AST element" "element" "some pandoc AST element"
+  <#> parameter pure "Pandoc|Block|Inline|Caption|Cell|MetaValue"
+        "element" "some pandoc AST element"
   =#> functionResult pushText "string"
         "A plain string representation of the given element."
   #? T.unlines
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module.hs 
new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module.hs
--- old/pandoc-lua-engine-0.5.0.2/src/Text/Pandoc/Lua/Module.hs 2001-09-09 
03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/src/Text/Pandoc/Lua/Module.hs   2001-09-09 
03:46:40.000000000 +0200
@@ -2,7 +2,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {- |
    Module      : Text.Pandoc.Lua.Module
-   Copyright   : © 2017-2024 Albert Krewinkel
+   Copyright   : © 2017-2026 Albert Krewinkel
    License     : GPL-2.0-or-later
    Maintainer  : Albert Krewinkel <[email protected]>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pandoc-lua-engine-0.5.0.2/test/lua/module/pandoc-types.lua 
new/pandoc-lua-engine-0.5.3/test/lua/module/pandoc-types.lua
--- old/pandoc-lua-engine-0.5.0.2/test/lua/module/pandoc-types.lua      
2001-09-09 03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/test/lua/module/pandoc-types.lua        
2001-09-09 03:46:40.000000000 +0200
@@ -1,5 +1,7 @@
 local tasty = require 'tasty'
+local system = require 'pandoc.system'
 local types = require 'pandoc.types'
+local Sources = types.Sources
 local Version = types.Version
 
 local assert = tasty.assert
@@ -7,6 +9,32 @@
 local group = tasty.test_group
 
 return {
+  group 'Sources' {
+    group 'constructor' {
+      test('has type `table`', function ()
+        assert.are_same(type(Sources ""), 'table')
+      end),
+      test('accepts a single string', function ()
+        assert.are_same(type(Sources('a')), 'table')
+      end),
+      test('accepts a list of strings', function ()
+        local srcs = Sources{'first text\n', 'second text\n'}
+        assert.are_equal(srcs[1].name, '')
+        assert.are_equal(srcs[1].text, 'first text\n')
+      end),
+      test('accepts list of filepath/content tuples', function ()
+        local srcs = Sources{{'test.txt', 'semi-random content'}}
+        assert.are_equal(srcs[1].name, 'test.txt')
+        assert.are_equal(srcs[1].text, 'semi-random content\n')
+      end),
+      test('accepts lists of Source-like tables', function ()
+        local srcs = Sources{{name = 'test.txt', text = 'semi-random content'}}
+        assert.are_equal(srcs[1].name, 'test.txt')
+        assert.are_equal(srcs[1].text, 'semi-random content\n')
+      end),
+    },
+  },
+
   group 'Version' {
 
     group 'constructor' {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pandoc-lua-engine-0.5.0.2/test/lua/module/pandoc.lua 
new/pandoc-lua-engine-0.5.3/test/lua/module/pandoc.lua
--- old/pandoc-lua-engine-0.5.0.2/test/lua/module/pandoc.lua    2001-09-09 
03:46:40.000000000 +0200
+++ new/pandoc-lua-engine-0.5.3/test/lua/module/pandoc.lua      2001-09-09 
03:46:40.000000000 +0200
@@ -273,7 +273,7 @@
     test('unsupported extension', function ()
       assert.error_matches(
         function () pandoc.read('foo', 'gfm+empty_paragraphs') end,
-        'The extension empty_paragraphs is not supported for gfm'
+        'The extension \'empty_paragraphs\' is not supported for gfm'
       )
     end),
     test('read with other indented code classes', function()
@@ -297,7 +297,7 @@
     test('failing read', function ()
       assert.error_matches(
         function () pandoc.read('foo', 'nosuchreader') end,
-        'Unknown input format nosuchreader'
+        'Unknown input format \'nosuchreader\''
       )
     end),
     group 'read_env' {
@@ -364,21 +364,21 @@
       test('unsupported extension', function ()
         assert.error_matches(
           function () pandoc.read('foo', 'gfm+empty_paragraphs') end,
-          'The extension empty_paragraphs is not supported for gfm'
+          'The extension \'empty_paragraphs\' is not supported for gfm'
         )
       end),
       test('unknown extension', function ()
         local format_spec = { format = 'markdown', extensions = {'nope'}}
         assert.error_matches(
           function () pandoc.read('x', format_spec) end,
-          'The extension nope is not supported for markdown'
+          'The extension \'nope\' is not supported for markdown'
         )
       end),
       test('fails on invalid extension', function ()
         local format_spec = { format = 'markdown', extensions = {'nope'}}
         assert.error_matches(
           function () pandoc.read('nu-uh', format_spec) end,
-          'The extension nope is not supported for markdown'
+          'The extension \'nope\' is not supported for markdown'
         )
       end),
     },
@@ -458,11 +458,53 @@
       local format_spec = { format = 'plain', extensions = {'nope'}}
       assert.error_matches(
         function () pandoc.write(doc, format_spec) end,
-        'The extension nope is not supported for plain'
+        'The extension \'nope\' is not supported for plain'
       )
     end),
   },
 
+  group 'with_state' {
+    test('request_headers can be modified', function ()
+      local headers = {
+        {"Authorization", "Basic my-secret"}
+      }
+      pandoc.with_state({request_headers = headers}, function ()
+        assert.are_same(PANDOC_STATE.request_headers, headers)
+      end)
+    end),
+    test('resource_path can be modified', function ()
+      local paths = {'.', '/test/resource/path' }
+      pandoc.with_state({resource_path = paths}, function ()
+        assert.are_same(PANDOC_STATE.resource_path, paths)
+      end)
+    end),
+    test('user_data_dir can be modified', function ()
+      local opts = {user_data_dir = '/my/test/path'}
+      pandoc.with_state(opts, function ()
+        assert.are_equal(PANDOC_STATE.user_data_dir, '/my/test/path')
+      end)
+    end),
+    test('original value is restored afterwards', function ()
+      local orig_user_data_dir = PANDOC_STATE.user_data_dir
+      local opts = {user_data_dir = '/my/test/path'}
+      pandoc.with_state(opts, function () end)
+      assert.are_equal(PANDOC_STATE.user_data_dir, orig_user_data_dir)
+    end),
+    test('unsupported options trigger an error', function ()
+      local orig_log = PANDOC_STATE.log
+      local opts = {log = 'nonsense'}
+      assert.error_matches(
+        function ()
+          pandoc.with_state(opts, function ()
+            assert.are_same(PANDOC_STATE.log, orig_log)
+          end)
+        end,
+        "Unknown or unsupported"
+      )
+      assert.are_same(PANDOC_STATE.log, orig_log)
+    end),
+  },
+
   group 'Marshal' {
     group 'Inlines' {
       test('Strings are broken into words', function ()

Reply via email to