Skip to content

Commit 318d47e

Browse files
committed
feat(asciidoc): Added ordered & unordered list item support
1 parent 69226e4 commit 318d47e

6 files changed

Lines changed: 258 additions & 0 deletions

File tree

lua/markview/config/asciidoc.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ return {
4747
},
4848

4949
tocs = {
50+
enable = true,
51+
5052
shift_width = 2,
5153
hl = "MarkviewPalette2Fg",
5254

@@ -84,4 +86,35 @@ return {
8486
hl = "MarkviewPalette5Fg",
8587
},
8688
},
89+
90+
list_items = {
91+
enable = true,
92+
shift_width = 4,
93+
94+
marker_dot = {
95+
add_padding = true,
96+
conceal_on_checkboxes = true,
97+
98+
text = function (_, item)
99+
return string.format("%d.", item.n);
100+
end,
101+
hl = "@markup.list.markdown",
102+
},
103+
104+
marker_minus = {
105+
add_padding = true,
106+
conceal_on_checkboxes = true,
107+
108+
text = "",
109+
hl = "MarkviewListItemMinus"
110+
},
111+
112+
marker_star = {
113+
add_padding = true,
114+
conceal_on_checkboxes = true,
115+
116+
text = "",
117+
hl = "MarkviewListItemStar"
118+
},
119+
},
87120
};

lua/markview/parsers/asciidoc.lua

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,99 @@ asciidoc.toc = function (_, _, text, range)
148148
});
149149
end
150150

151+
---@param buffer integer
152+
---@param now string Current marker.
153+
---@param last TSNode
154+
---@return boolean
155+
local function is_on_same_level(buffer, now, last)
156+
local _marker = last:child(0);
157+
158+
if not _marker then
159+
return false;
160+
end
161+
162+
local marker = vim.treesitter.get_node_text(_marker, buffer, {});
163+
return marker == now;
164+
end
165+
166+
---@param buffer integer
167+
---@param TSNode TSNode
168+
---@param text string[]
169+
---@param range markview.parsed.asciidoc.list_items.range
170+
asciidoc.unordered_list_item = function (buffer, TSNode, text, range)
171+
local _marker = TSNode:child(0);
172+
173+
if not _marker then
174+
return;
175+
end
176+
177+
local N = 1;
178+
local prev = TSNode:prev_named_sibling();
179+
180+
local marker = vim.treesitter.get_node_text(_marker, buffer, {});
181+
_, _, _, range.marker_end = _marker:range();
182+
183+
while prev do
184+
if prev:type() == "unordered_list_item" then
185+
if is_on_same_level(buffer, marker, prev) then
186+
N = N + 1;
187+
else
188+
break;
189+
end
190+
end
191+
192+
prev = prev:prev_named_sibling();
193+
end
194+
195+
asciidoc.insert({
196+
class = "asciidoc_list_item",
197+
marker = marker,
198+
n = N,
199+
200+
text = text,
201+
range = range
202+
});
203+
end
204+
205+
---@param buffer integer
206+
---@param TSNode TSNode
207+
---@param text string[]
208+
---@param range markview.parsed.asciidoc.list_items.range
209+
asciidoc.ordered_list_item = function (buffer, TSNode, text, range)
210+
local _marker = TSNode:child(0);
211+
212+
if not _marker then
213+
return;
214+
end
215+
216+
local N = 1;
217+
local prev = TSNode:prev_named_sibling();
218+
219+
local marker = vim.treesitter.get_node_text(_marker, buffer, {});
220+
_, _, _, range.marker_end = _marker:range();
221+
222+
while prev do
223+
if prev:type() == "ordered_list_item" then
224+
if is_on_same_level(buffer, marker, prev) then
225+
N = N + 1;
226+
else
227+
break;
228+
end
229+
end
230+
231+
prev = prev:prev_named_sibling();
232+
end
233+
234+
asciidoc.insert({
235+
class = "asciidoc_list_item",
236+
marker = marker,
237+
n = N,
238+
239+
text = text,
240+
range = range
241+
});
242+
end
243+
151244
--- HTML parser
152245
---@param buffer integer
153246
---@param TSTree table
@@ -178,6 +271,9 @@ asciidoc.parse = function (buffer, TSTree, from, to)
178271
(block_macro_name) @toc_pos_name
179272
(#eq? @toc_pos_name "toc")
180273
)) @asciidoc.toc_pos
274+
275+
(unordered_list_item) @asciidoc.unordered_list_item
276+
(ordered_list_item) @asciidoc.ordered_list_item
181277
]]);
182278

183279
if not can_scan then

lua/markview/renderers/asciidoc.lua

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,61 @@ asciidoc.document_title = function (buffer, item)
5050
});
5151
end
5252

