Skip to content

Commit f90293d

Browse files
authored
feat: add ---@toc (Table of Contents) generation (#25)
1 parent bca0954 commit f90293d

File tree

7 files changed

+185
-12
lines changed

7 files changed

+185
-12
lines changed

emmylua.md

+101-6
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ Following are the tags that you can use to create docs
1111

1212
A `brief` can be used to describe a module or even to add some footnote etc.
1313

14+
- Syntax
15+
1416
```lua
1517
---@brief [[
1618
---@comment
1719
---@brief ]]
1820
```
1921

22+
- Input
23+
2024
```lua
2125
---@brief [[
2226
---Any summary you wanted to write you can write here.
@@ -73,12 +77,19 @@ NOTE: remember there is no formatting or text wrapping
7377

7478
This can be used to add a heading for the module and change the prefix of every exported _function and type_.
7579

76-
> NOTE: This can appear multiple times in a file but only the last `---@mod` will be used to rename prefixes.
80+
> NOTE:
81+
>
82+
> 1. This can appear multiple times in a file but only the last `---@mod` will be used to rename prefixes.
83+
> 2. Also adds a entries in the [`Table of Contents`](#table-of-contents)
84+
85+
- Syntax
7786

7887
```lua
7988
---@mod <name> [desc]
8089
```
8190

91+
- Input
92+
8293
```lua
8394
---@mod mod.intro Introduction
8495
---@brief [[
@@ -181,15 +192,71 @@ U:create() *mod.Human:create*
181192
<
182193
```
183194

195+
### Table of Contents
196+
197+
Following tag can be used to generate a _Table of Contents_ section. It uses [`---@mod`](#module) tags for the entries.
198+
199+
- Syntax
200+
201+
```lua
202+
---@toc <tag>
203+
```
204+
205+
- Input
206+
207+
```lua
208+
---@toc my-plugin.contents
209+
210+
---@mod first.module First Module
211+
212+
---@mod second.module Second Module
213+
214+
---@mod third.module Third Module
215+
216+
local U = {}
217+
218+
return U
219+
```
220+
221+
- Output
222+
223+
```help
224+
================================================================================
225+
Table of Contents *my-plugin.contents*
226+
227+
First Module······················································|first.module|
228+
Second Module····················································|second.module|
229+
Third Module······················································|third.module|
230+
231+
================================================================================
232+
First Module *first.module*
233+
234+
================================================================================
235+
Second Module *second.module*
236+
237+
================================================================================
238+
Third Module *third.module*
239+
```
240+
184241
### Tag
185242

186243
This can used to create an alternate tag for your module, functions etc.
187244

245+
- Syntax
246+
247+
```lua
248+
---@tag <name>
249+
```
250+
251+
- Input
252+
188253
```lua
189254
---@tag cool-tag
190255
---@tag another-cool-tag
191256
```
192257

258+
- Output
259+
193260
```
194261
*cool-tag*
195262
*another-cool-tag*
@@ -199,10 +266,14 @@ This can used to create an alternate tag for your module, functions etc.
199266

200267
This tag can be used to add a divider/separator between section or anything you desire
201268

269+
- Syntax
270+
202271
```lua
203272
---@divider <char>
204273
```
205274

275+
- Input
276+
206277
```lua
207278
---@divider -
208279
---@divider =
@@ -223,17 +294,21 @@ This tag can be used to add a divider/separator between section or anything you
223294

224295
A function contains multiple tags which form its structure. Like `---@param` for parameter, `---@return` for the return value, `---@see` for other related things and `---@usage` for example
225296

297+
- Syntax
298+
226299
```lua
227300
---@comment
228-
---@param <name> <type> <desc>
301+
---@param <name> <type> [desc]
229302
---@comment
230-
---@return <type> <name> <desc>
303+
---@return <type> [name] [desc]
231304
---@see <ref>
232305
---@usage `<code>`
233306
```
234307

235308
> NOTE: All tag can be used multiple times except `---@usage`
236309
310+
- Input
311+
237312
```lua
238313
local U = {}
239314

@@ -324,15 +399,19 @@ U.magical({this}, {that}) *U.magical*
324399

325400
Classes can be used to better structure your code and can be referenced as an argument to a function or it's return value. You can define it once and use it multiple times.
326401

402+
- Syntax
403+
327404
```lua
328-
---@class <name> <desc>
405+
---@class <name> [desc]
329406
---@comment
330-
---@field [public|protected|private] <name> <type> <desc>
407+
---@field [public|protected|private] <name> <type> [desc]
331408
---@see <ref>
332409
```
333410

334411
> NOTE: `---@field` and `---@see` can be used multiple times
335412
413+
- Input
414+
336415
```lua
337416
local H = {}
338417

@@ -390,12 +469,16 @@ H:create() *H:create*
390469

391470
You can use `---@type` to document static objects, constants etc.
392471

472+
- Syntax
473+
393474
```lua
394475
---@comment
395-
---@type <type> <desc>
476+
---@type <type> [desc]
396477
---@usage `<code>`
397478
```
398479

480+
- Input
481+
399482
```lua
400483
local U = {}
401484

@@ -444,6 +527,14 @@ U.chai *U.chai*
444527

445528
This can be used to make a type alias. It is helpful if you are using the same the type multiple times.
446529

530+
- Syntax
531+
532+
```lua
533+
---@alias <name> <type> [desc]
534+
```
535+
536+
- Input
537+
447538
```lua
448539
local U = {}
449540

@@ -479,6 +570,8 @@ U.get_all() *U.get_all*
479570

480571
You can also define a (pseudo) enum using [`---@alias`](#alias).
481572

573+
- Input
574+
482575
```lua
483576
local U = {}
484577

@@ -524,6 +617,8 @@ U.VMODE *U.VMODE*
524617

525618
You can use `---@private` tag to discard any part of the code that is exported but it is not considered to be a part of the public API
526619

620+
- Input
621+
527622
```lua
528623
local U = {}
529624

src/parser/emmy.rs

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub enum Scope {
1717

1818
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1919
pub enum TagType {
20+
Toc(String),
2021
Module {
2122
name: String,
2223
desc: Option<String>,
@@ -137,6 +138,10 @@ impl Emmy {
137138

138139
let tag = just('@').ignore_then(choice((
139140
private.to(TagType::Skip),
141+
just("toc")
142+
.then_ignore(whitespace())
143+
.ignore_then(comment.clone())
144+
.map(TagType::Toc),
140145
just("mod")
141146
.then_ignore(whitespace())
142147
.ignore_then(ty)

src/parser/mod.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,32 @@ impl LemmyHelp {
120120
impl Display for LemmyHelp {
121121
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122122
for node in &self.nodes {
123-
writeln!(f, "{}", node)?;
123+
if let Node::Toc(x) = node {
124+
writeln!(
125+
f,
126+
"{}",
127+
Module {
128+
name: x.to_string(),
129+
desc: Some("Table of Contents".into())
130+
}
131+
)?;
132+
133+
for nodde in &self.nodes {
134+
if let Node::Module(x) = nodde {
135+
let desc = x.desc.as_deref().unwrap_or_default();
136+
137+
writeln!(
138+
f,
139+
"{desc}{}",
140+
format_args!("{:·>w$}", format!("|{}|", x.name), w = 80 - desc.len())
141+
)?;
142+
}
143+
}
144+
145+
writeln!(f)?;
146+
} else {
147+
writeln!(f, "{node}")?;
148+
}
124149
}
125150

126151
Ok(())

src/parser/node.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub enum Node {
1818
Alias(Alias),
1919
Type(Type),
2020
Export(String),
21+
Toc(String),
2122
}
2223

2324
parser!(Node, Option<Self>, {
@@ -30,11 +31,13 @@ parser!(Node, Option<Self>, {
3031
Class::parse().map(Self::Class),
3132
Alias::parse().map(Self::Alias),
3233
Type::parse().map(Self::Type),
33-
// We need this to match exported types/funcs etc.
34-
select! { TagType::Export(x) => Self::Export(x) },
34+
select! {
35+
TagType::Export(x) => Self::Export(x),
36+
TagType::Toc(x) => Self::Toc(x),
37+
},
3538
))
3639
.map(Some)
37-
// This will skip useless nodes
40+
// Skip useless nodes
3841
.or(any().to(None))
3942
});
4043

tests/basic.rs

+43
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,49 @@ U:create() *mod.Human:create*
378378
)
379379
}
380380

381+
#[test]
382+
fn table_of_contents() {
383+
let src = "
384+
---@toc my-plugin.contents
385+
386+
---@mod first.module First Module
387+
388+
---@mod second.module Second Module
389+
390+
---@mod third.module Third Module
391+
392+
local U = {}
393+
394+
return U
395+
";
396+
397+
let mut lemmy = LemmyHelp::default();
398+
399+
lemmy.for_help(src).unwrap();
400+
401+
assert_eq!(
402+
lemmy.to_string(),
403+
"\
404+
================================================================================
405+
Table of Contents *my-plugin.contents*
406+
407+
First Module······················································|first.module|
408+
Second Module····················································|second.module|
409+
Third Module······················································|third.module|
410+
411+
================================================================================
412+
First Module *first.module*
413+
414+
================================================================================
415+
Second Module *second.module*
416+
417+
================================================================================
418+
Third Module *third.module*
419+
420+
"
421+
);
422+
}
423+
381424
#[test]
382425
fn alias_and_type() {
383426
let src = r#"

tests/test.lua

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
---
1919
---@brief ]]
2020

21+
---@toc test.contents
22+
2123
---@mod awesome.name Awesome module title
2224

2325
local U = {}

todo.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
[x] enum via @alias
1818
[ ] also support string as an entry alongside path
1919
[x] long names
20-
[-] Non-Standard tags (should not interfere with LSP)
20+
[x] Non-Standard tags (should not interfere with LSP)
2121
[x] ---@module <tag> <description>
2222
(override the tagged name prefix like *U.comment* -> *comment-comment*)
2323
[x] ---@divider <char>
2424
[x] ---@private
25-
[ ] ---@toc-entry & ---@toc-slot
25+
[x] ---@toc <tag>
2626
[ ] Error handling
2727

2828
## Dropped

0 commit comments

Comments
 (0)