git.iko.soy/typeable/pandoc
on master help sign in
Lua: add a `clone()` method to all AST elements (#5572)

Closes: #5568

commit11bb8627677fb8b49af92d7c55aec07c69f95843 authorAlbert Krewinkel <albert@zeitkraut.de> dateWed 12 Jun 2019, 18:58 (7 years ago) parentd81b9f5
5 files changed+112−1
data/pandoc.lua+9 doc/lua-filters.md+15 src/Text/Pandoc/Lua/Marshaling/AST.hs+4−1 src/Text/Pandoc/Lua/Module/Types.hs+46 test/lua/module/pandoc.lua+38
data/pandoc.lua+9
@@ -28,6 +28,7 @@ local M = {}
2828M.List = require 'pandoc.List'
2929M.mediabag = require 'pandoc.mediabag'
3030M.system = require 'pandoc.system'
31+M.types = require 'pandoc.types'
3132M.utils = require 'pandoc.utils'
3233M.text = require 'text'
3334
@@ -280,6 +281,7 @@ end
280281-- @tparam {Block,...} blocks document content
281282-- @tparam[opt] Meta meta document meta data
282283M.Pandoc = AstElement:make_subtype'Pandoc'
284+M.Pandoc.behavior.clone = M.types.clone.Pandoc
283285function M.Pandoc:new (blocks, meta)
284286 return {
285287 blocks = ensureList(blocks),
@@ -299,6 +301,7 @@ M.Doc = M.Pandoc
299301-- @function Meta
300302-- @tparam meta table table containing document meta information
301303M.Meta = AstElement:make_subtype'Meta'
304+M.Meta.behavior.clone = M.types.clone.Meta
302305function M.Meta:new (meta) return meta end
303306
304307
@@ -306,6 +309,7 @@ function M.Meta:new (meta) return meta end
306309-- MetaValue
307310-- @section MetaValue
308311M.MetaValue = AstElement:make_subtype('MetaValue')
312+M.MetaValue.behavior.clone = M.types.clone.MetaValue
309313
310314--- Meta blocks
311315-- @function MetaBlocks
@@ -369,6 +373,7 @@ end
369373
370374--- Block elements
371375M.Block = AstElement:make_subtype'Block'
376+M.Block.behavior.clone = M.types.clone.Block
372377
373378--- Creates a block quote element
374379-- @function BlockQuote
@@ -542,6 +547,7 @@ M.Table = M.Block:create_constructor(
542547
543548--- Inline element class
544549M.Inline = AstElement:make_subtype'Inline'
550+M.Inline.behavior.clone = M.types.clone.Inline
545551
546552--- Creates a Cite inline element
547553-- @function Cite
@@ -898,6 +904,7 @@ function M.Attr:new (identifier, classes, attributes)
898904 attributes = setmetatable(to_alist(attributes or {}), AttributeList)
899905 return {identifier, classes, attributes}
900906end
907+M.Attr.behavior.clone = M.types.clone.Attr
901908M.Attr.behavior._field_names = {identifier = 1, classes = 2, attributes = 3}
902909M.Attr.behavior.__eq = utils.equals
903910M.Attr.behavior.__index = function(t, k)
@@ -922,6 +929,7 @@ end
922929
923930-- Citation
924931M.Citation = AstElement:make_subtype'Citation'
932+M.Citation.behavior.clone = M.types.clone.Citation
925933
926934--- Creates a single citation.
927935-- @function Citation
@@ -944,6 +952,7 @@ end
944952
945953-- ListAttributes
946954M.ListAttributes = AstElement:make_subtype 'ListAttributes'
955+M.ListAttributes.behavior.clone = M.types.clone.ListAttributes
947956
948957--- Creates a set of list attributes.
949958-- @function ListAttributes
doc/lua-filters.md+15
@@ -644,6 +644,20 @@ This section describes the types of objects available to Lua
644644filters. See the [pandoc module](#module-pandoc}) for functions
645645to create these objects.
646646
647+## Shared Properties
648+
649+### `clone`
650+
651+`clone ()`
652+
653+All instances of the types listed here, with the exception of
654+read-only objects, can be cloned via the `clone()` method.
655+
656+Usage:
657+
658+ local emph = pandoc.Emph {pandoc.Str 'important'}
659+ local cloned_emph = emph:clone() -- note the colon
660+
647661## Pandoc {#type-ref-pandoc}
648662
649663Pandoc document
@@ -1247,6 +1261,7 @@ Object equality is determined via
12471261: delimiter of list numbers; one of `DefaultDelim`, `Period`,
12481262 `OneParen`, and `TwoParens` (string)
12491263
1264+
12501265## Hierarchical Element {#type-ref-Element}
12511266
12521267Hierarchical elements can be either *Sec* (sections) or *Blk*
src/Text/Pandoc/Lua/Marshaling/AST.hs+4−1
@@ -14,7 +14,10 @@
1414
1515Marshaling/unmarshaling instances for document AST elements.
1616-}
17−module Text.Pandoc.Lua.Marshaling.AST () where
17+module Text.Pandoc.Lua.Marshaling.AST
18+ ( LuaAttr (..)
19+ , LuaListAttributes (..)
20+ ) where
1821
1922import Prelude
2023import Control.Applicative ((<|>))
src/Text/Pandoc/Lua/Module/Types.hs+46
@@ -15,8 +15,11 @@ module Text.Pandoc.Lua.Module.Types
1515import Prelude
1616import Data.Version (Version)
1717import Foreign.Lua (Lua, NumResults)
18+import Text.Pandoc.Definition
19+import Text.Pandoc.Lua.Marshaling.AST (LuaAttr, LuaListAttributes)
1820import Text.Pandoc.Lua.Marshaling.Version ()
1921import Text.Pandoc.Lua.Util (addFunction)
22+import Text.Pandoc.Shared (Element (..))
2023
2124import qualified Foreign.Lua as Lua
2225
@@ -25,4 +28,47 @@ pushModule :: Lua NumResults
2528pushModule = do
2629 Lua.newtable
2730 addFunction "Version" (return :: Version -> Lua Version)
31+ pushCloneTable
32+ Lua.setfield (Lua.nthFromTop 2) "clone"
2833 return 1
34+
35+pushCloneTable :: Lua NumResults
36+pushCloneTable = do
37+ Lua.newtable
38+ addFunction "Attr" cloneAttr
39+ addFunction "Block" cloneBlock
40+ addFunction "Citation" cloneCitation
41+ addFunction "Element" cloneElement
42+ addFunction "Inline" cloneInline
43+ addFunction "Meta" cloneMeta
44+ addFunction "MetaValue" cloneMetaValue
45+ addFunction "ListAttributes" cloneListAttributes
46+ addFunction "Pandoc" clonePandoc
47+ return 1
48+
49+cloneAttr :: LuaAttr -> Lua LuaAttr
50+cloneAttr = return
51+
52+cloneBlock :: Block -> Lua Block
53+cloneBlock = return
54+
55+cloneCitation :: Citation -> Lua Citation
56+cloneCitation = return
57+
58+cloneElement :: Element -> Lua Element
59+cloneElement = return
60+
61+cloneInline :: Inline -> Lua Inline
62+cloneInline = return
63+
64+cloneListAttributes :: LuaListAttributes -> Lua LuaListAttributes
65+cloneListAttributes = return
66+
67+cloneMeta :: Meta -> Lua Meta
68+cloneMeta = return
69+
70+cloneMetaValue :: MetaValue -> Lua MetaValue
71+cloneMetaValue = return
72+
73+clonePandoc :: Pandoc -> Lua Pandoc
74+clonePandoc = return
test/lua/module/pandoc.lua+38
@@ -87,6 +87,44 @@ return {
8787 end)
8888 },
8989 },
90+
91+ group 'clone' {
92+ test('clones Attr', function ()
93+ local attr = pandoc.Attr('test', {'my-class'}, {foo = 'bar'})
94+ local cloned = attr:clone()
95+ attr.identifier = ''
96+ attr.classes = {}
97+ attr.attributes = {}
98+ assert.are_same(cloned.identifier, 'test')
99+ assert.are_same(cloned.classes, {'my-class'})
100+ assert.are_same(cloned.attributes.foo, 'bar')
101+ end),
102+ test('clones ListAttributes', function ()
103+ local la = pandoc.ListAttributes(2, pandoc.DefaultStyle, pandoc.Period)
104+ local cloned = la:clone()
105+ la.start = 9
106+ assert.are_same(cloned.start, 2)
107+ end),
108+ test('clones Para', function ()
109+ local para = pandoc.Para {pandoc.Str 'Hello'}
110+ local cloned = para:clone()
111+ para.content[1].text = 'bye'
112+ assert.are_same(cloned, pandoc.Para {pandoc.Str 'Hello'})
113+ end),
114+ test('clones Str', function ()
115+ local str = pandoc.Str 'Hello'
116+ local cloned = str:clone()
117+ str.text = 'bye'
118+ assert.are_same(cloned.text, 'Hello')
119+ end),
120+ test('clones Citation', function ()
121+ local cite = pandoc.Citation('leibniz', pandoc.AuthorInText)
122+ local cloned = cite:clone()
123+ cite.id = 'newton'
124+ assert.are_same(cloned.id, 'leibniz')
125+ end),
126+ },
127+
90128 group 'pipe' {
91129 test('external string processing', function ()
92130 if os_is_windows() then