Lua filters: use script to initialize the interpreter

The file `init.lua` is used to initialize the Lua interpreter which is
used in Lua filters. This gives users the option to require libraries
which they want to use in all of their filters, and to extend default
modules.
This commit is contained in:
Albert Krewinkel 2017-12-06 20:45:38 +01:00
parent d5b1c7b767
commit 4066a385ac
No known key found for this signature in database
GPG key ID: 388DC0B21F631124
5 changed files with 46 additions and 14 deletions

6
data/init.lua Normal file
View file

@ -0,0 +1,6 @@
-- This Lua script is run every time the Lua interpreter is started when running
-- a Lua filter. It can be customized to load additional modules or to alter the
-- default modules.
pandoc = require 'pandoc'
pandoc.mediabag = require 'pandoc.mediabag'

View file

@ -3,7 +3,7 @@ title: Pandoc Lua Filters
author:
- Albert Krewinkel
- John MacFarlane
date: 'November 20, 2017'
date: 'December 6, 2017'
---
# Introduction
@ -176,6 +176,34 @@ Some pandoc functions have been made available in lua:
which stores binary content such as images that may be
included in the final document.
# Lua interpreter initialization
The way the Lua interpreter is set-up can be controlled by
placing a file `init.lua` in pandoc's data directory. The
default init file loads the `pandoc` and `pandoc.mediabag`
modules:
``` lua
pandoc = require 'pandoc'
pandoc.mediabag = require 'pandoc.mediabag'
```
A common use-case would be to add code to load additional
modules or to alter default modules. E.g., the following snippet
adds all unicode-aware functions defined in the [`text`
module](#module-text) to the default `string` module, prefixed
with the string `uc_`.
```lua
for name, fn in pairs(require 'text') do
string['uc_' .. name] = fn
end
```
This makes it possible to apply these functions on strings using
colon syntax (`mystring:uc_upper()`).
# Examples
## Macro substitution.

View file

@ -108,6 +108,8 @@ data-files:
data/abbreviations
-- sample lua custom writer
data/sample.lua
-- lua init script
data/init.lua
-- pandoc lua module
data/pandoc.lua
-- lua List module

View file

@ -48,10 +48,11 @@ import Foreign.Lua (FromLuaStack (peek), Lua, LuaException (..),
Status (OK), ToLuaStack (push))
import Text.Pandoc.Class (PandocIO, getCommonState, getMediaBag, setMediaBag)
import Text.Pandoc.Definition
import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter)
import Text.Pandoc.Lua.Packages (LuaPackageParams (..),
installPandocPackageSearcher)
import Text.Pandoc.Lua.PandocModule (pushMediaBagModule, pushPandocModule)
import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter)
import Text.Pandoc.Lua.PandocModule (pushPandocModule) -- TODO: remove
import Text.Pandoc.Lua.Util (loadScriptFromDataDir)
import qualified Foreign.Lua as Lua
import qualified Foreign.Lua.Module.Text as Lua
@ -101,17 +102,11 @@ luaPackageParams datadir = do
-- Initialize the lua state with all required values
initLuaState :: LuaPackageParams -> Lua ()
initLuaState luaPkgParams@(LuaPackageParams commonState datadir mbRef) = do
initLuaState luaPkgParams = do
Lua.openlibs
Lua.preloadTextModule "text"
installPandocPackageSearcher luaPkgParams
pushPandocModule datadir
-- add MediaBag module
push "mediabag"
pushMediaBagModule commonState mbRef
Lua.rawset (-3)
Lua.setglobal "pandoc"
return ()
loadScriptFromDataDir (luaPkgDataDir luaPkgParams) "init.lua"
pushGlobalFilter :: Lua ()
pushGlobalFilter = do

View file

@ -60,7 +60,7 @@ import qualified Text.Pandoc.MediaBag as MB
-- | Push the "pandoc" on the lua stack. Requires the `list` module to be
-- loaded.
pushPandocModule :: Maybe FilePath -> Lua ()
pushPandocModule :: Maybe FilePath -> Lua NumResults
pushPandocModule datadir = do
loadScriptFromDataDir datadir "pandoc.lua"
addFunction "_pipe" pipeFn
@ -68,6 +68,7 @@ pushPandocModule datadir = do
addFunction "sha1" sha1HashFn
addFunction "walk_block" walkBlock
addFunction "walk_inline" walkInline
return 1
walkElement :: (ToLuaStack a, Walkable [Inline] a, Walkable [Block] a)
=> a -> LuaFilter -> Lua NumResults
@ -99,14 +100,14 @@ readDoc formatSpec content = do
--
-- MediaBag submodule
--
pushMediaBagModule :: CommonState -> IORef MB.MediaBag -> Lua ()
pushMediaBagModule :: CommonState -> IORef MB.MediaBag -> Lua NumResults
pushMediaBagModule commonState mediaBagRef = do
Lua.newtable
addFunction "insert" (insertMediaFn mediaBagRef)
addFunction "lookup" (lookupMediaFn mediaBagRef)
addFunction "list" (mediaDirectoryFn mediaBagRef)
addFunction "fetch" (fetch commonState mediaBagRef)
return ()
return 1
addFunction :: ToHaskellFunction a => String -> a -> Lua ()
addFunction name fn = do