git.iko.soy/typeable/pandoc
on ea2ea45 help sign in
108 lines 3.8 kB history raw
1{-# LANGUAGE CPP #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE ScopedTypeVariables #-}
6{-# OPTIONS_GHC -fno-warn-orphans #-}
7{-
8Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23-}
24{- |
25 Module : Text.Pandoc.Lua
26 Copyright : Copyright © 2017 Albert Krewinkel
27 License : GNU GPL, version 2 or above
29 Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
30 Stability : alpha
32Pandoc lua utils.
33-}
34module Text.Pandoc.Lua (LuaException (..), pushPandocModule, runLuaFilter) where
36import Control.Monad (when, (>=>))
37import Control.Monad.Identity (Identity)
38import Control.Monad.Trans (MonadIO (..))
39import Data.IORef (IORef, newIORef, readIORef)
40import Foreign.Lua (FromLuaStack (peek), Lua, LuaException (..),
41 Status (OK), ToLuaStack (push))
42import Text.Pandoc.Class (CommonState, PandocIO, getCommonState, getMediaBag,
43 setMediaBag)
44import Text.Pandoc.Definition
45import Text.Pandoc.Lua.PandocModule (pushMediaBagModule, pushPandocModule)
46import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter)
47import Text.Pandoc.MediaBag (MediaBag)
48import qualified Foreign.Lua as Lua
49import qualified Foreign.Lua.Module.Text as Lua
51runLuaFilter :: Maybe FilePath -> FilePath -> String
52 -> Pandoc -> PandocIO (Either LuaException Pandoc)
53runLuaFilter datadir filterPath format pd = do
54 commonState <- getCommonState
55 mediaBag <- getMediaBag
56 mediaBagRef <- liftIO (newIORef mediaBag)
57 res <- liftIO . Lua.runLuaEither $
58 runLuaFilter' commonState datadir filterPath format mediaBagRef pd
59 newMediaBag <- liftIO (readIORef mediaBagRef)
60 setMediaBag newMediaBag
61 return res
63runLuaFilter' :: CommonState
64 -> Maybe FilePath -> FilePath -> String -> IORef MediaBag
65 -> Pandoc -> Lua Pandoc
66runLuaFilter' commonState datadir filterPath format mbRef pd = do
67 Lua.openlibs
68 Lua.preloadTextModule "text"
69 -- store module in global "pandoc"
70 pushPandocModule datadir
71 Lua.setglobal "pandoc"
72 addMediaBagModule
73 registerFormat
74 top <- Lua.gettop
75 stat <- Lua.dofile filterPath
76 if stat /= OK
77 then do
78 luaErrMsg <- peek (-1) <* Lua.pop 1
79 Lua.throwLuaError luaErrMsg
80 else do
81 newtop <- Lua.gettop
82 -- Use the implicitly defined global filter if nothing was returned
83 when (newtop - top < 1) pushGlobalFilter
84 luaFilters <- peek (-1)
85 runAll luaFilters pd
86 where
87 addMediaBagModule = do
88 Lua.getglobal "pandoc"
89 push "mediabag"
90 pushMediaBagModule commonState mbRef
91 Lua.rawset (-3)
92 registerFormat = do
93 push format
94 Lua.setglobal "FORMAT"
97pushGlobalFilter :: Lua ()
98pushGlobalFilter = do
99 Lua.newtable
100 Lua.getglobal' "pandoc.global_filter"
101 Lua.call 0 1
102 Lua.rawseti (-2) 1
104runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc
105runAll = foldr ((>=>) . walkMWithLuaFilter) return
107instance (FromLuaStack a) => FromLuaStack (Identity a) where
108 peek = fmap return . peek