Lua filters: test AST object equality via Haskell

Equality of Lua objects representing pandoc AST elements is tested by
unmarshalling the objects and comparing the result in Haskell. A new
function `equals` which performs this test has been added to the
`pandoc.utils` module.

Closes: #5092
This commit is contained in:
Albert Krewinkel 2018-11-19 21:36:02 +01:00
parent e80bcb9bea
commit c0d8b0abcb
No known key found for this signature in database
GPG key ID: 388DC0B21F631124
3 changed files with 66 additions and 5 deletions

View file

@ -25,6 +25,7 @@ THIS SOFTWARE.
local M = {}
local List = require 'pandoc.List'
local utils = require 'pandoc.utils'
------------------------------------------------------------------------
-- Accessor objects
@ -119,6 +120,7 @@ local function create_accessor_behavior (tag, accessors)
'function (x, v) x.c%s = v end',
accessors
)
behavior.__eq = utils.equals
behavior.__index = function(t, k)
if getmetatable(t).getters[k] then
return getmetatable(t).getters[k](t)
@ -873,6 +875,7 @@ function M.Attr:new (identifier, classes, attributes)
return {identifier, classes, attributes}
end
M.Attr.behavior._field_names = {identifier = 1, classes = 2, attributes = 3}
M.Attr.behavior.__eq = utils.equals
M.Attr.behavior.__index = function(t, k)
return rawget(t, getmetatable(t)._field_names[k]) or
getmetatable(t)[k]
@ -931,6 +934,7 @@ function M.ListAttributes:new (start, style, delimiter)
return {start, style, delimiter}
end
M.ListAttributes.behavior._field_names = {start = 1, style = 2, delimiter = 3}
M.ListAttributes.behavior.__eq = utils.equals
M.ListAttributes.behavior.__index = function (t, k)
return rawget(t, getmetatable(t)._field_names[k]) or
getmetatable(t)[k]
@ -1033,7 +1037,6 @@ M.UpperAlpha = "UpperAlpha"
------------------------------------------------------------------------
-- Functions which have moved to different modules
local utils = require 'pandoc.utils'
M.sha1 = utils.sha1
return M

View file

@ -171,7 +171,7 @@ variables.
: The name used to involve the filter. This value can be used
to find files relative to the script file. This variable is
also set in custom writers.
`PANDOC_STATE`
: The state shared by all readers and writers. It is used by
pandoc to collect and pass information. The value of this
@ -641,6 +641,9 @@ to create these objects.
Pandoc document
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
`blocks`
: document content ([List] of [Block]s)
@ -653,10 +656,16 @@ Pandoc document
Meta information on a document; string-indexed collection of
[MetaValue]s.
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
## MetaValue {#type-ref-MetaValue}
Document meta information items.
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
### MetaBlocks {#type-ref-MetaBlocks}
A list of blocks usable as meta value ([List] of [Block]s)
@ -707,6 +716,9 @@ Plain Lua string value (string)
## Block {#type-ref-Block}
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
### BlockQuote {#type-ref-BlockQuote}
A block quote element
@ -926,6 +938,9 @@ centered).
## Inline {#type-ref-Inline}
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
### Cite {#type-ref-Cite}
Citation
@ -1166,6 +1181,9 @@ Superscripted text
A set of element attributes
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
`identifier`
: element identifier (string)
@ -1184,6 +1202,9 @@ indices to the list table.
Single citation entry
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
`id`
: citation identifier, e.g., a bibtex key (string)
@ -1206,6 +1227,9 @@ Single citation entry
### ListAttributes {#type-ref-ListAttributes}
List attributes
Object equality is determined via
[`pandoc.utils.equals`](#utils-equals).
`start`
: number of the first list item (integer)
@ -2202,6 +2226,28 @@ functions.
-- pandoc.Emph{ pandoc.Str 'Paragraph2' }
-- }
[`equals (element1, element2)`]{#utils-equals}
: Test equality of AST elements. Elements in Lua are considered
equal if and only if the objects obtained by unmarshaling are
equal.
Parameters:
`element1`, `element2`:
: Objects to be compared. Acceptable input types are
[Pandoc](#type-ref-pandoc), [Meta](#type-ref-meta),
[MetaValue](#type-ref-MetaValue),
[Block](#type-ref-Block), [Inline](#type-ref-Inline),
[Attr](#type-ref-Attr),
[ListAttributes](#type-ref-ListAttributes), and
[Citation](#type-ref-Citation).
Returns:
- Whether the two objects represent the same element
(boolean)
[`hierarchicalize (blocks)`]{#utils-hierarchicalize}
: Convert list of blocks into an hierarchical list. An

View file

@ -1,3 +1,4 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-
Copyright © 2017-2018 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
@ -15,7 +16,6 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-}
{-# LANGUAGE NoImplicitPrelude #-}
{- |
Module : Text.Pandoc.Lua.Module.Utils
Copyright : Copyright © 2017-2018 Albert Krewinkel
@ -36,7 +36,8 @@ import Data.Char (toLower)
import Data.Default (def)
import Foreign.Lua (Peekable, Lua, NumResults)
import Text.Pandoc.Class (runIO, setUserDataDir)
import Text.Pandoc.Definition (Pandoc, Meta, MetaValue (..), Block, Inline)
import Text.Pandoc.Definition ( Pandoc, Meta, MetaValue (..), Block, Inline
, Citation, Attr, ListAttributes)
import Text.Pandoc.Lua.StackInstances ()
import Text.Pandoc.Lua.Util (addFunction)
@ -52,6 +53,7 @@ pushModule :: Maybe FilePath -> Lua NumResults
pushModule mbDatadir = do
Lua.newtable
addFunction "blocks_to_inlines" blocksToInlines
addFunction "equals" equals
addFunction "hierarchicalize" hierarchicalize
addFunction "normalize_date" normalizeDate
addFunction "run_json_filter" (runJSONFilter mbDatadir)
@ -112,7 +114,9 @@ stringify el = return $ case el of
InlineElement i -> Shared.stringify i
BlockElement b -> Shared.stringify b
MetaElement m -> Shared.stringify m
CitationElement c -> Shared.stringify c
MetaValueElement m -> stringifyMetaValue m
_ -> ""
stringifyMetaValue :: MetaValue -> String
stringifyMetaValue mv = case mv of
@ -120,19 +124,27 @@ stringifyMetaValue mv = case mv of
MetaString s -> s
_ -> Shared.stringify mv
equals :: AstElement -> AstElement -> Lua Bool
equals e1 e2 = return (e1 == e2)
data AstElement
= PandocElement Pandoc
| MetaElement Meta
| BlockElement Block
| InlineElement Inline
| MetaValueElement MetaValue
deriving (Show)
| AttrElement Attr
| ListAttributesElement ListAttributes
| CitationElement Citation
deriving (Eq, Show)
instance Peekable AstElement where
peek idx = do
res <- Lua.try $ (PandocElement <$> Lua.peek idx)
<|> (InlineElement <$> Lua.peek idx)
<|> (BlockElement <$> Lua.peek idx)
<|> (AttrElement <$> Lua.peek idx)
<|> (ListAttributesElement <$> Lua.peek idx)
<|> (MetaElement <$> Lua.peek idx)
<|> (MetaValueElement <$> Lua.peek idx)
case res of