aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Krewinkel <albert@zeitkraut.de>2019-06-12 18:58:38 +0200
committerJohn MacFarlane <jgm@berkeley.edu>2019-06-12 09:58:38 -0700
commit11bb8627677fb8b49af92d7c55aec07c69f95843 (patch)
tree3bd8a3ea839a94747b2cc41e78ef7f062c7489f9
parentd81b9f55c142f89db38edd44db999ef2de162a8d (diff)
downloadpandoc-11bb8627677fb8b49af92d7c55aec07c69f95843.tar.gz
Lua: add a `clone()` method to all AST elements (#5572)
Closes: #5568
-rw-r--r--data/pandoc.lua9
-rw-r--r--doc/lua-filters.md15
-rw-r--r--src/Text/Pandoc/Lua/Marshaling/AST.hs5
-rw-r--r--src/Text/Pandoc/Lua/Module/Types.hs46
-rw-r--r--test/lua/module/pandoc.lua38
5 files changed, 112 insertions, 1 deletions
diff --git a/data/pandoc.lua b/data/pandoc.lua
index 859ecedc4..97e75efca 100644
--- a/data/pandoc.lua
+++ b/data/pandoc.lua
@@ -28,6 +28,7 @@ local M = {}
M.List = require 'pandoc.List'
M.mediabag = require 'pandoc.mediabag'
M.system = require 'pandoc.system'
+M.types = require 'pandoc.types'
M.utils = require 'pandoc.utils'
M.text = require 'text'
@@ -280,6 +281,7 @@ end
-- @tparam {Block,...} blocks document content
-- @tparam[opt] Meta meta document meta data
M.Pandoc = AstElement:make_subtype'Pandoc'
+M.Pandoc.behavior.clone = M.types.clone.Pandoc
function M.Pandoc:new (blocks, meta)
return {
blocks = ensureList(blocks),
@@ -299,6 +301,7 @@ M.Doc = M.Pandoc
-- @function Meta
-- @tparam meta table table containing document meta information
M.Meta = AstElement:make_subtype'Meta'
+M.Meta.behavior.clone = M.types.clone.Meta
function M.Meta:new (meta) return meta end
@@ -306,6 +309,7 @@ function M.Meta:new (meta) return meta end
-- MetaValue
-- @section MetaValue
M.MetaValue = AstElement:make_subtype('MetaValue')
+M.MetaValue.behavior.clone = M.types.clone.MetaValue
--- Meta blocks
-- @function MetaBlocks
@@ -369,6 +373,7 @@ end
--- Block elements
M.Block = AstElement:make_subtype'Block'
+M.Block.behavior.clone = M.types.clone.Block
--- Creates a block quote element
-- @function BlockQuote
@@ -542,6 +547,7 @@ M.Table = M.Block:create_constructor(
--- Inline element class
M.Inline = AstElement:make_subtype'Inline'
+M.Inline.behavior.clone = M.types.clone.Inline
--- Creates a Cite inline element
-- @function Cite
@@ -898,6 +904,7 @@ function M.Attr:new (identifier, classes, attributes)
attributes = setmetatable(to_alist(attributes or {}), AttributeList)
return {identifier, classes, attributes}
end
+M.Attr.behavior.clone = M.types.clone.Attr
M.Attr.behavior._field_names = {identifier = 1, classes = 2, attributes = 3}
M.Attr.behavior.__eq = utils.equals
M.Attr.behavior.__index = function(t, k)
@@ -922,6 +929,7 @@ end
-- Citation
M.Citation = AstElement:make_subtype'Citation'
+M.Citation.behavior.clone = M.types.clone.Citation
--- Creates a single citation.
-- @function Citation
@@ -944,6 +952,7 @@ end
-- ListAttributes
M.ListAttributes = AstElement:make_subtype 'ListAttributes'
+M.ListAttributes.behavior.clone = M.types.clone.ListAttributes
--- Creates a set of list attributes.
-- @function ListAttributes
diff --git a/doc/lua-filters.md b/doc/lua-filters.md
index 3ac2a62d2..dadc9a2fc 100644
--- a/doc/lua-filters.md
+++ b/doc/lua-filters.md
@@ -644,6 +644,20 @@ This section describes the types of objects available to Lua
filters. See the [pandoc module](#module-pandoc}) for functions
to create these objects.
+## Shared Properties
+
+### `clone`
+
+`clone ()`
+
+All instances of the types listed here, with the exception of
+read-only objects, can be cloned via the `clone()` method.
+
+Usage:
+
+ local emph = pandoc.Emph {pandoc.Str 'important'}
+ local cloned_emph = emph:clone() -- note the colon
+
## Pandoc {#type-ref-pandoc}
Pandoc document
@@ -1247,6 +1261,7 @@ Object equality is determined via
: delimiter of list numbers; one of `DefaultDelim`, `Period`,
`OneParen`, and `TwoParens` (string)
+
## Hierarchical Element {#type-ref-Element}
Hierarchical elements can be either *Sec* (sections) or *Blk*
diff --git a/src/Text/Pandoc/Lua/Marshaling/AST.hs b/src/Text/Pandoc/Lua/Marshaling/AST.hs
index f18754ac2..7b428b5f0 100644
--- a/src/Text/Pandoc/Lua/Marshaling/AST.hs
+++ b/src/Text/Pandoc/Lua/Marshaling/AST.hs
@@ -14,7 +14,10 @@
Marshaling/unmarshaling instances for document AST elements.
-}
-module Text.Pandoc.Lua.Marshaling.AST () where
+module Text.Pandoc.Lua.Marshaling.AST
+ ( LuaAttr (..)
+ , LuaListAttributes (..)
+ ) where
import Prelude
import Control.Applicative ((<|>))
diff --git a/src/Text/Pandoc/Lua/Module/Types.hs b/src/Text/Pandoc/Lua/Module/Types.hs
index 641bde7d6..fdc63cd99 100644
--- a/src/Text/Pandoc/Lua/Module/Types.hs
+++ b/src/Text/Pandoc/Lua/Module/Types.hs
@@ -15,8 +15,11 @@ module Text.Pandoc.Lua.Module.Types
import Prelude
import Data.Version (Version)
import Foreign.Lua (Lua, NumResults)
+import Text.Pandoc.Definition
+import Text.Pandoc.Lua.Marshaling.AST (LuaAttr, LuaListAttributes)
import Text.Pandoc.Lua.Marshaling.Version ()
import Text.Pandoc.Lua.Util (addFunction)
+import Text.Pandoc.Shared (Element (..))
import qualified Foreign.Lua as Lua
@@ -25,4 +28,47 @@ pushModule :: Lua NumResults
pushModule = do
Lua.newtable
addFunction "Version" (return :: Version -> Lua Version)
+ pushCloneTable
+ Lua.setfield (Lua.nthFromTop 2) "clone"
return 1
+
+pushCloneTable :: Lua NumResults
+pushCloneTable = do
+ Lua.newtable
+ addFunction "Attr" cloneAttr
+ addFunction "Block" cloneBlock
+ addFunction "Citation" cloneCitation
+ addFunction "Element" cloneElement
+ addFunction "Inline" cloneInline
+ addFunction "Meta" cloneMeta
+ addFunction "MetaValue" cloneMetaValue
+ addFunction "ListAttributes" cloneListAttributes
+ addFunction "Pandoc" clonePandoc
+ return 1
+
+cloneAttr :: LuaAttr -> Lua LuaAttr
+cloneAttr = return
+
+cloneBlock :: Block -> Lua Block
+cloneBlock = return
+
+cloneCitation :: Citation -> Lua Citation
+cloneCitation = return
+
+cloneElement :: Element -> Lua Element
+cloneElement = return
+
+cloneInline :: Inline -> Lua Inline
+cloneInline = return
+
+cloneListAttributes :: LuaListAttributes -> Lua LuaListAttributes
+cloneListAttributes = return
+
+cloneMeta :: Meta -> Lua Meta
+cloneMeta = return
+
+cloneMetaValue :: MetaValue -> Lua MetaValue
+cloneMetaValue = return
+
+clonePandoc :: Pandoc -> Lua Pandoc
+clonePandoc = return
diff --git a/test/lua/module/pandoc.lua b/test/lua/module/pandoc.lua
index 1c02c8720..ca2168805 100644
--- a/test/lua/module/pandoc.lua
+++ b/test/lua/module/pandoc.lua
@@ -87,6 +87,44 @@ return {
end)
},
},
+
+ group 'clone' {
+ test('clones Attr', function ()
+ local attr = pandoc.Attr('test', {'my-class'}, {foo = 'bar'})
+ local cloned = attr:clone()
+ attr.identifier = ''
+ attr.classes = {}
+ attr.attributes = {}
+ assert.are_same(cloned.identifier, 'test')
+ assert.are_same(cloned.classes, {'my-class'})
+ assert.are_same(cloned.attributes.foo, 'bar')
+ end),
+ test('clones ListAttributes', function ()
+ local la = pandoc.ListAttributes(2, pandoc.DefaultStyle, pandoc.Period)
+ local cloned = la:clone()
+ la.start = 9
+ assert.are_same(cloned.start, 2)
+ end),
+ test('clones Para', function ()
+ local para = pandoc.Para {pandoc.Str 'Hello'}
+ local cloned = para:clone()
+ para.content[1].text = 'bye'
+ assert.are_same(cloned, pandoc.Para {pandoc.Str 'Hello'})
+ end),
+ test('clones Str', function ()
+ local str = pandoc.Str 'Hello'
+ local cloned = str:clone()
+ str.text = 'bye'
+ assert.are_same(cloned.text, 'Hello')
+ end),
+ test('clones Citation', function ()
+ local cite = pandoc.Citation('leibniz', pandoc.AuthorInText)
+ local cloned = cite:clone()
+ cite.id = 'newton'
+ assert.are_same(cloned.id, 'leibniz')
+ end),
+ },
+
group 'pipe' {
test('external string processing', function ()
if os_is_windows() then