git.iko.soy/typeable/pandoc
on master help sign in
Lua filters: load module `pandoc` before calling `init.lua` (#5287)
75c791bAlbert Krewinkel
data/init.lua−2
@@ -1,5 +1,3 @@
1-- This Lua script is run every time the Lua interpreter is started when running
1-- This Lua script is run every time the Lua interpreter is started when running
2-- a Lua filter. It can be customized to load additional modules or to alter the
2-- a Lua filter. It can be customized to load additional modules or to alter the
3-- default modules.
3-- default modules.
4−
5−pandoc = require 'pandoc'
doc/lua-filters.md+10−14
@@ -219,21 +219,15 @@ Some pandoc functions have been made available in lua:
219
219
220# Lua interpreter initialization
220# Lua interpreter initialization
221
221
222−The way the Lua interpreter is set-up can be controlled by
222+Initialization of pandoc's Lua interpreter can be controlled by
223−placing a file `init.lua` in pandoc's data directory. The
223+placing a file `init.lua` in pandoc's data directory. A common
224−default init file loads the `pandoc` and `pandoc.mediabag`
224+use-case would be to load additional modules, or even to alter
225−modules:
225+default modules.
226
226
227−``` {.lua}
227+The following snippet is an example of code that might be useful
228−pandoc = require 'pandoc'
228+when added to `init.lua`. The snippet adds all unicode-aware
229−pandoc.mediabag = require 'pandoc.mediabag'
230−```
231−
232−A common use-case would be to add code to load additional
233−modules or to alter default modules. E.g., the following snippet
234−adds all unicode-aware functions defined in the [`text`
229+functions defined in the [`text` module] to the default `string`
235−module](#module-text) to the default `string` module, prefixed
236−with the string `uc_`.
230+module, prefixed with the string `uc_`.
237
231
238``` {.lua}
232``` {.lua}
239for name, fn in pairs(require 'text') do
233for name, fn in pairs(require 'text') do
@@ -244,6 +238,8 @@ end
244This makes it possible to apply these functions on strings using
238This makes it possible to apply these functions on strings using
245colon syntax (`mystring:uc_upper()`).
239colon syntax (`mystring:uc_upper()`).
246
240
241+[`text` module]: #module-text
242+
247# Examples
243# Examples
248
244
249The following filters are presented as examples.
245The following filters are presented as examples.
src/Text/Pandoc/Lua/Init.hs+27−6
@@ -49,6 +49,7 @@ import Text.Pandoc.Lua.Util (loadScriptFromDataDir)
49import qualified Foreign.Lua as Lua
49import qualified Foreign.Lua as Lua
50import qualified Foreign.Lua.Module.Text as Lua
50import qualified Foreign.Lua.Module.Text as Lua
51import qualified Text.Pandoc.Definition as Pandoc
51import qualified Text.Pandoc.Definition as Pandoc
52+import qualified Text.Pandoc.Lua.Module.Pandoc as ModulePandoc
52
53
53-- | Lua error message
54-- | Lua error message
54newtype LuaException = LuaException String deriving (Show)
55newtype LuaException = LuaException String deriving (Show)
@@ -95,16 +96,37 @@ luaPackageParams = do
95
96
96-- | Initialize the lua state with all required values
97-- | Initialize the lua state with all required values
97initLuaState :: LuaPackageParams -> Lua ()
98initLuaState :: LuaPackageParams -> Lua ()
98−initLuaState luaPkgParams = do
99+initLuaState pkgParams = do
99 Lua.openlibs
100 Lua.openlibs
100 Lua.preloadTextModule "text"
101 Lua.preloadTextModule "text"
101− installPandocPackageSearcher luaPkgParams
102+ installPandocPackageSearcher pkgParams
103+ initPandocModule
102− loadScriptFromDataDir (luaPkgDataDir luaPkgParams) "init.lua"
104+ loadScriptFromDataDir (luaPkgDataDir pkgParams) "init.lua"
105+ where
106+ initPandocModule :: Lua ()
107+ initPandocModule = do
108+ -- Push module table
109+ ModulePandoc.pushModule (luaPkgDataDir pkgParams)
110+ -- register as loaded module
111+ Lua.pushvalue Lua.stackTop
112+ Lua.getfield Lua.registryindex Lua.loadedTableRegistryField
113+ Lua.setfield (Lua.nthFromTop 2) "pandoc"
114+ Lua.pop 1
115+ -- copy constructors into registry
103− putConstructorsInRegistry
116+ putConstructorsInRegistry
117+ -- assign module to global variable
118+ Lua.setglobal "pandoc"
104
119
120+-- | AST elements are marshaled via normal constructor functions in the
121+-- @pandoc@ module. However, accessing Lua globals from Haskell is
122+-- expensive (due to error handling). Accessing the Lua registry is much
123+-- cheaper, which is why the constructor functions are copied into the
124+-- Lua registry and called from there.
125+--
126+-- This function expects the @pandoc@ module to be at the top of the
127+-- stack.
105putConstructorsInRegistry :: Lua ()
128putConstructorsInRegistry :: Lua ()
106putConstructorsInRegistry = do
129putConstructorsInRegistry = do
107− Lua.getglobal "pandoc"
108 constrsToReg $ Pandoc.Pandoc mempty mempty
130 constrsToReg $ Pandoc.Pandoc mempty mempty
109 constrsToReg $ Pandoc.Str mempty
131 constrsToReg $ Pandoc.Str mempty
110 constrsToReg $ Pandoc.Para mempty
132 constrsToReg $ Pandoc.Para mempty
@@ -113,7 +135,6 @@ putConstructorsInRegistry = do
113 constrsToReg $ Pandoc.Citation mempty mempty mempty Pandoc.AuthorInText 0 0
135 constrsToReg $ Pandoc.Citation mempty mempty mempty Pandoc.AuthorInText 0 0
114 putInReg "Attr" -- used for Attr type alias
136 putInReg "Attr" -- used for Attr type alias
115 putInReg "ListAttributes" -- used for ListAttributes type alias
137 putInReg "ListAttributes" -- used for ListAttributes type alias
116− Lua.pop 1
117 where
138 where
118 constrsToReg :: Data a => a -> Lua ()
139 constrsToReg :: Data a => a -> Lua ()
119 constrsToReg = mapM_ (putInReg . showConstr) . dataTypeConstrs . dataTypeOf
140 constrsToReg = mapM_ (putInReg . showConstr) . dataTypeConstrs . dataTypeOf