53+
--- Renders atx headings.
54+
---@param buffer integer
55+
---@param item markview.parsed.asciidoc.list_items
56+
asciidoc.list_item = function (buffer, item)
57+
---@type markview.config.asciidoc.list_items?
58+
local main_config = spec.get({ "asciidoc", "list_items" }, { fallback = nil, eval_args = { buffer, item } });
59+
60+
if not main_config then
61+
return;
62+
end
63+
64+
---@type markview.config.asciidoc.list_items.opts?
65+
local config;
66+
67+
if string.match(item.marker, "%*") then
68+
config = spec.get({ "marker_star" }, { source = main_config, eval_args = { buffer, item } });
69+
elseif string.match(item.marker, "%-") then
70+
config = spec.get({ "marker_minus" }, { source = main_config, eval_args = { buffer, item } });
71+
else
72+
config = spec.get({ "marker_dot" }, { source = main_config, eval_args = { buffer, item } });
73+
end
74+
75+
if not config then
76+
return;
77+
end
78+
79+
---@cast config markview.config.asciidoc.list_items.opts
80+
81+
local shift_width = main_config.shift_width or 2;
82+
local range = item.range;
83+
84+
for r = range.row_start, range.row_end - 1, 1 do
85+
if r == range.row_start then
86+
87+
utils.set_extmark(buffer, asciidoc.ns, r, range.col_start, {
88+
end_col = range.marker_end,
89+
conceal = "",
90+
91+
virt_text = {
92+
{ config.add_padding and string.rep(" ", #item.marker * shift_width) or "" },
93+
{ config.text or "", config.hl },
94+
},
95+
hl_mode = "combine",
96+
});
97+
elseif config.add_padding then
98+
utils.set_extmark(buffer, asciidoc.ns, r, 0, {
99+
virt_text = {
100+
{ string.rep(" ", #item.marker * shift_width) },
101+
},
102+
hl_mode = "combine",
103+
});
104+
end
105+
end
106+
end
107+
53108
--- Renders atx headings.
54109
---@param buffer integer
55110
---@param item markview.parsed.asciidoc.section_titles

lua/markview/types/parsers/asciidoc.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,28 @@
2020

2121
------------------------------------------------------------------------------
2222

23+
---@class markview.parsed.asciidoc.list_items
24+
---
25+
---@field class "asciidoc_list_item"
26+
---@field marker string List item marker.
27+
---@field n integer Item index.
28+
---
29+
---@field text string[]
30+
---@field range markview.parsed.asciidoc.list_items.range
31+
32+
33+
---@class markview.parsed.asciidoc.list_items.range
34+
---
35+
---@field row_start integer
36+
---@field col_start integer
37+
---
38+
---@field row_end integer
39+
---@field col_end integer
40+
---
41+
---@field marker_end integer End column for the list item marker(e.g. `*` or `.`).
42+
43+
------------------------------------------------------------------------------
44+
2345
---@class markview.parsed.asciidoc.section_titles
2446
---
2547
---@field class "asciidoc_section_title"
@@ -56,15 +78,19 @@
5678
---@alias markview.parsed.asciidoc
5779
---| markview.parsed.asciidoc.document_attributes
5880
---| markview.parsed.asciidoc.document_titles
81+
---| markview.parsed.asciidoc.list_items
5982
---| markview.parsed.asciidoc.section_titles
83+
---| markview.parsed.asciidoc.tocs
6084

6185
------------------------------------------------------------------------------
6286

6387
---@class markview.parsed.asciidoc_sorted
6488
---
6589
---@field document_attributes markview.parsed.asciidoc.document_attributes[]
6690
---@field document_titles markview.parsed.asciidoc.document_titles[]
91+
---@field list_items markview.parsed.asciidoc.list_items[]
6792
---@field section_titles markview.parsed.asciidoc.section_titles[]
93+
---@field tocs markview.parsed.asciidoc.tocs[]
6894

6995
------------------------------------------------------------------------------
7096

lua/markview/types/renderers/asciidoc.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,33 @@
2222

2323
------------------------------------------------------------------------------
2424

25+
--- Configuration for list items.
26+
---@class markview.config.asciidoc.list_items
27+
---
28+
---@field enable boolean
29+
---@field shift_width integer | fun(buffer: integer, item: markview.parsed.markdown.list_items): integer Virtual indentation size for previewed list items.
30+
---
31+
---@field marker_dot markview.config.asciidoc.list_items.opts Configuration for `.` list items.
32+
---@field marker_minus markview.config.asciidoc.list_items.opts Configuration for `-` list items.
33+
---@field marker_star markview.config.asciidoc.list_items.opts Configuration for `*` list items.
34+
---
35+
---@field wrap? boolean Enables wrap support.
36+
37+
38+
---@class markview.config.asciidoc.list_items.opts
39+
---
40+
---@field add_padding boolean
41+
---@field conceal_on_checkboxes? boolean
42+
---@field enable? boolean
43+
---@field hl? string
44+
---
45+
---[[ Text used to replace the list item marker. ]]
46+
---@field text?
47+
---| string
48+
---| fun(buffer: integer, item: markview.parsed.asciidoc.list_items): string
49+
50+
------------------------------------------------------------------------------
51+
2552
---@class markview.config.asciidoc.section_titles
2653
---
2754
---@field enable boolean
@@ -80,5 +107,7 @@
80107
---
81108
---@field document_attributes markview.config.asciidoc.document_attributes
82109
---@field document_titles markview.config.asciidoc.document_titles
110+
---@field list_items markview.config.asciidoc.list_items
83111
---@field section_titles markview.config.asciidoc.section_titles
112+
---@field tocs markview.config.asciidoc.tocs
84113

test/asciidoc.adoc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,22 @@ devel@discuss.example.org
6262
mailto:devel@discuss.example.org[Discuss]
6363

6464
mailto:join@discuss.example.org[Subscribe,Subscribe me,I want to join!]
65+
66+
* List item
67+
+
68+
Hello
69+
70+
* Bye
71+
** Nested list item
72+
*** Deeper nested list item
73+
* List item
74+
*** Another nested list item
75+
* List item
76+
77+
. Hi
78+
.. Hello
79+
.. Bye
80+
. Bye
81+
.. bye
82+
.. hi
83+

0 commit comments

Comments
 (0)