git.iko.soy/typeable/pandoc
on master help sign in
Push blocks via lua constructors and constants

All element creation tasks are handled by lua functions defined in the pandoc module.

commit540a3e80ad33cb43d23532515757dff7ee68a17f authorAlbert Krewinkel <albert@zeitkraut.de> dateFri 14 Apr 2017, 10:33 (10 years ago) parent0085251
2 files changed+336−78
data/pandoc.lua+234−41 src/Text/Pandoc/Lua/StackInstances.hs+102−37
data/pandoc.lua+234−41
@@ -173,18 +173,23 @@ end
173173--- Meta blocks
174174-- @function MetaBlocks
175175-- @tparam {Block,...} blocks blocks
176+
176177--- Meta inlines
177178-- @function MetaInlines
178179-- @tparam {Inline,...} inlines inlines
180+
179181--- Meta list
180182-- @function MetaList
181183-- @tparam {MetaValue,...} meta_values list of meta values
184+
182185--- Meta boolean
183186-- @function MetaBool
184187-- @tparam boolean bool boolean value
188+
185189--- Meta map
186190-- @function MetaMap
187191-- @tparam table a string-index map of meta values
192+
188193--- Meta string
189194-- @function MetaString
190195-- @tparam string str string value
@@ -205,17 +210,166 @@ for i = 1, #M.meta_value_types do
205210 )
206211end
207212
208−--- Inline element class
209−-- @type Inline
210−M.Inline = Element:make_subtype{}
211−M.Inline.__call = function (t, ...)
213+------------------------------------------------------------------------
214+-- Block
215+-- @section Block
216+
217+M.Block = Element:make_subtype{}
218+M.Block.__call = function (t, ...)
212219 return t:new(...)
213220end
214221
222+--- Creates a block quote element
223+-- @function BlockQuote
224+-- @tparam {Block,...} content block content
225+-- @treturn Block block quote element
226+M.BlockQuote = M.Block:create_constructor(
227+ "BlockQuote",
228+ function(content) return {c = content} end
229+)
230+
231+--- Creates a bullet (i.e. unordered) list.
232+-- @function BulletList
233+-- @tparam {{Block,...},...} content list of items
234+-- @treturn Block block quote element
235+M.BulletList = M.Block:create_constructor(
236+ "BulletList",
237+ function(content) return {c = content} end
238+)
239+
240+--- Creates a code block element
241+-- @function CodeBlock
242+-- @tparam string code code string
243+-- @tparam[opt] Attributes attributes element attributes
244+-- @treturn Block code block element
245+M.CodeBlock = M.Block:create_constructor(
246+ "CodeBlock",
247+ function(code, attributes) return {c = {attributes, code}} end
248+)
249+
250+--- Creates a definition list, containing terms and their explanation.
251+-- @function DefinitionList
252+-- @tparam {{{Inline,...},{Block,...}},...} content list of items
253+-- @treturn Block block quote element
254+M.DefinitionList = M.Block:create_constructor(
255+ "DefinitionList",
256+ function(content) return {c = content} end
257+)
258+
259+--- Creates a div element
260+-- @function Div
261+-- @tparam {Block,...} content block content
262+-- @tparam[opt] Attributes attributes element attributes
263+-- @treturn Block code block element
264+M.Div = M.Block:create_constructor(
265+ "Div",
266+ function(content, attributes) return {c = {attributes, content}} end
267+)
268+
269+--- Creates a block quote element.
270+-- @function Header
271+-- @tparam int level header level
272+-- @tparam Attributes attributes element attributes
273+-- @tparam {Inline,...} content inline content
274+-- @treturn Block header element
275+M.Header = M.Block:create_constructor(
276+ "Header",
277+ function(level, attributes, content)
278+ return {c = {level, attributes, content}}
279+ end
280+)
281+
282+--- Creates a horizontal rule.
283+-- @function HorizontalRule
284+-- @treturn Block horizontal rule
285+M.HorizontalRule = M.Block:create_constructor(
286+ "HorizontalRule",
287+ function() return {} end
288+)
289+
290+--- Creates a line block element.
291+-- @function LineBlock
292+-- @tparam {{Inline,...},...} content inline content
293+-- @treturn Block block quote element
294+M.LineBlock = M.Block:create_constructor(
295+ "LineBlock",
296+ function(content) return {c = content} end
297+)
298+
299+--- Creates a null element.
300+-- @function Null
301+-- @treturn Block null element
302+M.Null = M.Block:create_constructor(
303+ "Null",
304+ function() return {} end
305+)
306+
307+--- Creates an ordered list.
308+-- @function OrderedList
309+-- @tparam {{Block,...},...} items list items
310+-- @param[opt] listAttributes list parameters
311+-- @treturn Block
312+M.OrderedList = M.Block:create_constructor(
313+ "OrderedList",
314+ function(items, listAttributes)
315+ return {c = {listAttributes,items}}
316+ end
317+)
318+
319+--- Creates a para element.
320+-- @function Para
321+-- @tparam {Inline,...} content inline content
322+-- @treturn Block block quote element
323+M.Para = M.Block:create_constructor(
324+ "Para",
325+ function(content) return {c = content} end
326+)
327+
328+--- Creates a plain element.
329+-- @function Plain
330+-- @tparam {Inline,...} content inline content
331+-- @treturn Block block quote element
332+M.Plain = M.Block:create_constructor(
333+ "Plain",
334+ function(content) return {c = content} end
335+)
336+
337+--- Creates a raw content block of the specified format.
338+-- @function RawBlock
339+-- @tparam string format format of content
340+-- @tparam string content string content
341+-- @treturn Block block quote element
342+M.RawBlock = M.Block:create_constructor(
343+ "RawBlock",
344+ function(format, content) return {c = {format, content}} end
345+)
346+
347+--- Creates a table element.
348+-- @function Table
349+-- @tparam {Inline,...} caption table caption
350+-- @tparam {AlignDefault|AlignLeft|AlignRight|AlignCenter,...} aligns alignments
351+-- @tparam {int,...} widths column widths
352+-- @tparam {Block,...} headers header row
353+-- @tparam {{Block,...}} rows table rows
354+-- @treturn Block block quote element
355+M.Table = M.Block:create_constructor(
356+ "Table",
357+ function(caption, aligns, widths, headers, rows)
358+ return {c = {caption, aligns, widths, headers, rows}}
359+ end
360+)
361+
362+
215363------------------------------------------------------------------------
216364-- Inline
217365-- @section Inline
218366
367+--- Inline element class
368+M.Inline = Element:make_subtype{}
369+M.Inline.__call = function (t, ...)
370+ return t:new(...)
371+end
372+
219373--- Creates a Cite inline element
220374-- @function Cite
221375-- @tparam {Inline,...} content List of inlines
@@ -405,42 +559,6 @@ M.Superscript = M.Inline:create_constructor(
405559)
406560
407561
408−------------------------------------------------------------------------
409−-- Block elements
410−-- @type Block
411−M.Block = Element:make_subtype{}
412−
413−--- Block constructors
414−M.Block.constructors = {
415− BlockQuote = true,
416− BulletList = true,
417− CodeBlock = true,
418− DefinitionList = true,
419− Div = true,
420− Header = true,
421− HorizontalRule = true,
422− HorizontalRule = true,
423− LineBlock = true,
424− Null = true,
425− OrderedList = true,
426− Para = true,
427− Plain = true,
428− RawBlock = true,
429− Table = true,
430−}
431−
432−local set_of_inline_types = {}
433−for k, _ in pairs(M.Inline.constructor) do
434− set_of_inline_types[k] = true
435−end
436−
437−for block_type, _ in pairs(M.Block.constructors) do
438− M[block_type] = function(...)
439− return M.Block:new(block_type, ...)
440− end
441−end
442−
443−
444562------------------------------------------------------------------------
445563-- Constants
446564-- @section constants
@@ -482,6 +600,81 @@ M.SuppressAuthor.t = "SuppressAuthor"
482600M.NormalCitation = {}
483601M.NormalCitation.t = "NormalCitation"
484602
603+--- Table cells aligned left.
604+-- @see Table
605+M.AlignLeft = {}
606+M.AlignLeft.t = "AlignLeft"
607+
608+--- Table cells right-aligned.
609+-- @see Table
610+M.AlignRight = {}
611+M.AlignRight.t = "AlignRight"
612+
613+--- Table cell content is centered.
614+-- @see Table
615+M.AlignCenter = {}
616+M.AlignCenter.t = "AlignCenter"
617+
618+--- Table cells are alignment is unaltered.
619+-- @see Table
620+M.AlignDefault = {}
621+M.AlignDefault.t = "AlignDefault"
622+
623+--- Default list number delimiters are used.
624+-- @see OrderedList
625+M.DefaultDelim = {}
626+M.DefaultDelim.t = "DefaultDelim"
627+
628+--- List numbers are delimited by a period.
629+-- @see OrderedList
630+M.Period = {}
631+M.Period.t = "Period"
632+
633+--- List numbers are delimited by a single parenthesis.
634+-- @see OrderedList
635+M.OneParen = {}
636+M.OneParen.t = "OneParen"
637+
638+--- List numbers are delimited by a double parentheses.
639+-- @see OrderedList
640+M.TwoParens = {}
641+M.TwoParens.t = "TwoParens"
642+
643+--- List are numbered in the default style
644+-- @see OrderedList
645+M.DefaultStyle = {}
646+M.DefaultStyle.t = "DefaultStyle"
647+
648+--- List items are numbered as examples.
649+-- @see OrderedList
650+M.Example = {}
651+M.Example.t = "Example"
652+
653+--- List are numbered using decimal integers.
654+-- @see OrderedList
655+M.Decimal = {}
656+M.Decimal.t = "Decimal"
657+
658+--- List are numbered using lower-case roman numerals.
659+-- @see OrderedList
660+M.LowerRoman = {}
661+M.LowerRoman.t = "LowerRoman"
662+
663+--- List are numbered using upper-case roman numerals
664+-- @see OrderedList
665+M.UpperRoman = {}
666+M.UpperRoman.t = "UpperRoman"
667+
668+--- List are numbered using lower-case alphabetic characters.
669+-- @see OrderedList
670+M.LowerAlpha = {}
671+M.LowerAlpha.t = "LowerAlpha"
672+
673+--- List are numbered using upper-case alphabetic characters.
674+-- @see OrderedList
675+M.UpperAlpha = {}
676+M.UpperAlpha.t = "UpperAlpha"
677+
485678
486679------------------------------------------------------------------------
487680-- Helper Functions
@@ -503,7 +696,7 @@ M.NormalCitation.t = "NormalCitation"
503696function M.global_filter()
504697 local res = {}
505698 for k, v in pairs(_G) do
506− if M.Inline.constructor[k] or M.Block.constructors[k] or k == "Doc" then
699+ if M.Inline.constructor[k] or M.Block.constructor[k] or M.Block.constructors[k] or k == "Doc" then
507700 res[k] = v
508701 end
509702 end
src/Text/Pandoc/Lua/StackInstances.hs+102−37
@@ -36,25 +36,17 @@ StackValue instances for pandoc types.
3636module Text.Pandoc.Lua.StackInstances () where
3737
3838import Control.Applicative ( (<|>) )
39−import Data.Aeson ( FromJSON(..), ToJSON(..), Result(..), Value, fromJSON )
4039import Scripting.Lua
4140 ( LTYPE(..), LuaState, StackValue(..)
4241 , call, getglobal2, gettable, ltype, newtable, next, objlen
43− , pop, pushnil, rawgeti, rawset, rawseti, settable
42+ , pop, pushnil, rawgeti, rawseti, settable
4443 )
4544import Scripting.Lua.Aeson ()
4645import Text.Pandoc.Definition
47− ( Block(..), Inline(..), Meta(..), MetaValue(..), Pandoc(..)
48− , Citation(..), CitationMode(..), Format(..), MathType(..), QuoteType(..) )
4946
5047import qualified Data.Map as M
5148import qualified Text.Pandoc.UTF8 as UTF8
5249
53−maybeFromJson :: (FromJSON a) => Maybe Value -> Maybe a
54−maybeFromJson mv = fromJSON <$> mv >>= \case
55− Success x -> Just x
56− _ -> Nothing
57−
5850instance StackValue Pandoc where
5951 push lua (Pandoc meta blocks) = do
6052 newtable lua
@@ -121,16 +113,22 @@ peekContent lua idx = do
121113
122114instance StackValue Block where
123115 push lua = \case
124− BlockQuote blcks -> pushTagged lua "BlockQuote" blcks
125− BulletList items -> pushTagged lua "BulletList" items
126− HorizontalRule -> pushTagged' lua "HorizontalRule"
127− LineBlock blcks -> pushTagged lua "LineBlock" blcks
128− Null -> pushTagged' lua "Null"
129− Para blcks -> pushTagged lua "Para" blcks
130− Plain blcks -> pushTagged lua "Plain" blcks
131− RawBlock f cs -> pushTagged lua "RawBlock" (f, cs)
116+ BlockQuote blcks -> pushViaConstructor lua "BlockQuote" blcks
117+ BulletList items -> pushViaConstructor lua "BulletList" items
118+ CodeBlock attr code -> pushViaConstructor lua "CodeBlock" code attr
119+ DefinitionList items -> pushViaConstructor lua "DefinitionList" items
120+ Div attr blcks -> pushViaConstructor lua "Div" blcks attr
121+ Header lvl attr inlns -> pushViaConstructor lua "Header" lvl attr inlns
122+ HorizontalRule -> pushViaConstructor lua "HorizontalRule"
123+ LineBlock blcks -> pushViaConstructor lua "LineBlock" blcks
124+ OrderedList lstAttr list -> pushViaConstructor lua "OrderedList" list lstAttr
125+ Null -> pushViaConstructor lua "Null"
126+ Para blcks -> pushViaConstructor lua "Para" blcks
127+ Plain blcks -> pushViaConstructor lua "Plain" blcks
128+ RawBlock f cs -> pushViaConstructor lua "RawBlock" f cs
129+ Table capt aligns widths headers rows ->
130+ pushViaConstructor lua "Table" capt aligns widths headers rows
132131 -- fall back to conversion via aeson's Value
133− x -> push lua (toJSON x)
134132 peek lua i = peekBlock lua i
135133 valuetype _ = TTABLE
136134
@@ -158,6 +156,22 @@ instance StackValue Inline where
158156 peek = peekInline
159157 valuetype _ = TTABLE
160158
159+instance StackValue Alignment where
160+ push lua = \case
161+ AlignLeft -> getglobal2 lua "pandoc.AlignLeft"
162+ AlignRight -> getglobal2 lua "pandoc.AlignRight"
163+ AlignCenter -> getglobal2 lua "pandoc.AlignCenter"
164+ AlignDefault -> getglobal2 lua "pandoc.AlignDefault"
165+ peek lua idx = do
166+ tag <- getField lua idx "t"
167+ case tag of
168+ Just "AlignLeft" -> return $ Just AlignLeft
169+ Just "AlignRight" -> return $ Just AlignRight
170+ Just "AlignCenter" -> return $ Just AlignCenter
171+ Just "AlignDefault" -> return $ Just AlignDefault
172+ _ -> return Nothing
173+ valuetype _ = TSTRING
174+
161175instance StackValue Citation where
162176 push lua (Citation cid prefix suffix mode noteNum hash) =
163177 pushViaConstructor lua "Citation" cid mode prefix suffix noteNum hash
@@ -183,13 +197,51 @@ instance StackValue CitationMode where
183197 Just "NormalCitation" -> return $ Just NormalCitation
184198 Just "SuppressAuthor" -> return $ Just SuppressAuthor
185199 _ -> return Nothing
186− valuetype _ = TSTRING
200+ valuetype _ = TTABLE
187201
188202instance StackValue Format where
189203 push lua (Format f) = push lua f
190204 peek lua idx = fmap Format <$> peek lua idx
191205 valuetype _ = TSTRING
192206
207+instance StackValue ListNumberDelim where
208+ push lua = \case
209+ DefaultDelim -> getglobal2 lua "pandoc.DefaultDelim"
210+ Period -> getglobal2 lua "pandoc.Period"
211+ OneParen -> getglobal2 lua "pandoc.OneParen"
212+ TwoParens -> getglobal2 lua "pandoc.TwoParens"
213+ peek lua idx = do
214+ tag <- getField lua idx "t"
215+ case tag of
216+ Just "DefaultDelim" -> return $ Just DefaultDelim
217+ Just "Period" -> return $ Just Period
218+ Just "OneParen" -> return $ Just OneParen
219+ Just "TwoParens" -> return $ Just TwoParens
220+ _ -> return Nothing
221+ valuetype _ = TTABLE
222+
223+instance StackValue ListNumberStyle where
224+ push lua = \case
225+ DefaultStyle -> getglobal2 lua "pandoc.DefaultStyle"
226+ LowerRoman -> getglobal2 lua "pandoc.LowerRoman"
227+ UpperRoman -> getglobal2 lua "pandoc.UpperRoman"
228+ LowerAlpha -> getglobal2 lua "pandoc.LowerAlpha"
229+ UpperAlpha -> getglobal2 lua "pandoc.UpperAlpha"
230+ Decimal -> getglobal2 lua "pandoc.Decimal"
231+ Example -> getglobal2 lua "pandoc.Example"
232+ peek lua idx = do
233+ tag <- getField lua idx "t"
234+ case tag of
235+ Just "DefaultStyle" -> return $ Just DefaultStyle
236+ Just "LowerRoman" -> return $ Just LowerRoman
237+ Just "UpperRoman" -> return $ Just UpperRoman
238+ Just "LowerAlpha" -> return $ Just LowerAlpha
239+ Just "UpperAlpha" -> return $ Just UpperAlpha
240+ Just "Decimal" -> return $ Just Decimal
241+ Just "Example" -> return $ Just Example
242+ _ -> return Nothing
243+ valuetype _ = TTABLE
244+
193245instance StackValue MathType where
194246 push lua = \case
195247 InlineMath -> getglobal2 lua "pandoc.InlineMath"
@@ -249,6 +301,26 @@ instance (StackValue a, StackValue b, StackValue c) =>
249301 return $ (,,) <$> a <*> b <*> c
250302 valuetype _ = TTABLE
251303
304+instance (StackValue a, StackValue b, StackValue c,
305+ StackValue d, StackValue e) =>
306+ StackValue (a, b, c, d, e)
307+ where
308+ push lua (a, b, c, d, e) = do
309+ newtable lua
310+ addIndexedValue lua 1 a
311+ addIndexedValue lua 2 b
312+ addIndexedValue lua 3 c
313+ addIndexedValue lua 4 d
314+ addIndexedValue lua 5 e
315+ peek lua idx = do
316+ a <- getIndexedValue lua idx 1
317+ b <- getIndexedValue lua idx 2
318+ c <- getIndexedValue lua idx 3
319+ d <- getIndexedValue lua idx 4
320+ e <- getIndexedValue lua idx 5
321+ return $ (,,,,) <$> a <*> b <*> c <*> d <*> e
322+ valuetype _ = TTABLE
323+
252324instance (Ord a, StackValue a, StackValue b) =>
253325 StackValue (M.Map a b) where
254326 push lua m = do
@@ -307,22 +379,6 @@ pushViaCall lua fn = pushViaCall' lua fn (return ()) 0
307379pushViaConstructor :: PushViaCall a => LuaState -> String -> a
308380pushViaConstructor lua pandocFn = pushViaCall lua ("pandoc." ++ pandocFn)
309381
310−-- | Push a value to the lua stack, tagged with a given string. This currently
311−-- creates a structure equivalent to what the JSONified value would look like
312−-- when pushed to lua.
313−pushTagged :: StackValue a => LuaState -> String -> a -> IO ()
314−pushTagged lua tag value = do
315− newtable lua
316− addKeyValue lua "t" tag
317− addKeyValue lua "c" value
318−
319−pushTagged' :: LuaState -> String -> IO ()
320−pushTagged' lua tag = do
321− newtable lua
322− push lua "t"
323− push lua tag
324− rawset lua (-3)
325−
326382-- | Return the value at the given index as inline if possible.
327383peekInline :: LuaState -> Int -> IO (Maybe Inline)
328384peekInline lua idx = do
@@ -366,13 +422,22 @@ peekBlock lua idx = do
366422 Just t -> case t of
367423 "BlockQuote" -> fmap BlockQuote <$> elementContent
368424 "BulletList" -> fmap BulletList <$> elementContent
425+ "CodeBlock" -> fmap (uncurry CodeBlock) <$> elementContent
426+ "DefinitionList" -> fmap DefinitionList <$> elementContent
427+ "Div" -> fmap (uncurry Div) <$> elementContent
428+ "Header" -> fmap (\(lvl, attr, lst) -> Header lvl attr lst)
429+ <$> elementContent
369430 "HorizontalRule" -> return (Just HorizontalRule)
370431 "LineBlock" -> fmap LineBlock <$> elementContent
432+ "OrderedList" -> fmap (uncurry OrderedList) <$> elementContent
371433 "Null" -> return (Just Null)
372434 "Para" -> fmap Para <$> elementContent
373435 "Plain" -> fmap Plain <$> elementContent
374− -- fall back to construction via aeson's Value
375− _ -> maybeFromJson <$> peek lua idx
436+ "RawBlock" -> fmap (uncurry RawBlock) <$> elementContent
437+ "Table" -> fmap (\(capt, aligns, widths, headers, body) ->
438+ Table capt aligns widths headers body)
439+ <$> elementContent
440+ _ -> return Nothing
376441 where
377442 -- Get the contents of an AST element.
378443 elementContent :: StackValue a => IO (Maybe a)