Skip to content

Commit b4e1a80

Browse files
authored
Merge #162 feat: numbered listitems
2 parents 570dc10 + c3f5620 commit b4e1a80

File tree

10 files changed

+5224
-4542
lines changed

10 files changed

+5224
-4542
lines changed

README.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,27 @@ Overview
1414

1515
- `block` is the main top-level node, delimited by blank line(s) or any line
1616
starting with `<` (codeblock terminator).
17-
- contains `line` and `line_li` nodes.
17+
- Contains `line` and `line_li` nodes.
1818
- `line`:
19-
- contains atoms (words, tags, taglinks, …)
20-
- contains headings (`h1`, `h2`, `h3`, `column_heading`) because `codeblock`
19+
- Contains atoms (words, tags, taglinks, …)
20+
- Contains headings (`h1`, `h2`, `h3`, `column_heading`) because `codeblock`
2121
terminated by "implicit stop" (no terminating `<`) consumes blank lines, so
2222
`block` has no way to end.
2323
- `line_li` ("listitem")
24-
- lines starting with `-`/`` (_not_ `+`/`*`) are listitems.
25-
- consumes lines until blank line, codeblock, or next listitem.
26-
- nesting is ignored: indented listitems are parsed as siblings.
24+
- Lines starting with `-`/``/`[0-9].` (_not_ `+`/`*`) are listitems.
25+
- Use the `prefix` node to detect if the listitem is ordered (numbered) or
26+
unodered.
27+
- Consumes lines until blank line, codeblock, or next listitem.
28+
- Nesting is ignored: indented listitems are parsed as siblings. Consumers can
29+
check leading whitespace to decide nesting.
2730
- `codeblock`:
28-
- contained by `line` or `line_li`, because ">" can start a codeblock at the
31+
- Contained by `line` or `line_li`, because ">" can start a codeblock at the
2932
end of any line.
30-
- contains `line` nodes without `word` nodes: it's just the full raw text
33+
- Contains `line` nodes without `word` nodes: it's just the full raw text
3134
line including whitespace. This is somewhat dictated by its "preformatted"
3235
nature; parsing the contents would require loading a "child" language
3336
(injection). See [#2](https://github.com/neovim/tree-sitter-vimdoc/issues/2).
34-
- the terminating `<` (and any following whitespace) is discarded (anonymous).
37+
- The terminating `<` (and any following whitespace) is discarded (anonymous).
3538
- `url` intentionally does not capture `.,)` at the end of the URL. See also [Known issues](#known-issues).
3639
- `h1` = "Heading 1": `======` followed by text and optional `*tags*`.
3740
- `h2` = "Heading 2": `------` followed by text and optional `*tags*`.
@@ -43,6 +46,12 @@ Known issues
4346

4447
- Input must end with newline/EOL (`\n`). Grammar does not support files without EOL.
4548
- Input must end with a blank line. Though this doesn't seem to matter in practice.
49+
- Any line starting with `1.` (or other number) is treated as a listitem, even
50+
if the first line of its `block` is not a listitem. Example:
51+
```
52+
Foo was 0, not
53+
1. Uh oh.
54+
```
4655
- Spec requires that `codeblock` delimiter ">" must be preceded by a space
4756
(" >"), not a tab. But currently the grammar doesn't enforce this. Example:
4857
`:help lcs-tab`.

grammar.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
// @ts-check
1414

1515
const _uppercase_word = /[A-Z0-9.()][-A-Z0-9.()_]+/;
16-
const _li_token = /[-][ ]+/;
16+
// Listitem (incl. numbered items).
17+
const _li_token = /([-]|([0-9]{1,3}\.))[ ]+/;
1718

1819
module.exports = grammar({
1920
name: 'vimdoc',
@@ -49,9 +50,10 @@ module.exports = grammar({
4950
alias($.word_noli, $.word),
5051
$._atom_common,
5152
),
53+
// Word NOT matching (numbered) listitem.
5254
word_noli: ($) => choice(
53-
// Lines contained by line_li must not start with a listitem symbol.
54-
token(prec(-1, /[^-\n\t ][^(\[\n\t ]*/)),
55+
// Lines contained by line_li must not start with (numbered) listitem symbol.
56+
token(prec(-1, /(([^-\n\t ])|([^0-9\n\t ][^.\n\t ]))[^.(\[\n\t ]*/)),
5557
token(prec(-1, /[-][^\n\t ]+/)),
5658
$._word_common,
5759
),
@@ -164,7 +166,7 @@ module.exports = grammar({
164166
// Listitem: consumes prefixed line and all adjacent non-prefixed lines.
165167
line_li: ($) => prec.right(1, seq(
166168
optional(token.immediate('<')), // Treat codeblock-terminating "<" as whitespace.
167-
_li_token,
169+
alias(_li_token, $.prefix),
168170
choice(
169171
alias(seq(repeat1($._atom), /\n/), $.line),
170172
seq(alias(repeat1($._atom), $.line), $.codeblock),

src/grammar.json

Lines changed: 8 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/node-types.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)