aboutsummaryrefslogtreecommitdiff
path: root/data/pandoc.lua
diff options
context:
space:
mode:
authorAlbert Krewinkel <albert@zeitkraut.de>2018-10-20 15:06:16 +0200
committerAlbert Krewinkel <albert@zeitkraut.de>2018-10-20 19:14:17 +0200
commit916db81ade8049ae417350b88bbe08e1a4018c79 (patch)
treefb7f11df9d37e2f0bcfd09dd740b084b19e9d8f7 /data/pandoc.lua
parent8d4027da4dc698cdb13d143bc542977391f4b49b (diff)
downloadpandoc-916db81ade8049ae417350b88bbe08e1a4018c79.tar.gz
Lua filters: iterate over AST element fields when using `pairs`
This makes it possible to iterate over all field names of an AST element by using a generic `for` loop with `pairs`: for field_name, field_content in pairs(element) do … end Raw table fields of AST elements should be considered an implementation detail and might change in the future. Accessing element properties should always happen through the fields listed in the Lua filter docs. Note that the iterator currently excludes the `t`/`tag` field.
Diffstat (limited to 'data/pandoc.lua')
-rw-r--r--data/pandoc.lua58
1 files changed, 58 insertions, 0 deletions
diff --git a/data/pandoc.lua b/data/pandoc.lua
index 370c6a944..e69f8ac9c 100644
--- a/data/pandoc.lua
+++ b/data/pandoc.lua
@@ -73,6 +73,39 @@ local function create_accessor_functions (fn_template, accessors)
return res
end
+--- Get list of top-level fields from field descriptor table.
+-- E.g.: `top_level_fields{'foo', {bar='baz'}, {'qux', 'quux'}}`
+-- gives {'foo, 'bar', 'qux', 'quux'}
+-- @local
+local function top_level_fields (fields)
+ local result = List:new{}
+ for _, v in ipairs(fields) do
+ if type(v) == 'string' then
+ table.insert(result, v)
+ elseif type(v) == 'table' and #v == 0 and next(v) then
+ table.insert(result, (next(v)))
+ else
+ result:extend(top_level_fields(v))
+ end
+ end
+ return result
+end
+
+--- Creates a function which behaves like next, but respects field names.
+-- @local
+local function make_next_function (fields)
+ local field_indices = {}
+ for i, f in ipairs(fields) do
+ field_indices[f] = i
+ end
+
+ return function (t, field)
+ local raw_idx = field == nil and 0 or field_indices[field]
+ local next_field = fields[raw_idx + 1]
+ return next_field, t[next_field]
+ end
+end
+
--- Create a new table which allows to access numerical indices via accessor
-- functions.
-- @local
@@ -102,6 +135,15 @@ local function create_accessor_behavior (tag, accessors)
rawset(t, k, v)
end
end
+ behavior.__pairs = function (t)
+ if accessors == nil then
+ return next, t
+ end
+ local iterable_fields = type(accessors) == 'string'
+ and {accessors}
+ or top_level_fields(accessors)
+ return make_next_function(iterable_fields), t
+ end
return behavior
end
@@ -842,6 +884,14 @@ M.Attr.behavior.__newindex = function(t, k, v)
rawset(t, k, v)
end
end
+M.Attr.behavior.__pairs = function(t)
+ local field_names = M.Attr.behavior._field_names
+ local fields = {}
+ for name, i in pairs(field_names) do
+ fields[i] = name
+ end
+ return make_next_function(fields), t, nil
+end
-- Citation
M.Citation = AstElement:make_subtype'Citation'
@@ -892,6 +942,14 @@ M.ListAttributes.behavior.__newindex = function (t, k, v)
rawset(t, k, v)
end
end
+M.ListAttributes.behavior.__pairs = function(t)
+ local field_names = M.ListAttributes.behavior._field_names
+ local fields = {}
+ for name, i in pairs(field_names) do
+ fields[i] = name
+ end
+ return make_next_function(fields), t, nil
+end
------------------------------------------------------------------------