@@ -1,11 +1,5 @@
1−{-# OPTIONS_GHC -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
31{-# LANGUAGE DeriveDataTypeable #-}
42{-# LANGUAGE FlexibleInstances #-}
5−#if MIN_VERSION_base(4,8,0)
6−#else
7−{-# LANGUAGE OverlappingInstances #-}
8−#endif
93{- Copyright (C) 2012-2017 John MacFarlane <jgm@berkeley.edu>
104
115This program is free software; you can redistribute it and/or modify
@@ -36,19 +30,23 @@ Conversion of 'Pandoc' documents to custom markup using
3630a lua writer.
3731-}
3832module Text.Pandoc.Writers.Custom ( writeCustom ) where
33+import Control.Arrow ((***))
3934import Control.Exception
4035import Control.Monad (when)
36+import Control.Monad.Trans (MonadIO (liftIO))
4137import Data.Char (toLower)
4238import Data.List (intersperse)
4339import qualified Data.Map as M
4440import Data.Text (Text, pack)
4541import Data.Typeable
46−import Foreign.Lua (Lua, ToLuaStack (..), callFunc, runLua)
42+import Foreign.Lua (Lua, ToLuaStack (..), callFunc)
4743import Foreign.Lua.Api
48−import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
44+import Text.Pandoc.Class (PandocIO)
4945import Text.Pandoc.Definition
5046import Text.Pandoc.Error
51−import Text.Pandoc.Lua.Util (addValue)
47+import Text.Pandoc.Lua.Init (runPandocLua)
48+import Text.Pandoc.Lua.StackInstances ()
49+import Text.Pandoc.Lua.Util (addValue, dostring')
5250import Text.Pandoc.Options
5351import Text.Pandoc.Templates
5452import qualified Text.Pandoc.UTF8 as UTF8
@@ -60,43 +58,31 @@ attrToMap (id',classes,keyvals) = M.fromList
6058 : ("class", unwords classes)
6159 : keyvals
6260
63−instance ToLuaStack Double where
64− push = push . (realToFrac :: Double -> LuaNumber)
65−
66−instance ToLuaStack Int where
67− push = push . (fromIntegral :: Int -> LuaInteger)
68−
69−instance ToLuaStack Format where
70− push (Format f) = push (map toLower f)
71−
72−#if MIN_VERSION_base(4,8,0)
73−instance {-# OVERLAPS #-} ToLuaStack [Inline] where
74−#else
75−instance ToLuaStack [Inline] where
76−#endif
77− push ils = push =<< inlineListToCustom ils
78−
79−#if MIN_VERSION_base(4,8,0)
80−instance {-# OVERLAPS #-} ToLuaStack [Block] where
81−#else
82−instance ToLuaStack [Block] where
83−#endif
84− push ils = push =<< blockListToCustom ils
85−
86−instance ToLuaStack MetaValue where
87− push (MetaMap m) = push m
88− push (MetaList xs) = push xs
89− push (MetaBool x) = push x
90− push (MetaString s) = push s
91− push (MetaInlines ils) = push ils
92− push (MetaBlocks bs) = push bs
93−
94−instance ToLuaStack Citation where
95− push cit = do
61+newtype Stringify a = Stringify a
62+
63+instance ToLuaStack (Stringify Format) where
64+ push (Stringify (Format f)) = push (map toLower f)
65+
66+instance ToLuaStack (Stringify [Inline]) where
67+ push (Stringify ils) = push =<< inlineListToCustom ils
68+
69+instance ToLuaStack (Stringify [Block]) where
70+ push (Stringify blks) = push =<< blockListToCustom blks
71+
72+instance ToLuaStack (Stringify MetaValue) where
73+ push (Stringify (MetaMap m)) = push (fmap Stringify m)
74+ push (Stringify (MetaList xs)) = push (map Stringify xs)
75+ push (Stringify (MetaBool x)) = push x
76+ push (Stringify (MetaString s)) = push s
77+ push (Stringify (MetaInlines ils)) = push (Stringify ils)
78+ push (Stringify (MetaBlocks bs)) = push (Stringify bs)
79+
80+instance ToLuaStack (Stringify Citation) where
81+ push (Stringify cit) = do
9682 createtable 6 0
9783 addValue "citationId" $ citationId cit
98− addValue "citationPrefix" $ citationPrefix cit
99− addValue "citationSuffix" $ citationSuffix cit
84+ addValue "citationPrefix" . Stringify $ citationPrefix cit
85+ addValue "citationSuffix" . Stringify $ citationSuffix cit
10086 addValue "citationMode" $ show (citationMode cit)
10187 addValue "citationNoteNum" $ citationNoteNum cit
10288 addValue "citationHash" $ citationHash cit
@@ -107,14 +93,11 @@ data PandocLuaException = PandocLuaException String
10793instance Exception PandocLuaException
10894
10995-- | Convert Pandoc to custom markup.
110−writeCustom :: FilePath -> WriterOptions -> Pandoc -> IO Text
96+writeCustom :: FilePath -> WriterOptions -> Pandoc -> PandocIO Text
11197writeCustom luaFile opts doc@(Pandoc meta _) = do
112− luaScript <- UTF8.readFile luaFile
113− enc <- getForeignEncoding
114− setForeignEncoding utf8
115− (body, context) <- runLua $ do
116− openlibs
117− stat <- loadstring luaScript
98+ luaScript <- liftIO $ UTF8.readFile luaFile
99+ res <- runPandocLua $ do
100+ stat <- dostring' luaScript
118101 -- check for error in lua script (later we'll change the return type
119102 -- to handle this more gracefully):
120103 when (stat /= OK) $
@@ -127,7 +110,9 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
127110 inlineListToCustom
128111 meta
129112 return (rendered, context)
130− setForeignEncoding enc
113+ let (body, context) = case res of
114+ Left e -> throw (PandocLuaException (show e))
115+ Right x -> x
131116 case writerTemplate opts of
132117 Nothing -> return $ pack body
133118 Just tpl ->
@@ -138,7 +123,7 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
138123docToCustom :: WriterOptions -> Pandoc -> Lua String
139124docToCustom opts (Pandoc (Meta metamap) blocks) = do
140125 body <- blockListToCustom blocks
141− callFunc "Doc" body metamap (writerVariables opts)
126+ callFunc "Doc" body (fmap Stringify metamap) (writerVariables opts)
142127
143128-- | Convert Pandoc block element to Custom.
144129blockToCustom :: Block -- ^ Block element
@@ -146,41 +131,45 @@ blockToCustom :: Block -- ^ Block element
146131
147132blockToCustom Null = return ""
148133
149−blockToCustom (Plain inlines) = callFunc "Plain" inlines
134+blockToCustom (Plain inlines) = callFunc "Plain" (Stringify inlines)
150135
151136blockToCustom (Para [Image attr txt (src,tit)]) =
152− callFunc "CaptionedImage" src tit txt (attrToMap attr)
137+ callFunc "CaptionedImage" src tit (Stringify txt) (attrToMap attr)
153138
154−blockToCustom (Para inlines) = callFunc "Para" inlines
139+blockToCustom (Para inlines) = callFunc "Para" (Stringify inlines)
155140
156−blockToCustom (LineBlock linesList) = callFunc "LineBlock" linesList
141+blockToCustom (LineBlock linesList) = callFunc "LineBlock" (map Stringify linesList)
157142
158143blockToCustom (RawBlock format str) =
159− callFunc "RawBlock" format str
144+ callFunc "RawBlock" (Stringify format) str
160145
161146blockToCustom HorizontalRule = callFunc "HorizontalRule"
162147
163148blockToCustom (Header level attr inlines) =
164− callFunc "Header" level inlines (attrToMap attr)
149+ callFunc "Header" level (Stringify inlines) (attrToMap attr)
165150
166151blockToCustom (CodeBlock attr str) =
167152 callFunc "CodeBlock" str (attrToMap attr)
168153
169−blockToCustom (BlockQuote blocks) = callFunc "BlockQuote" blocks
154+blockToCustom (BlockQuote blocks) = callFunc "BlockQuote" (Stringify blocks)
170155
171−blockToCustom (Table capt aligns widths headers rows') =
172− callFunc "Table" capt (map show aligns) widths headers rows'
156+blockToCustom (Table capt aligns widths headers rows) =
157+ let aligns' = map show aligns
158+ capt' = Stringify capt
159+ headers' = map Stringify headers
160+ rows' = map (map Stringify) rows
161+ in callFunc "Table" capt' aligns' widths headers' rows'
173162
174−blockToCustom (BulletList items) = callFunc "BulletList" items
163+blockToCustom (BulletList items) = callFunc "BulletList" (map Stringify items)
175164
176165blockToCustom (OrderedList (num,sty,delim) items) =
177− callFunc "OrderedList" items num (show sty) (show delim)
166+ callFunc "OrderedList" (map Stringify items) num (show sty) (show delim)
178167
179168blockToCustom (DefinitionList items) =
180− callFunc "DefinitionList" items
169+ callFunc "DefinitionList" (map (Stringify *** map Stringify) items)
181170
182171blockToCustom (Div attr items) =
183− callFunc "Div" items (attrToMap attr)
172+ callFunc "Div" (Stringify items) (attrToMap attr)
184173
185174-- | Convert list of Pandoc block elements to Custom.
186175blockListToCustom :: [Block] -- ^ List of block elements
@@ -205,23 +194,23 @@ inlineToCustom Space = callFunc "Space"
205194
206195inlineToCustom SoftBreak = callFunc "SoftBreak"
207196
208−inlineToCustom (Emph lst) = callFunc "Emph" lst
197+inlineToCustom (Emph lst) = callFunc "Emph" (Stringify lst)
209198
210−inlineToCustom (Strong lst) = callFunc "Strong" lst
199+inlineToCustom (Strong lst) = callFunc "Strong" (Stringify lst)
211200
212−inlineToCustom (Strikeout lst) = callFunc "Strikeout" lst
201+inlineToCustom (Strikeout lst) = callFunc "Strikeout" (Stringify lst)
213202
214−inlineToCustom (Superscript lst) = callFunc "Superscript" lst
203+inlineToCustom (Superscript lst) = callFunc "Superscript" (Stringify lst)
215204
216−inlineToCustom (Subscript lst) = callFunc "Subscript" lst
205+inlineToCustom (Subscript lst) = callFunc "Subscript" (Stringify lst)
217206
218−inlineToCustom (SmallCaps lst) = callFunc "SmallCaps" lst
207+inlineToCustom (SmallCaps lst) = callFunc "SmallCaps" (Stringify lst)
219208
220−inlineToCustom (Quoted SingleQuote lst) = callFunc "SingleQuoted" lst
209+inlineToCustom (Quoted SingleQuote lst) = callFunc "SingleQuoted" (Stringify lst)
221210
222−inlineToCustom (Quoted DoubleQuote lst) = callFunc "DoubleQuoted" lst
211+inlineToCustom (Quoted DoubleQuote lst) = callFunc "DoubleQuoted" (Stringify lst)
223212
224−inlineToCustom (Cite cs lst) = callFunc "Cite" lst cs
213+inlineToCustom (Cite cs lst) = callFunc "Cite" (Stringify lst) (map Stringify cs)
225214
226215inlineToCustom (Code attr str) =
227216 callFunc "Code" str (attrToMap attr)
@@ -233,17 +222,17 @@ inlineToCustom (Math InlineMath str) =
233222 callFunc "InlineMath" str
234223
235224inlineToCustom (RawInline format str) =
236− callFunc "RawInline" format str
225+ callFunc "RawInline" (Stringify format) str
237226
238227inlineToCustom LineBreak = callFunc "LineBreak"
239228
240229inlineToCustom (Link attr txt (src,tit)) =
241− callFunc "Link" txt src tit (attrToMap attr)
230+ callFunc "Link" (Stringify txt) src tit (attrToMap attr)
242231
243232inlineToCustom (Image attr alt (src,tit)) =
244− callFunc "Image" alt src tit (attrToMap attr)
233+ callFunc "Image" (Stringify alt) src tit (attrToMap attr)
245234
246−inlineToCustom (Note contents) = callFunc "Note" contents
235+inlineToCustom (Note contents) = callFunc "Note" (Stringify contents)
247236
248237inlineToCustom (Span attr items) =
249− callFunc "Span" items (attrToMap attr)
238+ callFunc "Span" (Stringify items) (attrToMap attr)