data/pandoc.lua: accept single block as singleton list

Every constructor which accepts a list of blocks now also accepts a
single block element for convenience.  Furthermore, strings are accepted as
shorthand for `{pandoc.Str "text"}` in constructors.
This commit is contained in:
Albert Krewinkel 2018-01-13 22:29:16 +01:00
parent e5e69e68c9
commit e0cb0dab18
No known key found for this signature in database
GPG key ID: 388DC0B21F631124
2 changed files with 43 additions and 24 deletions

View file

@ -186,15 +186,24 @@ function AstElement:create_constructor(tag, fn, accessors)
return constr return constr
end end
--- Ensure a given object is an Inline element, or convert it into one. --- Convert AstElement input into a list if necessary.
local function ensureInlineList (x) -- @local
if type(x) == string then local function ensureList (x)
return List:new{M.Str(x)} if x.tag then
elseif x.tag then
-- Lists are not tagged, but all elements are -- Lists are not tagged, but all elements are
return List:new{x} return List:new{x}
else else
return x return List:new(x)
end
end
--- Ensure a given object is an Inline element, or convert it into one.
-- @local
local function ensureInlineList (x)
if type(x) == 'string' then
return List:new{M.Str(x)}
else
return ensureList(x)
end end
end end
@ -209,7 +218,7 @@ end
M.Pandoc = AstElement:make_subtype'Pandoc' M.Pandoc = AstElement:make_subtype'Pandoc'
function M.Pandoc:new (blocks, meta) function M.Pandoc:new (blocks, meta)
return { return {
blocks = List:new(blocks), blocks = ensureList(blocks),
meta = meta or {}, meta = meta or {},
} }
end end
@ -239,7 +248,7 @@ M.MetaValue = AstElement:make_subtype('MetaValue')
-- @tparam {Block,...} blocks blocks -- @tparam {Block,...} blocks blocks
M.MetaBlocks = M.MetaValue:create_constructor( M.MetaBlocks = M.MetaValue:create_constructor(
'MetaBlocks', 'MetaBlocks',
function (content) return List:new(content) end function (content) return ensureList(content) end
) )
--- Meta inlines --- Meta inlines
@ -255,7 +264,7 @@ M.MetaInlines = M.MetaValue:create_constructor(
-- @tparam {MetaValue,...} meta_values list of meta values -- @tparam {MetaValue,...} meta_values list of meta values
M.MetaList = M.MetaValue:create_constructor( M.MetaList = M.MetaValue:create_constructor(
'MetaList', 'MetaList',
function (content) return List:new(content) end function (content) return ensureList(content) end
) )
--- Meta map --- Meta map
@ -295,7 +304,7 @@ M.Block = AstElement:make_subtype'Block'
-- @treturn Block block quote element -- @treturn Block block quote element
M.BlockQuote = M.Block:create_constructor( M.BlockQuote = M.Block:create_constructor(
"BlockQuote", "BlockQuote",
function(content) return {c = content} end, function(content) return {c = ensureList(content)} end,
"content" "content"
) )
@ -305,7 +314,7 @@ M.BlockQuote = M.Block:create_constructor(
-- @treturn Block bullet list element -- @treturn Block bullet list element
M.BulletList = M.Block:create_constructor( M.BulletList = M.Block:create_constructor(
"BulletList", "BulletList",
function(content) return {c = content} end, function(content) return {c = ensureList(content)} end,
"content" "content"
) )
@ -326,7 +335,7 @@ M.CodeBlock = M.Block:create_constructor(
-- @treturn Block definition list element -- @treturn Block definition list element
M.DefinitionList = M.Block:create_constructor( M.DefinitionList = M.Block:create_constructor(
"DefinitionList", "DefinitionList",
function(content) return {c = List:new(content)} end, function(content) return {c = ensureList(content)} end,
"content" "content"
) )
@ -338,7 +347,7 @@ M.DefinitionList = M.Block:create_constructor(
M.Div = M.Block:create_constructor( M.Div = M.Block:create_constructor(
"Div", "Div",
function(content, attr) function(content, attr)
return {c = {attr or M.Attr(), List:new(content)}} return {c = {attr or M.Attr(), ensureList(content)}}
end, end,
{{"identifier", "classes", "attributes"}, "content"} {{"identifier", "classes", "attributes"}, "content"}
) )
@ -371,7 +380,7 @@ M.HorizontalRule = M.Block:create_constructor(
-- @treturn Block line block element -- @treturn Block line block element
M.LineBlock = M.Block:create_constructor( M.LineBlock = M.Block:create_constructor(
"LineBlock", "LineBlock",
function(content) return {c = List:new(content)} end, function(content) return {c = ensureList(content)} end,
"content" "content"
) )
@ -392,7 +401,7 @@ M.OrderedList = M.Block:create_constructor(
"OrderedList", "OrderedList",
function(items, listAttributes) function(items, listAttributes)
listAttributes = listAttributes or {1, M.DefaultStyle, M.DefaultDelim} listAttributes = listAttributes or {1, M.DefaultStyle, M.DefaultDelim}
return {c = {listAttributes, List:new(items)}} return {c = {listAttributes, ensureList(items)}}
end, end,
{{"start", "style", "delimiter"}, "content"} {{"start", "style", "delimiter"}, "content"}
) )
@ -468,7 +477,7 @@ M.Inline = AstElement:make_subtype'Inline'
M.Cite = M.Inline:create_constructor( M.Cite = M.Inline:create_constructor(
"Cite", "Cite",
function(content, citations) function(content, citations)
return {c = {List:new(citations), ensureInlineList(content)}} return {c = {ensureList(citations), ensureInlineList(content)}}
end, end,
{"citations", "content"} {"citations", "content"}
) )
@ -572,7 +581,7 @@ M.InlineMath = M.Inline:create_constructor(
-- @tparam {Block,...} content footnote block content -- @tparam {Block,...} content footnote block content
M.Note = M.Inline:create_constructor( M.Note = M.Inline:create_constructor(
"Note", "Note",
function(content) return {c = List:new(content)} end, function(content) return {c = ensureList(content)} end,
"content" "content"
) )
@ -806,7 +815,7 @@ end
M.Attr = AstElement:make_subtype'Attr' M.Attr = AstElement:make_subtype'Attr'
function M.Attr:new (identifier, classes, attributes) function M.Attr:new (identifier, classes, attributes)
identifier = identifier or '' identifier = identifier or ''
classes = List:new(classes or {}) classes = ensureList(classes or {})
attributes = setmetatable(to_alist(attributes or {}), AttributeList) attributes = setmetatable(to_alist(attributes or {}), AttributeList)
return {identifier, classes, attributes} return {identifier, classes, attributes}
end end
@ -838,8 +847,8 @@ function M.Citation:new (id, mode, prefix, suffix, note_num, hash)
return { return {
id = id, id = id,
mode = mode, mode = mode,
prefix = prefix or {}, prefix = ensureList(prefix or {}),
suffix = suffix or {}, suffix = ensureList(suffix or {}),
note_num = note_num or 0, note_num = note_num or 0,
hash = hash or 0, hash = hash or 0,
} }

View file

@ -12,8 +12,8 @@ import Text.Pandoc.Builder (bulletList, divWith, doc, doubleQuoted, emph,
header, linebreak, para, plain, rawBlock, header, linebreak, para, plain, rawBlock,
singleQuoted, space, str, strong, (<>)) singleQuoted, space, str, strong, (<>))
import Text.Pandoc.Class (runIOorExplode, setUserDataDir) import Text.Pandoc.Class (runIOorExplode, setUserDataDir)
import Text.Pandoc.Definition (Block, Inline (Emph, Str), Meta, Pandoc, import Text.Pandoc.Definition (Block (BlockQuote, Para), Inline (Emph, Str),
pandocTypesVersion) Meta, Pandoc, pandocTypesVersion)
import Text.Pandoc.Lua (runLuaFilter, runPandocLua) import Text.Pandoc.Lua (runLuaFilter, runPandocLua)
import Text.Pandoc.Options (def) import Text.Pandoc.Options (def)
import Text.Pandoc.Shared (pandocVersion) import Text.Pandoc.Shared (pandocVersion)
@ -126,8 +126,18 @@ tests = map (localOption (QuickCheckTests 20))
=<< Lua.peek Lua.stackTop =<< Lua.peek Lua.stackTop
, testCase "Allow singleton inline in constructors" . runPandocLua' $ do , testCase "Allow singleton inline in constructors" . runPandocLua' $ do
res <- Lua.callFunc "pandoc.Emph" (Str "test") Lua.liftIO . assertEqual "Not the exptected Emph" (Emph [Str "test"])
Lua.liftIO $ assertEqual "Not the exptected Emph" (Emph [Str "test"]) res =<< Lua.callFunc "pandoc.Emph" (Str "test")
Lua.liftIO . assertEqual "Unexpected element" (Para [Str "test"])
=<< Lua.callFunc "pandoc.Para" ("test" :: String)
Lua.liftIO . assertEqual "Unexptected element"
(BlockQuote [Para [Str "foo"]]) =<< (
do
Lua.getglobal' "pandoc.BlockQuote"
Lua.push (Para [Str "foo"])
_ <- Lua.call 1 1
Lua.peek Lua.stackTop
)
, testCase "informative error messages" . runPandocLua' $ do , testCase "informative error messages" . runPandocLua' $ do
Lua.pushboolean True Lua.pushboolean True