git.iko.soy/typeable/pandoc
on master help sign in
data/pandoc.lua: accept single block as singleton list
e0cb0daAlbert Krewinkel
data/pandoc.lua+28−19
@@ -186,15 +186,24 @@ function AstElement:create_constructor(tag, fn, accessors)
186 return constr
186 return constr
187end
187end
188
188
189+--- Convert AstElement input into a list if necessary.
190+-- @local
191+local function ensureList (x)
192+ if x.tag then
193+ -- Lists are not tagged, but all elements are
194+ return List:new{x}
195+ else
196+ return List:new(x)
197+ end
198+end
199+
189--- Ensure a given object is an Inline element, or convert it into one.
200--- Ensure a given object is an Inline element, or convert it into one.
201+-- @local
190local function ensureInlineList (x)
202local function ensureInlineList (x)
191− if type(x) == string then
203+ if type(x) == 'string' then
192 return List:new{M.Str(x)}
204 return List:new{M.Str(x)}
193− elseif x.tag then
194− -- Lists are not tagged, but all elements are
195− return List:new{x}
196 else
205 else
197− return x
206+ return ensureList(x)
198 end
207 end
199end
208end
200
209
@@ -209,7 +218,7 @@ end
209M.Pandoc = AstElement:make_subtype'Pandoc'
218M.Pandoc = AstElement:make_subtype'Pandoc'
210function M.Pandoc:new (blocks, meta)
219function M.Pandoc:new (blocks, meta)
211 return {
220 return {
212− blocks = List:new(blocks),
221+ blocks = ensureList(blocks),
213 meta = meta or {},
222 meta = meta or {},
214 }
223 }
215end
224end
@@ -239,7 +248,7 @@ M.MetaValue = AstElement:make_subtype('MetaValue')
239-- @tparam {Block,...} blocks blocks
248-- @tparam {Block,...} blocks blocks
240M.MetaBlocks = M.MetaValue:create_constructor(
249M.MetaBlocks = M.MetaValue:create_constructor(
241 'MetaBlocks',
250 'MetaBlocks',
242− function (content) return List:new(content) end
251+ function (content) return ensureList(content) end
243)
252)
244
253
245--- Meta inlines
254--- Meta inlines
@@ -255,7 +264,7 @@ M.MetaInlines = M.MetaValue:create_constructor(
255-- @tparam {MetaValue,...} meta_values list of meta values
264-- @tparam {MetaValue,...} meta_values list of meta values
256M.MetaList = M.MetaValue:create_constructor(
265M.MetaList = M.MetaValue:create_constructor(
257 'MetaList',
266 'MetaList',
258− function (content) return List:new(content) end
267+ function (content) return ensureList(content) end
259)
268)
260
269
261--- Meta map
270--- Meta map
@@ -295,7 +304,7 @@ M.Block = AstElement:make_subtype'Block'
295-- @treturn Block block quote element
304-- @treturn Block block quote element
296M.BlockQuote = M.Block:create_constructor(
305M.BlockQuote = M.Block:create_constructor(
297 "BlockQuote",
306 "BlockQuote",
298− function(content) return {c = content} end,
307+ function(content) return {c = ensureList(content)} end,
299 "content"
308 "content"
300)
309)
301
310
@@ -305,7 +314,7 @@ M.BlockQuote = M.Block:create_constructor(
305-- @treturn Block bullet list element
314-- @treturn Block bullet list element
306M.BulletList = M.Block:create_constructor(
315M.BulletList = M.Block:create_constructor(
307 "BulletList",
316 "BulletList",
308− function(content) return {c = content} end,
317+ function(content) return {c = ensureList(content)} end,
309 "content"
318 "content"
310)
319)
311
320
@@ -326,7 +335,7 @@ M.CodeBlock = M.Block:create_constructor(
326-- @treturn Block definition list element
335-- @treturn Block definition list element
327M.DefinitionList = M.Block:create_constructor(
336M.DefinitionList = M.Block:create_constructor(
328 "DefinitionList",
337 "DefinitionList",
329− function(content) return {c = List:new(content)} end,
338+ function(content) return {c = ensureList(content)} end,
330 "content"
339 "content"
331)
340)
332
341
@@ -338,7 +347,7 @@ M.DefinitionList = M.Block:create_constructor(
338M.Div = M.Block:create_constructor(
347M.Div = M.Block:create_constructor(
339 "Div",
348 "Div",
340 function(content, attr)
349 function(content, attr)
341− return {c = {attr or M.Attr(), List:new(content)}}
350+ return {c = {attr or M.Attr(), ensureList(content)}}
342 end,
351 end,
343 {{"identifier", "classes", "attributes"}, "content"}
352 {{"identifier", "classes", "attributes"}, "content"}
344)
353)
@@ -371,7 +380,7 @@ M.HorizontalRule = M.Block:create_constructor(
371-- @treturn Block line block element
380-- @treturn Block line block element
372M.LineBlock = M.Block:create_constructor(
381M.LineBlock = M.Block:create_constructor(
373 "LineBlock",
382 "LineBlock",
374− function(content) return {c = List:new(content)} end,
383+ function(content) return {c = ensureList(content)} end,
375 "content"
384 "content"
376)
385)
377
386
@@ -392,7 +401,7 @@ M.OrderedList = M.Block:create_constructor(
392 "OrderedList",
401 "OrderedList",
393 function(items, listAttributes)
402 function(items, listAttributes)
394 listAttributes = listAttributes or {1, M.DefaultStyle, M.DefaultDelim}
403 listAttributes = listAttributes or {1, M.DefaultStyle, M.DefaultDelim}
395− return {c = {listAttributes, List:new(items)}}
404+ return {c = {listAttributes, ensureList(items)}}
396 end,
405 end,
397 {{"start", "style", "delimiter"}, "content"}
406 {{"start", "style", "delimiter"}, "content"}
398)
407)
@@ -468,7 +477,7 @@ M.Inline = AstElement:make_subtype'Inline'
468M.Cite = M.Inline:create_constructor(
477M.Cite = M.Inline:create_constructor(
469 "Cite",
478 "Cite",
470 function(content, citations)
479 function(content, citations)
471− return {c = {List:new(citations), ensureInlineList(content)}}
480+ return {c = {ensureList(citations), ensureInlineList(content)}}
472 end,
481 end,
473 {"citations", "content"}
482 {"citations", "content"}
474)
483)
@@ -572,7 +581,7 @@ M.InlineMath = M.Inline:create_constructor(
572-- @tparam {Block,...} content footnote block content
581-- @tparam {Block,...} content footnote block content
573M.Note = M.Inline:create_constructor(
582M.Note = M.Inline:create_constructor(
574 "Note",
583 "Note",
575− function(content) return {c = List:new(content)} end,
584+ function(content) return {c = ensureList(content)} end,
576 "content"
585 "content"
577)
586)
578
587
@@ -806,7 +815,7 @@ end
806M.Attr = AstElement:make_subtype'Attr'
815M.Attr = AstElement:make_subtype'Attr'
807function M.Attr:new (identifier, classes, attributes)
816function M.Attr:new (identifier, classes, attributes)
808 identifier = identifier or ''
817 identifier = identifier or ''
809− classes = List:new(classes or {})
818+ classes = ensureList(classes or {})
810 attributes = setmetatable(to_alist(attributes or {}), AttributeList)
819 attributes = setmetatable(to_alist(attributes or {}), AttributeList)
811 return {identifier, classes, attributes}
820 return {identifier, classes, attributes}
812end
821end
@@ -838,8 +847,8 @@ function M.Citation:new (id, mode, prefix, suffix, note_num, hash)
838 return {
847 return {
839 id = id,
848 id = id,
840 mode = mode,
849 mode = mode,
841− prefix = prefix or {},
850+ prefix = ensureList(prefix or {}),
842− suffix = suffix or {},
851+ suffix = ensureList(suffix or {}),
843 note_num = note_num or 0,
852 note_num = note_num or 0,
844 hash = hash or 0,
853 hash = hash or 0,
845 }
854 }
test/Tests/Lua.hs+14−4
@@ -12,8 +12,8 @@ import Text.Pandoc.Builder (bulletList, divWith, doc, doubleQuoted, emph,
12 header, linebreak, para, plain, rawBlock,
12 header, linebreak, para, plain, rawBlock,
13 singleQuoted, space, str, strong, (<>))
13 singleQuoted, space, str, strong, (<>))
14import Text.Pandoc.Class (runIOorExplode, setUserDataDir)
14import Text.Pandoc.Class (runIOorExplode, setUserDataDir)
15−import Text.Pandoc.Definition (Block, Inline (Emph, Str), Meta, Pandoc,
15+import Text.Pandoc.Definition (Block (BlockQuote, Para), Inline (Emph, Str),
16− pandocTypesVersion)
16+ Meta, Pandoc, pandocTypesVersion)
17import Text.Pandoc.Lua (runLuaFilter, runPandocLua)
17import Text.Pandoc.Lua (runLuaFilter, runPandocLua)
18import Text.Pandoc.Options (def)
18import Text.Pandoc.Options (def)
19import Text.Pandoc.Shared (pandocVersion)
19import Text.Pandoc.Shared (pandocVersion)
@@ -126,8 +126,18 @@ tests = map (localOption (QuickCheckTests 20))
126 =<< Lua.peek Lua.stackTop
126 =<< Lua.peek Lua.stackTop
127
127
128 , testCase "Allow singleton inline in constructors" . runPandocLua' $ do
128 , testCase "Allow singleton inline in constructors" . runPandocLua' $ do
129− res <- Lua.callFunc "pandoc.Emph" (Str "test")
130− Lua.liftIO $ assertEqual "Not the exptected Emph" (Emph [Str "test"]) res
129+ Lua.liftIO . assertEqual "Not the exptected Emph" (Emph [Str "test"])
130+ =<< Lua.callFunc "pandoc.Emph" (Str "test")
131+ Lua.liftIO . assertEqual "Unexpected element" (Para [Str "test"])
132+ =<< Lua.callFunc "pandoc.Para" ("test" :: String)
133+ Lua.liftIO . assertEqual "Unexptected element"
134+ (BlockQuote [Para [Str "foo"]]) =<< (
135+ do
136+ Lua.getglobal' "pandoc.BlockQuote"
137+ Lua.push (Para [Str "foo"])
138+ _ <- Lua.call 1 1
139+ Lua.peek Lua.stackTop
140+ )
131
141
132 , testCase "informative error messages" . runPandocLua' $ do
142 , testCase "informative error messages" . runPandocLua' $ do
133 Lua.pushboolean True
143 Lua.pushboolean True