2017-11-29 01:20:01 +01:00
|
|
|
|
--[[
|
|
|
|
|
List.lua
|
|
|
|
|
|
2020-01-10 20:13:06 +01:00
|
|
|
|
Copyright © 2017–2020 Albert Krewinkel
|
2017-11-29 01:20:01 +01:00
|
|
|
|
|
2020-01-10 20:13:06 +01:00
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
|
|
|
copyright notice and this permission notice appear in all copies.
|
2017-11-29 01:20:01 +01:00
|
|
|
|
|
2020-01-10 20:13:06 +01:00
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ]]
|
2017-11-29 01:20:01 +01:00
|
|
|
|
|
2017-12-01 17:12:56 +01:00
|
|
|
|
--- Pandoc's List type and helper methods
|
|
|
|
|
-- @classmod pandoc.List
|
2017-11-29 01:20:01 +01:00
|
|
|
|
-- @author Albert Krewinkel
|
2020-01-10 20:13:06 +01:00
|
|
|
|
-- @copyright © 2017–2020 Albert Krewinkel
|
2017-11-29 01:20:01 +01:00
|
|
|
|
-- @license MIT
|
2017-11-29 21:10:45 +01:00
|
|
|
|
local List = {
|
2020-01-10 20:13:06 +01:00
|
|
|
|
_VERSION = "1.0.0"
|
2017-11-29 21:10:45 +01:00
|
|
|
|
}
|
2017-11-29 01:20:01 +01:00
|
|
|
|
|
|
|
|
|
function List:new (o)
|
|
|
|
|
o = o or {}
|
|
|
|
|
setmetatable(o, self)
|
|
|
|
|
self.__index = self
|
|
|
|
|
return o
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Concatenates two lists.
|
2017-12-01 17:12:56 +01:00
|
|
|
|
-- @param list second list concatenated to the first
|
|
|
|
|
-- @return a new list containing all elements from list1 and list2
|
2017-11-29 01:20:01 +01:00
|
|
|
|
function List:__concat (list)
|
|
|
|
|
local res = List.clone(self)
|
|
|
|
|
List.extend(res, list)
|
|
|
|
|
return res
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Returns a (shallow) copy of the list.
|
|
|
|
|
function List:clone ()
|
|
|
|
|
local lst = setmetatable({}, getmetatable(self))
|
|
|
|
|
List.extend(lst, self)
|
|
|
|
|
return lst
|
|
|
|
|
end
|
|
|
|
|
|
2017-12-01 17:12:56 +01:00
|
|
|
|
--- Checks if the list has an item equal to the given needle.
|
|
|
|
|
-- @param needle item to search for
|
|
|
|
|
-- @param init index at which the search is started
|
|
|
|
|
-- @return true if a list item is equal to the needle, false otherwise
|
|
|
|
|
function List:includes (needle, init)
|
|
|
|
|
return not (List.find(self, needle, init) == nil)
|
2017-11-29 01:20:01 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Returns the value and index of the first occurrence of the given item.
|
|
|
|
|
-- @param needle item to search for
|
2017-12-01 17:12:56 +01:00
|
|
|
|
-- @param init index at which the search is started
|
2017-11-29 01:20:01 +01:00
|
|
|
|
-- @return first item equal to the needle, or nil if no such item exists.
|
|
|
|
|
-- @return index of that element
|
|
|
|
|
function List:find (needle, init)
|
|
|
|
|
return List.find_if(self, function(x) return x == needle end, init)
|
|
|
|
|
end
|
|
|
|
|
|
2017-12-01 17:12:56 +01:00
|
|
|
|
--- Returns the value and index of the first element for which the predicate
|
|
|
|
|
--- holds true.
|
|
|
|
|
-- @param pred the predicate function
|
2017-11-29 01:20:01 +01:00
|
|
|
|
-- @param init index at which the search is started
|
|
|
|
|
-- @return first item for which `test` succeeds, or nil if no such item exists.
|
|
|
|
|
-- @return index of that element
|
2017-12-01 17:12:56 +01:00
|
|
|
|
function List:find_if (pred, init)
|
2017-11-29 01:20:01 +01:00
|
|
|
|
init = (init == nil and 1) or (init < 0 and #self - init) or init
|
|
|
|
|
for i = init, #self do
|
2017-12-01 17:12:56 +01:00
|
|
|
|
if pred(self[i], i) then
|
2017-11-29 01:20:01 +01:00
|
|
|
|
return self[i], i
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return nil
|
|
|
|
|
end
|
|
|
|
|
|
2017-12-01 17:12:56 +01:00
|
|
|
|
--- Adds the given list to the end of this list.
|
2017-11-29 01:20:01 +01:00
|
|
|
|
-- @param list list to appended
|
|
|
|
|
function List:extend (list)
|
|
|
|
|
for i = 1, #list do
|
|
|
|
|
self[#self + 1] = list[i]
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2017-12-01 17:12:56 +01:00
|
|
|
|
--- Returns a copy of the current list by applying the given function to all
|
2017-11-29 01:20:01 +01:00
|
|
|
|
-- elements.
|
2017-12-01 17:12:56 +01:00
|
|
|
|
-- @param fn function which is applied to all list items.
|
2017-11-29 01:20:01 +01:00
|
|
|
|
function List:map (fn)
|
|
|
|
|
local res = setmetatable({}, getmetatable(self))
|
|
|
|
|
for i = 1, #self do
|
2017-12-01 17:12:56 +01:00
|
|
|
|
res[i] = fn(self[i], i)
|
|
|
|
|
end
|
|
|
|
|
return res
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--- Returns a new list containing all items satisfying a given condition.
|
|
|
|
|
-- @param pred condition items must satisfy.
|
|
|
|
|
-- @return a new list containing all items for which `test` was true.
|
|
|
|
|
function List:filter (pred)
|
|
|
|
|
local res = setmetatable({}, getmetatable(self))
|
|
|
|
|
for i = 1, #self do
|
|
|
|
|
if pred(self[i], i) then
|
|
|
|
|
res[#res + 1] = self[i]
|
|
|
|
|
end
|
2017-11-29 01:20:01 +01:00
|
|
|
|
end
|
|
|
|
|
return res
|
|
|
|
|
end
|
|
|
|
|
|
2020-01-10 20:13:06 +01:00
|
|
|
|
-- Set metatable with __call metamethod. This allows the use of `List`
|
|
|
|
|
-- as a constructor function.
|
|
|
|
|
local ListMT = {
|
|
|
|
|
__call = List.new
|
|
|
|
|
}
|
|
|
|
|
setmetatable(List, ListMT)
|
|
|
|
|
|
2017-11-29 01:20:01 +01:00
|
|
|
|
return List
|