11--- HTML parser for `markview.nvim`.
22local asciidoc = {};
33
4- asciidoc .data = {
5- document_title = nil ,
6- };
4+ --- @type markview.parser.asciidoc.data
5+ asciidoc .data = {};
76
87--- Queried contents
98--- @type table[]
@@ -25,9 +24,32 @@ asciidoc.insert = function (data)
2524 table.insert (asciidoc .sorted [data .class ], data );
2625end
2726
27+ --- @param buffer integer
28+ --- @param TSNode TSNode
2829--- @param text string[]
2930--- @param range markview.parsed.range
30- asciidoc .doc_attr = function (_ , _ , text , range )
31+ asciidoc .doc_attr = function (buffer , TSNode , text , range )
32+ local _name = TSNode :named_child (1 ) --[[ @as TSNode]] ;
33+ local name = vim .treesitter .get_node_text (_name , buffer , {});
34+
35+ local _value = TSNode :named_child (3 );
36+
37+ if name == " toc" then
38+ return ;
39+ elseif name == " toc-title" and _value then
40+ asciidoc .data .toc_title = vim .treesitter .get_node_text (_value , buffer , {});
41+ elseif name == " toclevels" and _value then
42+ asciidoc .data .toc_max_depth = math.max (
43+ math.min (
44+ tonumber (
45+ vim .treesitter .get_node_text (_value , buffer , {})
46+ ) or 0 ,
47+ 5
48+ ),
49+ 0
50+ );
51+ end
52+
3153 asciidoc .insert ({
3254 class = " asciidoc_document_attribute" ,
3355
5476--- @param text string[]
5577--- @param range markview.parsed.range
5678asciidoc .section_title = function (buffer , TSNode , text , range )
57- local marker = TSNode :child (0 );
79+ local _marker = TSNode :child (0 );
5880
59- if not marker then
81+ if not _marker then
6082 return ;
6183 end
6284
85+ local marker = vim .treesitter .get_node_text (_marker , buffer , {});
86+ local prev = TSNode :prev_named_sibling ();
87+
88+ if prev then
89+ local prev_text = vim .treesitter .get_node_text (prev , buffer , {});
90+
91+ if prev :type () == " element_attr" and prev_text == " [discrete]" then
92+ goto dont_add_to_toc ;
93+ end
94+ end
95+
96+ if not asciidoc .data .toc_entries then
97+ asciidoc .data .toc_entries = {};
98+ end
99+
100+ table.insert (asciidoc .data .toc_entries , {
101+ depth = (# marker or 1 ) - 1 ,
102+ text = string.gsub (text [1 ] or " " , " ^[=%s]+" , " " ),
103+
104+ range = vim .deepcopy (range , true ),
105+ } --[[ @as markview.parser.asciidoc.data.toc_entry]] );
106+
107+ :: dont_add_to_toc::
108+
63109 asciidoc .insert ({
64110 class = " asciidoc_section_title" ,
65- marker = vim .treesitter .get_node_text (marker , buffer , {}),
111+ marker = marker ,
112+
113+ text = text ,
114+ range = range
115+ });
116+ end
117+
118+ --- @param range markview.parsed.range
119+ asciidoc .toc_pos = function (_ , _ , _ , range )
120+ asciidoc .data .toc_pos = range ;
121+ end
122+
123+ --- @param text string[]
124+ --- @param range markview.parsed.range
125+ asciidoc .toc = function (_ , _ , text , range )
126+ local validated = {};
127+
128+ for _ , entry in ipairs (asciidoc .data .toc_entries or {}) do
129+ if entry .depth < (asciidoc .data .toc_max_depth or 5 ) then
130+ table.insert (validated , entry );
131+ end
132+ end
133+
134+ range .position = asciidoc .data .toc_pos ;
135+
136+ asciidoc .insert ({
137+ class = " asciidoc_toc" ,
138+
139+ title = asciidoc .data .toc_title ,
140+ max_depth = asciidoc .data .toc_max_depth ,
141+ entries = validated ,
66142
67143 text = text ,
68144 range = range
@@ -92,6 +168,12 @@ asciidoc.parse = function (buffer, TSTree, from, to)
92168 (title4)
93169 (title5)
94170 ] @asciidoc.section_title
171+
172+ (block_macro
173+ (
174+ (block_macro_name) @toc_pos_name
175+ (#eq? @toc_pos_name "toc")
176+ )) @asciidoc.toc_pos
95177 ]] );
96178
97179 if not can_scan then
@@ -109,61 +191,92 @@ asciidoc.parse = function (buffer, TSTree, from, to)
109191 return asciidoc .content , asciidoc .sorted ;
110192 end
111193
112- for capture_id , capture_node , _ , _ in scanned_queries : iter_captures ( TSTree : root (), buffer , from , to ) do
113- local capture_name = scanned_queries . captures [ capture_id ];
194+ local function iter ( queries )
195+ --- | fS
114196
115- if not capture_name :match (" ^asciidoc%." ) then
116- goto continue ;
117- end
197+ for capture_id , capture_node , _ , _ in queries :iter_captures (TSTree :root (), buffer , from , to ) do
198+ local capture_name = queries .captures [capture_id ];
118199
119- --- @type string ?
120- local capture_text = vim . treesitter . get_node_text ( capture_node , buffer ) ;
121- local r_start , c_start , r_end , c_end = capture_node : range ();
200+ if not capture_name : match ( " ^asciidoc%. " ) then
201+ goto continue ;
202+ end
122203
123- if capture_text == nil then
124- goto continue ;
125- end
204+ --- @type string ?
205+ local capture_text = vim . treesitter . get_node_text ( capture_node , buffer ) ;
206+ local r_start , c_start , r_end , c_end = capture_node : range ();
126207
127- if not capture_text : match ( " \n $ " ) then
128- capture_text = capture_text .. " \n " ;
129- end
208+ if capture_text == nil then
209+ goto continue ;
210+ end
130211
131- local lines = {};
212+ if not capture_text :match (" \n $" ) then
213+ capture_text = capture_text .. " \n " ;
214+ end
132215
133- for line in capture_text :gmatch (" (.-)\n " ) do
134- table.insert (lines , line );
135- end
216+ local lines = {};
136217
137- --- @type boolean , string
138- local success , error = pcall (
139- asciidoc [ capture_name : gsub ( " ^asciidoc%. " , " " )],
218+ for line in capture_text : gmatch ( " (.-) \n " ) do
219+ table.insert ( lines , line );
220+ end
140221
141- buffer ,
142- capture_node ,
143- lines ,
144- {
145- row_start = r_start ,
146- col_start = c_start ,
222+ --- @type boolean , string
223+ local success , error = pcall (
224+ asciidoc [capture_name :gsub (" ^asciidoc%." , " " )],
147225
148- row_end = r_end ,
149- col_end = c_end
150- }
151- );
226+ buffer ,
227+ capture_node ,
228+ lines ,
229+ {
230+ row_start = r_start ,
231+ col_start = c_start ,
152232
153- if success == false then
154- require (" markview.health" ).print ({
155- kind = " ERR" ,
233+ row_end = r_end ,
234+ col_end = c_end
235+ }
236+ );
156237
157- from = " parsers/asciidoc.lua" ,
158- fn = " parse()" ,
238+ if success == false then
239+ require (" markview.health" ).print ({
240+ kind = " ERR" ,
159241
160- message = {
161- { tostring (error ), " DiagnosticError" }
162- }
163- });
242+ from = " parsers/asciidoc.lua" ,
243+ fn = " parse()" ,
244+
245+ message = {
246+ { tostring (error ), " DiagnosticError" }
247+ }
248+ });
249+ end
250+
251+ :: continue::
164252 end
165253
166- :: continue::
254+ --- | fE
255+ end
256+
257+ iter (scanned_queries );
258+
259+ local can_scan_tquery , scanned_tqueries = pcall (vim .treesitter .query .parse , " asciidoc" , [[
260+ (document_attr
261+ (
262+ (attr_name) @toc_attr
263+ (#eq? @toc_attr "toc")
264+ )) @asciidoc.toc
265+ ]] );
266+
267+ if not can_scan_tquery then
268+ require (" markview.health" ).print ({
269+ kind = " ERR" ,
270+
271+ from = " parsers/asciidoc.lua" ,
272+ fn = " parse() -> toc_query" ,
273+
274+ message = {
275+ { tostring (error ), " DiagnosticError" }
276+ }
277+ });
278+ else
279+ iter (scanned_tqueries );
167280 end
168281
169282 return asciidoc .content , asciidoc .sorted ;
0 commit comments