From a3dded3935997b73335240b2e1afd8fb219ee49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Mon, 29 Apr 2024 23:23:15 +0200 Subject: [PATCH] [api] allow text event data grouping by tag --- anselme/ast/Choice.lua | 15 +++++++----- anselme/ast/Text.lua | 39 ++++++++++++++++++++++++++--- anselme/ast/abstract/Event.lua | 8 +----- anselme/lib/class.lua | 8 +++--- test/results/text grouping.ans | 45 ++++++++++++++++++++++++++++++++++ test/run.lua | 9 +++++-- test/tests/text grouping.ans | 39 +++++++++++++++++++++++++++++ 7 files changed, 140 insertions(+), 23 deletions(-) create mode 100644 test/results/text grouping.ans create mode 100644 test/tests/text grouping.ans diff --git a/anselme/ast/Choice.lua b/anselme/ast/Choice.lua index c089a1e..82f6907 100644 --- a/anselme/ast/Choice.lua +++ b/anselme/ast/Choice.lua @@ -1,9 +1,17 @@ +local class = require("anselme.lib.class") local ast = require("anselme.ast") local ArgumentTuple local Event = ast.abstract.Event local operator_priority = require("anselme.common").operator_priority +local ChoiceEventData = class { + _selected = nil, + choose = function(self, choice) + self._selected = choice + end +} + local Choice Choice = ast.abstract.Runtime(Event) { type = "choice", @@ -26,12 +34,7 @@ Choice = ast.abstract.Runtime(Event) { end, build_event_data = function(self, state, event_buffer) - local l = { - _selected = nil, - choose = function(self, choice) - self._selected = choice - end - } + local l = ChoiceEventData:new() for _, c in event_buffer:iter(state) do table.insert(l, c.text) end diff --git a/anselme/ast/Text.lua b/anselme/ast/Text.lua index eb7329e..4599290 100644 --- a/anselme/ast/Text.lua +++ b/anselme/ast/Text.lua @@ -1,11 +1,38 @@ +local class = require("anselme.lib.class") local ast = require("anselme.ast") local Event, Runtime = ast.abstract.Event, ast.abstract.Runtime local ArgumentTuple +local to_anselme = require("anselme.common.to_anselme") + +local TextEventData +TextEventData = class { + -- returns a list of TextEventData where the first element of each text of each TextEventData has the same value for the tag tag_name + group_by = function(self, tag_name) + local l = {} + local current_group + local tag_key = to_anselme(tag_name) + local last_value + for _, event in ipairs(self) do + local list = event.list + if #list > 0 then + local value = list[1][2]:get_strict(tag_key) + if (not current_group) or (last_value == nil and value) or (last_value and value == nil) or (last_value and value and last_value:hash() ~= value:hash()) then -- new group + current_group = TextEventData:new() + table.insert(l, current_group) + last_value = value + end + table.insert(current_group, event) -- add to current group + end + end + return l + end, +} + local Text = Runtime(Event) { type = "text", - list = nil, -- { { String, tag Table }, ... } + list = nil, -- { { String, tag Struct }, ... } init = function(self) self.list = {} @@ -36,9 +63,13 @@ local Text = Runtime(Event) { -- Text comes from TextInterpolation which already evals the contents - to_event_data = function(self) - return self - end + build_event_data = function(self, state, event_buffer) + local l = TextEventData:new() + for _, event in event_buffer:iter(state) do + table.insert(l, event) + end + return l + end, } package.loaded[...] = Text diff --git a/anselme/ast/abstract/Event.lua b/anselme/ast/abstract/Event.lua index d837ff6..068d0f8 100644 --- a/anselme/ast/abstract/Event.lua +++ b/anselme/ast/abstract/Event.lua @@ -7,15 +7,9 @@ return ast.abstract.Node { init = false, -- returns value that will be yielded by the whole event buffer data on flush - -- by default a list of what is returned by :to_event_data for each event of the buffer build_event_data = function(self, state, event_buffer) - local l = {} - for _, event in event_buffer:iter(state) do - table.insert(l, event:to_event_data(state)) - end - return l + error("build_event_data not implemented for "..self.type) end, - to_event_data = function(self, state) error("unimplemented") end, -- post_flush_callback(self, state, event_buffer, event_data) post_flush_callback = false diff --git a/anselme/lib/class.lua b/anselme/lib/class.lua index 80ff0e3..e6aa342 100644 --- a/anselme/lib/class.lua +++ b/anselme/lib/class.lua @@ -3,7 +3,7 @@ -- -- usage: -- --- local class = require("anselme.lib.class") +-- local class = require("class") -- local Vehicle = class { -- type = "vehicle", -- class name, optional -- @@ -28,7 +28,7 @@ -- local car = Car:new("red") -- instancing -- print(car:is_stable(), car.color) -- true, "red" -- --- the default class returned by require("anselme.lib.class") contains a few other default methods that will be inherited by all subclasses +-- the default class returned by require("class") contains a few other default methods that will be inherited by all subclasses -- see line 99 and further for details & documentation -- -- design philosophy: @@ -70,9 +70,9 @@ local function add_to_set(set, val) end --# class creation logic #-- -local class_mt +local new_class, class_mt -local function new_class(...) +new_class = function(...) local class = {} local include = {...} for i=1, #include do diff --git a/test/results/text grouping.ans b/test/results/text grouping.ans new file mode 100644 index 0000000..e7d451d --- /dev/null +++ b/test/results/text grouping.ans @@ -0,0 +1,45 @@ +--# run #-- +--- text --- +| {}"A" | +| {}"A" | +| {}"A" | +--- text --- +| {"group":1}"B" | +| {"group":1}"B" | +| {"group":1}"B" | +--- text --- +:: group :: +| {"group":1}"C" | +| {"group":1}"C" | +:: group :: +| {"group":3}"D" | +--- text --- +:: group :: +| {"group":1}"E" | +:: group :: +| {"group":"j"}"F" | +:: group :: +| {"group":1}"G" | +--- text --- +:: group :: +| {"group":1}"H" | +:: group :: +| {}"I" | +:: group :: +| {"group":1}"J" | +--- text --- +:: group :: +| {"group":1}"K" | +:: group :: +| {}"L" | +| {"not group":1}"L" | +--- text --- +:: group :: +| {}"M" | +:: group :: +| {"group":"j"}"N" | +| {"group":"j"}"N" | +--- return --- +() +--# saved #-- +{} \ No newline at end of file diff --git a/test/run.lua b/test/run.lua index 4c64e84..9181220 100644 --- a/test/run.lua +++ b/test/run.lua @@ -33,8 +33,13 @@ local function run_loop(run_state, write_output, interactive) local e, data = run_state:step() write_output("--- "..e.." ---") if e == "text" then - for _, l in ipairs(data) do - write_output(l:format(run_state)) + local grouped = data:group_by("group") + local groups = #grouped > 1 + for _, v in ipairs(grouped) do + if groups then write_output(":: group ::") end + for _, l in ipairs(v) do + write_output(l:format(run_state)) + end end elseif e == "choice" then local choice diff --git a/test/tests/text grouping.ans b/test/tests/text grouping.ans new file mode 100644 index 0000000..3de00c3 --- /dev/null +++ b/test/tests/text grouping.ans @@ -0,0 +1,39 @@ +| A +| A +| A + +"group": 1 # + | B + | B + | B + +"group": 1 # + | C +"group": 1 # + | C +"group": 3 # + | D + +"group": 1 # + | E +"group": "j" # + | F +"group": 1 # + | G + +"group": 1 # + | H +| I +"group": 1 # + | J + +"group": 1 # + | K +| L +"not group": 1 # + | L + +| M +"group": "j" # + | N + | N